Skip to content

Commit 3bc8cee

Browse files
committed
Fix: remove limitation of 1024 max path size for fcntl
1 parent 2fbee85 commit 3bc8cee

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove max path size limit of 1024 for :func:`fcntl.fcntl` function. Patch by Grégory Starck.

Modules/clinic/fcntlmodule.c.h

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/fcntlmodule.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,19 @@ as constants in the fcntl module, using the same names as used in
4040
the relevant C header files. The argument arg is optional, and
4141
defaults to 0; it may be an int or a string. If arg is given as a string,
4242
the return value of fcntl is a string of that length, containing the
43-
resulting value put in the arg buffer by the operating system. The length
44-
of the arg string is not allowed to exceed 1024 bytes. If the arg given
43+
resulting value put in the arg buffer by the operating system. If the arg given
4544
is an integer or if none is specified, the result value is an integer
4645
corresponding to the return value of the fcntl call in the C code.
4746
[clinic start generated code]*/
4847

4948
static PyObject *
5049
fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
51-
/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/
50+
/*[clinic end generated code: output=888fc93b51c295bd input=eed7ab9999c13350]*/
5251
{
5352
unsigned int int_arg = 0;
5453
int ret;
5554
char *str;
5655
Py_ssize_t len;
57-
char buf[1024];
5856
int async_err = 0;
5957

6058
if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
@@ -65,21 +63,23 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
6563
int parse_result;
6664

6765
if (PyArg_Parse(arg, "s#", &str, &len)) {
68-
if ((size_t)len > sizeof buf) {
69-
PyErr_SetString(PyExc_ValueError,
70-
"fcntl string arg too long");
66+
PyObject* buf_ret = PyBytes_FromStringAndSize(NULL, len);
67+
if (buf_ret == NULL) {
68+
PyErr_NoMemory();
7169
return NULL;
7270
}
71+
char *buf = PyBytes_AS_STRING(buf_ret);
7372
memcpy(buf, str, len);
7473
do {
7574
Py_BEGIN_ALLOW_THREADS
7675
ret = fcntl(fd, code, buf);
7776
Py_END_ALLOW_THREADS
7877
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7978
if (ret < 0) {
79+
Py_DECREF(buf_ret);
8080
return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
8181
}
82-
return PyBytes_FromStringAndSize(buf, len);
82+
return buf_ret;
8383
}
8484

8585
PyErr_Clear();

0 commit comments

Comments
 (0)