@@ -93,29 +93,53 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
9393 return NULL ;
9494 }
9595 Py_ssize_t len = view .len ;
96- if (len > FCNTL_BUFSZ ) {
97- PyErr_SetString ( PyExc_ValueError ,
98- "fcntl argument 3 is too long" );
96+ if (len <= FCNTL_BUFSZ ) {
97+ memcpy ( buf , view . buf , len );
98+ memcpy ( buf + len , guard , GUARDSZ );
9999 PyBuffer_Release (& view );
100- return NULL ;
101- }
102- memcpy (buf , view .buf , len );
103- memcpy (buf + len , guard , GUARDSZ );
104- PyBuffer_Release (& view );
105100
106- do {
107- Py_BEGIN_ALLOW_THREADS
108- ret = fcntl (fd , code , buf );
109- Py_END_ALLOW_THREADS
110- } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
111- if (ret < 0 ) {
112- return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
101+ do {
102+ Py_BEGIN_ALLOW_THREADS
103+ ret = fcntl (fd , code , buf );
104+ Py_END_ALLOW_THREADS
105+ } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
106+ if (ret < 0 ) {
107+ return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
108+ }
109+ if (memcmp (buf + len , guard , GUARDSZ ) != 0 ) {
110+ PyErr_SetString (PyExc_SystemError , "buffer overflow" );
111+ return NULL ;
112+ }
113+ return PyBytes_FromStringAndSize (buf , len );
113114 }
114- if (memcmp (buf + len , guard , GUARDSZ ) != 0 ) {
115- PyErr_SetString (PyExc_SystemError , "buffer overflow" );
116- return NULL ;
115+ else {
116+ PyObject * result = PyBytes_FromStringAndSize (NULL , len );
117+ if (result == NULL ) {
118+ PyBuffer_Release (& view );
119+ return NULL ;
120+ }
121+ char * ptr = PyBytes_AsString (result );
122+ memcpy (ptr , view .buf , len );
123+ PyBuffer_Release (& view );
124+
125+ do {
126+ Py_BEGIN_ALLOW_THREADS
127+ ret = fcntl (fd , code , ptr );
128+ Py_END_ALLOW_THREADS
129+ } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
130+ if (ret < 0 ) {
131+ if (async_err ) {
132+ PyErr_SetFromErrno (PyExc_OSError );
133+ }
134+ Py_DECREF (result );
135+ return NULL ;
136+ }
137+ if (ptr [len ] != '\0' ) {
138+ PyErr_SetString (PyExc_SystemError , "buffer overflow" );
139+ return NULL ;
140+ }
141+ return result ;
117142 }
118- return PyBytes_FromStringAndSize (buf , len );
119143#undef FCNTL_BUFSZ
120144 }
121145 PyErr_Format (PyExc_TypeError ,
@@ -251,29 +275,53 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
251275 return NULL ;
252276 }
253277 Py_ssize_t len = view .len ;
254- if (len > IOCTL_BUFSZ ) {
255- PyErr_SetString ( PyExc_ValueError ,
256- "ioctl argument 3 is too long" );
278+ if (len <= IOCTL_BUFSZ ) {
279+ memcpy ( buf , view . buf , len );
280+ memcpy ( buf + len , guard , GUARDSZ );
257281 PyBuffer_Release (& view );
258- return NULL ;
259- }
260- memcpy (buf , view .buf , len );
261- memcpy (buf + len , guard , GUARDSZ );
262- PyBuffer_Release (& view );
263282
264- do {
265- Py_BEGIN_ALLOW_THREADS
266- ret = ioctl (fd , code , buf );
267- Py_END_ALLOW_THREADS
268- } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
269- if (ret < 0 ) {
270- return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
283+ do {
284+ Py_BEGIN_ALLOW_THREADS
285+ ret = ioctl (fd , code , buf );
286+ Py_END_ALLOW_THREADS
287+ } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
288+ if (ret < 0 ) {
289+ return !async_err ? PyErr_SetFromErrno (PyExc_OSError ) : NULL ;
290+ }
291+ if (memcmp (buf + len , guard , GUARDSZ ) != 0 ) {
292+ PyErr_SetString (PyExc_SystemError , "buffer overflow" );
293+ return NULL ;
294+ }
295+ return PyBytes_FromStringAndSize (buf , len );
271296 }
272- if (memcmp (buf + len , guard , GUARDSZ ) != 0 ) {
273- PyErr_SetString (PyExc_SystemError , "buffer overflow" );
274- return NULL ;
297+ else {
298+ PyObject * result = PyBytes_FromStringAndSize (NULL , len );
299+ if (result == NULL ) {
300+ PyBuffer_Release (& view );
301+ return NULL ;
302+ }
303+ char * ptr = PyBytes_AsString (result );
304+ memcpy (ptr , view .buf , len );
305+ PyBuffer_Release (& view );
306+
307+ do {
308+ Py_BEGIN_ALLOW_THREADS
309+ ret = ioctl (fd , code , ptr );
310+ Py_END_ALLOW_THREADS
311+ } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals ()));
312+ if (ret < 0 ) {
313+ if (async_err ) {
314+ PyErr_SetFromErrno (PyExc_OSError );
315+ }
316+ Py_DECREF (result );
317+ return NULL ;
318+ }
319+ if (ptr [len ] != '\0' ) {
320+ PyErr_SetString (PyExc_SystemError , "buffer overflow" );
321+ return NULL ;
322+ }
323+ return result ;
275324 }
276- return PyBytes_FromStringAndSize (buf , len );
277325#undef IOCTL_BUFSZ
278326 }
279327 PyErr_Format (PyExc_TypeError ,
0 commit comments