]> granicus.if.org Git - python/commitdiff
Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 10 Nov 2014 09:25:50 +0000 (11:25 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 10 Nov 2014 09:25:50 +0000 (11:25 +0200)
platforms.

1  2 
Misc/NEWS
Modules/fcntlmodule.c

diff --cc Misc/NEWS
index 53040b264992289622205a3664d1d7a0dd389192,1a4ad5626826c710858da604f19edeee142d7184..4b495d72c50b68798a7be273460848737965977a
+++ 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.
  
index 87662dd66ed74b281da2f5ad8e5144bf72f1901f,93259409652c931741c96ab5c544b57a9098c256..1f1cef90eb22ce5add7248e54869df1503b6b687
@@@ -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);