Skip to content

Remove fcntl_fcntl_impl keeping fcntl_ioctl_impl #95443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Modules/clinic/fcntlmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 38 additions & 45 deletions Modules/fcntlmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
int ret;
char *str;
Py_ssize_t len;
char buf[1024];
//char buf[1024];
int async_err = 0;

if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
Expand All @@ -65,21 +65,37 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
int parse_result;

if (PyArg_Parse(arg, "s#", &str, &len)) {
if ((size_t)len > sizeof buf) {
/*if ((size_t)len > sizeof buf) {
PyErr_SetString(PyExc_ValueError,
"fcntl string arg too long");
return NULL;
}*/
char* buf = malloc((size_t)len);
PyObject* buf_ret;
if(buf == NULL) {
PyErr_NoMemory();
return NULL;
}
/*PyObject *o = PyBytes_FromStringAndSize(NULL, len);
if (o == NULL) {
return NULL;
}
char *buf = PyBytes_AS_STRING(o);*/

memcpy(buf, str, len);
do {
Py_BEGIN_ALLOW_THREADS
ret = fcntl(fd, code, buf);
Py_END_ALLOW_THREADS
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
if (ret < 0) {
free(buf);
return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
}
return PyBytes_FromStringAndSize(buf, len);
//return PyBytes_FromStringAndSize(buf, len);
buf_ret = PyBytes_FromStringAndSize(buf, len);
free(buf);
return(buf_ret);
}

PyErr_Clear();
Expand Down Expand Up @@ -135,8 +151,7 @@ the behavior is as if a string had been passed.
If the argument is an immutable buffer (most likely a string) then a copy
of the buffer is passed to the operating system and the return value is a
string of the same length containing whatever the operating system put in
the buffer. The length of the arg buffer in this case is not allowed to
exceed 1024 bytes.
the buffer.

If the arg given is an integer or if none is specified, the result value is
an integer corresponding to the return value of the ioctl call in the C
Expand All @@ -146,9 +161,8 @@ code.
static PyObject *
fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
PyObject *ob_arg, int mutate_arg)
/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/
/*[clinic end generated code: output=7f7f5840c65991be input=6b70e7e5a8df40fa]*/
{
#define IOCTL_BUFSZ 1024
/* We use the unsigned non-checked 'I' format for the 'code' parameter
because the system expects it to be a 32bit bit field value
regardless of it being passed as an int or unsigned long on
Expand All @@ -164,7 +178,6 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
Py_buffer pstr;
char *str;
Py_ssize_t len;
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */

if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
ob_arg ? ob_arg : Py_None) < 0) {
Expand All @@ -173,42 +186,22 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,

if (ob_arg != NULL) {
if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
char *arg;
str = pstr.buf;
len = pstr.len;

if (mutate_arg) {
if (len <= IOCTL_BUFSZ) {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
else {
arg = str;
}
}
else {
if (len > IOCTL_BUFSZ) {
PyBuffer_Release(&pstr);
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
else {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
}
if (buf == arg) {
Py_BEGIN_ALLOW_THREADS /* think array.resize() */
ret = ioctl(fd, code, arg);
Py_END_ALLOW_THREADS
}
else {
ret = ioctl(fd, code, arg);
PyObject *o = PyBytes_FromStringAndSize(NULL, len);
if (o == NULL) {
return NULL;
}
if (mutate_arg && (len <= IOCTL_BUFSZ)) {
char *buf = PyBytes_AS_STRING(o);

memcpy(buf, str, len);

Py_BEGIN_ALLOW_THREADS /* think array.resize() */
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS

if (mutate_arg) {
memcpy(str, buf, len);
}
PyBuffer_Release(&pstr); /* No further access to str below this point */
Expand All @@ -228,14 +221,14 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
str = pstr.buf;
len = pstr.len;
if (len > IOCTL_BUFSZ) {
PyBuffer_Release(&pstr);
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");

PyObject *o = PyBytes_FromStringAndSize(NULL, len);
if (o == NULL) {
return NULL;
}
char *buf = PyBytes_AS_STRING(o);

memcpy(buf, str, len);
buf[len] = '\0';
Py_BEGIN_ALLOW_THREADS
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS
Expand Down