From: Serhiy Storchaka Date: Mon, 10 Nov 2014 09:25:50 +0000 (+0200) Subject: Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian X-Git-Tag: v3.5.0a1~499 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a8dacf9c682734dd96ab25731faf5610179fa57;p=python Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian platforms. --- 5a8dacf9c682734dd96ab25731faf5610179fa57 diff --cc Misc/NEWS index 53040b2649,1a4ad56268..4b495d72c5 --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -183,8 -36,9 +183,11 @@@ Core and Builtin Library ------- + - Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian + platforms. + +- Issue #21650: Add an `--sort-keys` option to json.tool CLI. + - Issues #814253, #9179: Group references and conditional group references now work in lookbehind assertions in regular expressions. diff --cc Modules/fcntlmodule.c index 87662dd66e,9325940965..1f1cef90eb --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@@ -32,72 -26,48 +32,72 @@@ conv_descriptor(PyObject *object, int * return 1; } +/* Must come after conv_descriptor definition. */ +#include "clinic/fcntlmodule.c.h" + +/*[clinic input] +fcntl.fcntl + + fd: object(type='int', converter='conv_descriptor') + code: int + arg: object = NULL + / -/* fcntl(fd, op, [arg]) */ +Perform the operation `code` on file descriptor fd. + +The values used for `code` are operating system dependent, and are available +as constants in the fcntl module, using the same names as used in +the relevant C header files. The argument arg is optional, and +defaults to 0; it may be an int or a string. If arg is given as a string, +the return value of fcntl is a string of that length, containing the +resulting value put in the arg buffer by the operating system. The length +of the arg string is not allowed to exceed 1024 bytes. 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 fcntl call in the C code. +[clinic start generated code]*/ static PyObject * -fcntl_fcntl(PyObject *self, PyObject *args) +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg) +/*[clinic end generated code: output=afc5bfa74a03ef0d input=4850c13a41e86930]*/ { - int int_arg = 0; - int fd; - int code; - int arg; ++ unsigned int int_arg = 0; int ret; char *str; Py_ssize_t len; char buf[1024]; - if (PyArg_ParseTuple(args, "O&is#:fcntl", - conv_descriptor, &fd, &code, &str, &len)) { - if (len > sizeof buf) { - PyErr_SetString(PyExc_ValueError, - "fcntl string arg too long"); - return NULL; + if (arg != NULL) { + int parse_result; + + if (PyArg_Parse(arg, "s#", &str, &len)) { + if ((size_t)len > sizeof buf) { + PyErr_SetString(PyExc_ValueError, + "fcntl string arg too long"); + return NULL; + } + memcpy(buf, str, len); + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, buf); + Py_END_ALLOW_THREADS + if (ret < 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + return PyBytes_FromStringAndSize(buf, len); } - memcpy(buf, str, len); - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, buf); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; + + PyErr_Clear(); + parse_result = PyArg_Parse(arg, - "l;fcntl requires a file or file descriptor," ++ "I;fcntl requires a file or file descriptor," + " an integer and optionally a third integer or a string", + &int_arg); + if (!parse_result) { + return NULL; } - return PyBytes_FromStringAndSize(buf, len); } - PyErr_Clear(); - arg = 0; - if (!PyArg_ParseTuple(args, - "O&i|I;fcntl requires a file or file descriptor," - " an integer and optionally a third integer or a string", - conv_descriptor, &fd, &code, &arg)) { - return NULL; - } Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, int_arg); - ret = fcntl(fd, code, arg); ++ ret = fcntl(fd, code, (int)int_arg); Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError);