@@ -93,29 +93,53 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
93
93
return NULL ;
94
94
}
95
95
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 );
99
99
PyBuffer_Release (& view );
100
- return NULL ;
101
- }
102
- memcpy (buf , view .buf , len );
103
- memcpy (buf + len , guard , GUARDSZ );
104
- PyBuffer_Release (& view );
105
100
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 );
113
114
}
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 ;
117
142
}
118
- return PyBytes_FromStringAndSize (buf , len );
119
143
#undef FCNTL_BUFSZ
120
144
}
121
145
PyErr_Format (PyExc_TypeError ,
@@ -251,29 +275,53 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
251
275
return NULL ;
252
276
}
253
277
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 );
257
281
PyBuffer_Release (& view );
258
- return NULL ;
259
- }
260
- memcpy (buf , view .buf , len );
261
- memcpy (buf + len , guard , GUARDSZ );
262
- PyBuffer_Release (& view );
263
282
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 );
271
296
}
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 ;
275
324
}
276
- return PyBytes_FromStringAndSize (buf , len );
277
325
#undef IOCTL_BUFSZ
278
326
}
279
327
PyErr_Format (PyExc_TypeError ,
0 commit comments