@@ -106,6 +106,44 @@ resource_getrusage(PyObject *self, PyObject *args)
106106 return result ;
107107}
108108
109+ static int
110+ py2rlimit (PyObject * curobj , PyObject * maxobj , struct rlimit * rl_out )
111+ {
112+ #if !defined(HAVE_LARGEFILE_SUPPORT )
113+ rl_out -> rlim_cur = PyLong_AsLong (curobj );
114+ if (rl_out -> rlim_cur == (rlim_t )- 1 && PyErr_Occurred ())
115+ return -1 ;
116+ rl_out -> rlim_max = PyLong_AsLong (maxobj );
117+ if (rl_out -> rlim_max == (rlim_t )- 1 && PyErr_Occurred ())
118+ return -1 ;
119+ #else
120+ /* The limits are probably bigger than a long */
121+ rl_out -> rlim_cur = PyLong_AsLongLong (curobj );
122+ if (rl_out -> rlim_cur == (rlim_t )- 1 && PyErr_Occurred ())
123+ return -1 ;
124+ rl_out -> rlim_max = PyLong_AsLongLong (maxobj );
125+ if (rl_out -> rlim_max == (rlim_t )- 1 && PyErr_Occurred ())
126+ return -1 ;
127+ #endif
128+
129+ rl_out -> rlim_cur = rl_out -> rlim_cur & RLIM_INFINITY ;
130+ rl_out -> rlim_max = rl_out -> rlim_max & RLIM_INFINITY ;
131+ return 0 ;
132+
133+ }
134+
135+ static PyObject *
136+ rlimit2py (struct rlimit rl )
137+ {
138+ #if defined(HAVE_LONG_LONG )
139+ if (sizeof (rl .rlim_cur ) > sizeof (long )) {
140+ return Py_BuildValue ("LL" ,
141+ (PY_LONG_LONG ) rl .rlim_cur ,
142+ (PY_LONG_LONG ) rl .rlim_max );
143+ }
144+ #endif
145+ return Py_BuildValue ("ll" , (long ) rl .rlim_cur , (long ) rl .rlim_max );
146+ }
109147
110148static PyObject *
111149resource_getrlimit (PyObject * self , PyObject * args )
@@ -126,15 +164,7 @@ resource_getrlimit(PyObject *self, PyObject *args)
126164 PyErr_SetFromErrno (PyExc_OSError );
127165 return NULL ;
128166 }
129-
130- #if defined(HAVE_LONG_LONG )
131- if (sizeof (rl .rlim_cur ) > sizeof (long )) {
132- return Py_BuildValue ("LL" ,
133- (PY_LONG_LONG ) rl .rlim_cur ,
134- (PY_LONG_LONG ) rl .rlim_max );
135- }
136- #endif
137- return Py_BuildValue ("ll" , (long ) rl .rlim_cur , (long ) rl .rlim_max );
167+ return rlimit2py (rl );
138168}
139169
140170static PyObject *
@@ -166,25 +196,10 @@ resource_setrlimit(PyObject *self, PyObject *args)
166196 curobj = PyTuple_GET_ITEM (limits , 0 );
167197 maxobj = PyTuple_GET_ITEM (limits , 1 );
168198
169- #if !defined(HAVE_LARGEFILE_SUPPORT )
170- rl .rlim_cur = PyLong_AsLong (curobj );
171- if (rl .rlim_cur == (rlim_t )- 1 && PyErr_Occurred ())
172- goto error ;
173- rl .rlim_max = PyLong_AsLong (maxobj );
174- if (rl .rlim_max == (rlim_t )- 1 && PyErr_Occurred ())
175- goto error ;
176- #else
177- /* The limits are probably bigger than a long */
178- rl .rlim_cur = PyLong_AsLongLong (curobj );
179- if (rl .rlim_cur == (rlim_t )- 1 && PyErr_Occurred ())
199+ if (py2rlimit (curobj , maxobj , & rl ) < 0 ) {
180200 goto error ;
181- rl .rlim_max = PyLong_AsLongLong (maxobj );
182- if (rl .rlim_max == (rlim_t )- 1 && PyErr_Occurred ())
183- goto error ;
184- #endif
201+ }
185202
186- rl .rlim_cur = rl .rlim_cur & RLIM_INFINITY ;
187- rl .rlim_max = rl .rlim_max & RLIM_INFINITY ;
188203 if (setrlimit (resource , & rl ) == -1 ) {
189204 if (errno == EINVAL )
190205 PyErr_SetString (PyExc_ValueError ,
@@ -205,6 +220,48 @@ resource_setrlimit(PyObject *self, PyObject *args)
205220 return NULL ;
206221}
207222
223+ #ifdef HAVE_PRLIMIT
224+ static PyObject *
225+ resource_prlimit (PyObject * self , PyObject * args )
226+ {
227+ struct rlimit old_limit , new_limit ;
228+ int resource , retval ;
229+ pid_t pid ;
230+ PyObject * curobj = NULL , * maxobj = NULL ;
231+
232+ if (!PyArg_ParseTuple (args , _Py_PARSE_PID "i|(OO):prlimit" ,
233+ & pid , & resource , & curobj , & maxobj ))
234+ return NULL ;
235+
236+ if (resource < 0 || resource >= RLIM_NLIMITS ) {
237+ PyErr_SetString (PyExc_ValueError ,
238+ "invalid resource specified" );
239+ return NULL ;
240+ }
241+
242+ if (curobj != NULL ) {
243+ if (py2rlimit (curobj , maxobj , & new_limit ) < 0 ) {
244+ return NULL ;
245+ }
246+ retval = prlimit (pid , resource , & new_limit , & old_limit );
247+ }
248+ else {
249+ retval = prlimit (pid , resource , NULL , & old_limit );
250+ }
251+
252+ if (retval == -1 ) {
253+ if (errno == EINVAL ) {
254+ PyErr_SetString (PyExc_ValueError ,
255+ "current limit exceeds maximum limit" );
256+ } else {
257+ PyErr_SetFromErrno (PyExc_OSError );
258+ }
259+ return NULL ;
260+ }
261+ return rlimit2py (old_limit );
262+ }
263+ #endif /* HAVE_PRLIMIT */
264+
208265static PyObject *
209266resource_getpagesize (PyObject * self , PyObject * unused )
210267{
@@ -229,6 +286,9 @@ static struct PyMethodDef
229286resource_methods [] = {
230287 {"getrusage" , resource_getrusage , METH_VARARGS },
231288 {"getrlimit" , resource_getrlimit , METH_VARARGS },
289+ #ifdef HAVE_PRLIMIT
290+ {"prlimit" , resource_prlimit , METH_VARARGS },
291+ #endif
232292 {"setrlimit" , resource_setrlimit , METH_VARARGS },
233293 {"getpagesize" , resource_getpagesize , METH_NOARGS },
234294 {NULL , NULL } /* sentinel */
0 commit comments