]> granicus.if.org Git - python/commitdiff
Issue #23098: 64-bit dev_t is now supported in the os module.
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 18 Jan 2015 09:17:39 +0000 (11:17 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 18 Jan 2015 09:17:39 +0000 (11:17 +0200)
1  2 
Misc/NEWS
Modules/posixmodule.c

diff --cc Misc/NEWS
index 4fe3ff3af4851281ab38d2db26b1eb64adc077ff,c866803c598b6a624322164999250184df21f9ae..1c1bbb05396d3bfa962fae0280268d18ae383847
+++ b/Misc/NEWS
@@@ -203,13 -44,8 +203,15 @@@ Core and Builtin
  Library
  -------
  
+ - Issue #23098: 64-bit dev_t is now supported in the os module.
 +- Issue #21817: When an exception is raised in a task submitted to a
 +  ProcessPoolExecutor, the remote traceback is now displayed in the
 +  parent process.  Patch by Claudiu Popa.
 +
 +- Issue #15955: Add an option to limit output size when decompressing LZMA
 +  data.  Patch by Nikolaus Rath and Martin Panter.
 +
  - Issue #23250: In the http.cookies module, capitalize "HttpOnly" and "Secure"
    as they are written in the standard.
  
index d8e244133184b7dd5675d19cbfe18cc234af026b,03798ca2e5900b924cfd2924d9092903ea3ca659..542e600e7f8b32c38ee286d0157205dcc6a467da
@@@ -2568,78 -2426,15 +2588,87 @@@ class path_t_converter(CConverter)
  
  class dir_fd_converter(CConverter):
      type = 'int'
 -    converter = 'OS_STAT_DIR_FD_CONVERTER'
  
 -    def converter_init(self):
 +    def converter_init(self, requires=None):
          if self.default in (unspecified, None):
              self.c_default = 'DEFAULT_DIR_FD'
 +        if isinstance(requires, str):
 +            self.converter = requires.upper() + '_DIR_FD_CONVERTER'
 +        else:
 +            self.converter = 'dir_fd_converter'
 +
 +class fildes_converter(CConverter):
 +    type = 'int'
 +    converter = 'fildes_converter'
 +
 +class uid_t_converter(CConverter):
 +    type = "uid_t"
 +    converter = '_Py_Uid_Converter'
 +
 +class gid_t_converter(CConverter):
 +    type = "gid_t"
 +    converter = '_Py_Gid_Converter'
 +
++class dev_t_converter(CConverter):
++    type = 'dev_t'
++    converter = '_Py_Dev_Converter'
++
++class dev_t_return_converter(unsigned_long_return_converter):
++    type = 'dev_t'
++    conversion_fn = '_PyLong_FromDev'
++    unsigned_cast = '(dev_t)'
++
 +class FSConverter_converter(CConverter):
 +    type = 'PyObject *'
 +    converter = 'PyUnicode_FSConverter'
 +    def converter_init(self):
 +        if self.default is not unspecified:
 +            fail("FSConverter_converter does not support default values")
 +        self.c_default = 'NULL'
 +
 +    def cleanup(self):
 +        return "Py_XDECREF(" + self.name + ");\n"
 +
 +class pid_t_converter(CConverter):
 +    type = 'pid_t'
 +    format_unit = '" _Py_PARSE_PID "'
 +
 +class idtype_t_converter(int_converter):
 +    type = 'idtype_t'
  
 +class id_t_converter(CConverter):
 +    type = 'id_t'
 +    format_unit = '" _Py_PARSE_PID "'
 +
 +class Py_intptr_t_converter(CConverter):
 +    type = 'Py_intptr_t'
 +    format_unit = '" _Py_PARSE_INTPTR "'
 +
 +class Py_off_t_converter(CConverter):
 +    type = 'Py_off_t'
 +    converter = 'Py_off_t_converter'
 +
 +class Py_off_t_return_converter(long_return_converter):
 +    type = 'Py_off_t'
 +    conversion_fn = 'PyLong_FromPy_off_t'
 +
 +class path_confname_converter(CConverter):
 +    type="int"
 +    converter="conv_path_confname"
 +
 +class confstr_confname_converter(path_confname_converter):
 +    converter='conv_confstr_confname'
 +
 +class sysconf_confname_converter(path_confname_converter):
 +    converter="conv_sysconf_confname"
 +
 +class sched_param_converter(CConverter):
 +    type = 'struct sched_param'
 +    converter = 'convert_sched_param'
 +    impl_by_reference = True;
  
  [python start generated code]*/
- /*[python end generated code: output=da39a3ee5e6b4b0d input=147ba8f52a05aca4]*/
 -/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
++/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
  
  /*[clinic input]
  
@@@ -12328,375 -8612,180 +12357,375 @@@ os_mkfifo_impl(PyModuleDef *module, pat
      Py_BEGIN_ALLOW_THREADS
  #ifdef HAVE_MKFIFOAT
      if (dir_fd != DEFAULT_DIR_FD)
 -        result = mkfifoat(dir_fd, path.narrow, mode);
 +        result = mkfifoat(dir_fd, path->narrow, mode);
      else
  #endif
 -        result = mkfifo(path.narrow, mode);
 +        result = mkfifo(path->narrow, mode);
      Py_END_ALLOW_THREADS
  
 -    if (result < 0) {
 -        return_value = posix_error();
 -        goto exit;
 -    }
 -
 -    return_value = Py_None;
 -    Py_INCREF(Py_None);
 +    if (result < 0)
 +        return posix_error();
  
 -exit:
 -    path_cleanup(&path);
 -    return return_value;
 +    Py_RETURN_NONE;
  }
 -#endif
 +#endif /* HAVE_MKFIFO */
 +
  
  #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
 -PyDoc_STRVAR(posix_mknod__doc__,
 -"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
 -Create a filesystem node (file, device special file or named pipe)\n\
 -named filename. mode specifies both the permissions to use and the\n\
 -type of node to be created, being combined (bitwise OR) with one of\n\
 -S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
 -device defines the newly created device special file (probably using\n\
 -os.makedev()), otherwise it is ignored.\n\
 -\n\
 -If dir_fd is not None, it should be a file descriptor open to a directory,\n\
 -  and path should be relative; path will then be relative to that directory.\n\
 -dir_fd may not be implemented on your platform.\n\
 -  If it is unavailable, using it will raise a NotImplementedError.");
 +/*[clinic input]
 +os.mknod
 +
 +    path: path_t
 +    mode: int=0o600
-     device: int=0
++    device: dev_t=0
 +    *
 +    dir_fd: dir_fd(requires='mknodat')=None
 +
 +Create a node in the file system.
 +
 +Create a node in the file system (file, device special file or named pipe)
 +at path.  mode specifies both the permissions to use and the
 +type of node to be created, being combined (bitwise OR) with one of
 +S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO.  If S_IFCHR or S_IFBLK is set on mode,
 +device defines the newly created device special file (probably using
 +os.makedev()).  Otherwise device is ignored.
 +
 +If dir_fd is not None, it should be a file descriptor open to a directory,
 +  and path should be relative; path will then be relative to that directory.
 +dir_fd may not be implemented on your platform.
 +  If it is unavailable, using it will raise a NotImplementedError.
 +[clinic start generated code]*/
  
- os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd);
 +PyDoc_STRVAR(os_mknod__doc__,
 +"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n"
 +"--\n"
 +"\n"
 +"Create a node in the file system.\n"
 +"\n"
 +"Create a node in the file system (file, device special file or named pipe)\n"
 +"at path.  mode specifies both the permissions to use and the\n"
 +"type of node to be created, being combined (bitwise OR) with one of\n"
 +"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO.  If S_IFCHR or S_IFBLK is set on mode,\n"
 +"device defines the newly created device special file (probably using\n"
 +"os.makedev()).  Otherwise device is ignored.\n"
 +"\n"
 +"If dir_fd is not None, it should be a file descriptor open to a directory,\n"
 +"  and path should be relative; path will then be relative to that directory.\n"
 +"dir_fd may not be implemented on your platform.\n"
 +"  If it is unavailable, using it will raise a NotImplementedError.");
 +
 +#define OS_MKNOD_METHODDEF    \
 +    {"mknod", (PyCFunction)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__},
 +
 +static PyObject *
++os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd);
  
  static PyObject *
 -posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
 +os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs)
  {
 -    path_t path;
 -    int mode = 0666;
 +    PyObject *return_value = NULL;
 +    static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL};
 +    path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0);
 +    int mode = 384;
-     int device = 0;
+     dev_t device = 0;
      int dir_fd = DEFAULT_DIR_FD;
 -    int result;
 -    PyObject *return_value = NULL;
 -    static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
  
 -    memset(&path, 0, sizeof(path));
 -    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
 -        path_converter, &path,
 -        &mode, _Py_Dev_Converter, &device,
 -#ifdef HAVE_MKNODAT
 -        dir_fd_converter, &dir_fd
 -#else
 -        dir_fd_unavailable, &dir_fd
 -#endif
 -        ))
 -        return NULL;
 +    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-         "O&|ii$O&:mknod", _keywords,
-         path_converter, &path, &mode, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd))
++        "O&|iO&$O&:mknod", _keywords,
++        path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd))
 +        goto exit;
 +    return_value = os_mknod_impl(module, &path, mode, device, dir_fd);
 +
 +exit:
 +    /* Cleanup for path */
 +    path_cleanup(&path);
 +
 +    return return_value;
 +}
 +
 +static PyObject *
- os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd)
- /*[clinic end generated code: output=c688739c15ca7bbb input=30e02126aba9732e]*/
++os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd)
++/*[clinic end generated code: output=f71d54eaf9bb6f1a input=ee44531551a4d83b]*/
 +{
 +    int result;
  
      Py_BEGIN_ALLOW_THREADS
  #ifdef HAVE_MKNODAT
      if (dir_fd != DEFAULT_DIR_FD)
 -        result = mknodat(dir_fd, path.narrow, mode, device);
 +        result = mknodat(dir_fd, path->narrow, mode, device);
      else
  #endif
 -        result = mknod(path.narrow, mode, device);
 +        result = mknod(path->narrow, mode, device);
      Py_END_ALLOW_THREADS
  
 -    if (result < 0) {
 -        return_value = posix_error();
 -        goto exit;
 -    }
 -
 -    return_value = Py_None;
 -    Py_INCREF(Py_None);
 +    if (result < 0)
 +        return posix_error();
  
 -exit:
 -    path_cleanup(&path);
 -    return return_value;
 +    Py_RETURN_NONE;
  }
 -#endif
 +#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
 +
  
  #ifdef HAVE_DEVICE_MACROS
 -PyDoc_STRVAR(posix_major__doc__,
 -"major(device) -> major number\n\
 -Extracts a device major number from a raw device number.");
 +/*[clinic input]
 +os.major -> unsigned_int
 +
-     device: int
++    device: dev_t
 +    /
 +
 +Extracts a device major number from a raw device number.
 +[clinic start generated code]*/
 +
 +PyDoc_STRVAR(os_major__doc__,
 +"major($module, device, /)\n"
 +"--\n"
 +"\n"
 +"Extracts a device major number from a raw device number.");
 +
 +#define OS_MAJOR_METHODDEF    \
 +    {"major", (PyCFunction)os_major, METH_VARARGS, os_major__doc__},
 +
 +static unsigned int
- os_major_impl(PyModuleDef *module, int device);
++os_major_impl(PyModuleDef *module, dev_t device);
  
  static PyObject *
 -posix_major(PyObject *self, PyObject *args)
 +os_major(PyModuleDef *module, PyObject *args)
  {
-     int device;
 +    PyObject *return_value = NULL;
 -    if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
 -        return NULL;
 -    return PyLong_FromLong((long)major(device));
+     dev_t device;
-         "i:major",
-         &device))
 +    unsigned int _return_value;
 +
 +    if (!PyArg_ParseTuple(args,
- os_major_impl(PyModuleDef *module, int device)
- /*[clinic end generated code: output=52e6743300dcf4ad input=ea48820b7e10d310]*/
++        "O&:major",
++        _Py_Dev_Converter, &device))
 +        goto exit;
 +    _return_value = os_major_impl(module, device);
 +    if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
 +        goto exit;
 +    return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
 +
 +exit:
 +    return return_value;
 +}
 +
 +static unsigned int
++os_major_impl(PyModuleDef *module, dev_t device)
++/*[clinic end generated code: output=a2d06e908ebf95b5 input=1e16a4d30c4d4462]*/
 +{
 +    return major(device);
  }
  
 -PyDoc_STRVAR(posix_minor__doc__,
 -"minor(device) -> minor number\n\
 -Extracts a device minor number from a raw device number.");
 +
 +/*[clinic input]
 +os.minor -> unsigned_int
 +
-     device: int
++    device: dev_t
 +    /
 +
 +Extracts a device minor number from a raw device number.
 +[clinic start generated code]*/
 +
 +PyDoc_STRVAR(os_minor__doc__,
 +"minor($module, device, /)\n"
 +"--\n"
 +"\n"
 +"Extracts a device minor number from a raw device number.");
 +
 +#define OS_MINOR_METHODDEF    \
 +    {"minor", (PyCFunction)os_minor, METH_VARARGS, os_minor__doc__},
 +
 +static unsigned int
- os_minor_impl(PyModuleDef *module, int device);
++os_minor_impl(PyModuleDef *module, dev_t device);
  
  static PyObject *
 -posix_minor(PyObject *self, PyObject *args)
 +os_minor(PyModuleDef *module, PyObject *args)
  {
-     int device;
 +    PyObject *return_value = NULL;
 -    if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
 -        return NULL;
 -    return PyLong_FromLong((long)minor(device));
 -}
+     dev_t device;
-         "i:minor",
-         &device))
 +    unsigned int _return_value;
 +
 +    if (!PyArg_ParseTuple(args,
++        "O&:minor",
++        _Py_Dev_Converter, &device))
 +        goto exit;
 +    _return_value = os_minor_impl(module, device);
 +    if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
 +        goto exit;
 +    return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
  
 -PyDoc_STRVAR(posix_makedev__doc__,
 -"makedev(major, minor) -> device number\n\
 -Composes a raw device number from the major and minor device numbers.");
 +exit:
 +    return return_value;
 +}
  
 -static PyObject *
 -posix_makedev(PyObject *self, PyObject *args)
 +static unsigned int
- os_minor_impl(PyModuleDef *module, int device)
- /*[clinic end generated code: output=aebe4bd7f455b755 input=089733ebbf9754e8]*/
++os_minor_impl(PyModuleDef *module, dev_t device)
++/*[clinic end generated code: output=6332287ee3f006e2 input=0842c6d23f24c65e]*/
  {
 -    int major, minor;
 -    if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
 -        return NULL;
 -    return _PyLong_FromDev(makedev(major, minor));
 +    return minor(device);
  }
 -#endif /* device macros */
  
  
 -#ifdef HAVE_FTRUNCATE
 -PyDoc_STRVAR(posix_ftruncate__doc__,
 -"ftruncate(fd, length)\n\n\
 -Truncate a file to a specified length.");
 +/*[clinic input]
- os.makedev -> unsigned_int
++os.makedev -> dev_t
  
 -static PyObject *
 -posix_ftruncate(PyObject *self, PyObject *args)
 -{
 -    int fd;
 -    off_t length;
 -    int res;
 +    major: int
 +    minor: int
 +    /
  
 -    if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
 -        return NULL;
 +Composes a raw device number from the major and minor device numbers.
 +[clinic start generated code]*/
  
 -    Py_BEGIN_ALLOW_THREADS
 -    res = ftruncate(fd, length);
 -    Py_END_ALLOW_THREADS
 -    if (res < 0)
 -        return posix_error();
 -    Py_INCREF(Py_None);
 -    return Py_None;
 -}
 -#endif
 +PyDoc_STRVAR(os_makedev__doc__,
 +"makedev($module, major, minor, /)\n"
 +"--\n"
 +"\n"
 +"Composes a raw device number from the major and minor device numbers.");
  
 -#ifdef HAVE_TRUNCATE
 -PyDoc_STRVAR(posix_truncate__doc__,
 -"truncate(path, length)\n\n\
 -Truncate the file given by path to length bytes.\n\
 -On some platforms, path may also be specified as an open file descriptor.\n\
 -  If this functionality is unavailable, using it raises an exception.");
 +#define OS_MAKEDEV_METHODDEF    \
 +    {"makedev", (PyCFunction)os_makedev, METH_VARARGS, os_makedev__doc__},
 +
- static unsigned int
++static dev_t
 +os_makedev_impl(PyModuleDef *module, int major, int minor);
  
  static PyObject *
 -posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
 +os_makedev(PyModuleDef *module, PyObject *args)
  {
 -    path_t path;
 -    off_t length;
 -    int res;
 -    PyObject *result = NULL;
 -    static char *keywords[] = {"path", "length", NULL};
 +    PyObject *return_value = NULL;
 +    int major;
 +    int minor;
-     unsigned int _return_value;
++    dev_t _return_value;
 +
 +    if (!PyArg_ParseTuple(args,
 +        "ii:makedev",
 +        &major, &minor))
 +        goto exit;
 +    _return_value = os_makedev_impl(module, major, minor);
-     if ((_return_value == (unsigned int)-1) && PyErr_Occurred())
++    if ((_return_value == (dev_t)-1) && PyErr_Occurred())
 +        goto exit;
-     return_value = PyLong_FromUnsignedLong((unsigned long)_return_value);
++    return_value = _PyLong_FromDev(_return_value);
 +
 +exit:
 +    return return_value;
 +}
 +
- static unsigned int
++static dev_t
 +os_makedev_impl(PyModuleDef *module, int major, int minor)
- /*[clinic end generated code: output=5cb79d9c9eac58b0 input=f55bf7cffb028a08]*/
++/*[clinic end generated code: output=38e9a9774c96511a input=4b9fd8fc73cbe48f]*/
 +{
 +    return makedev(major, minor);
 +}
 +#endif /* HAVE_DEVICE_MACROS */
 +
  
 -    memset(&path, 0, sizeof(path));
 -    path.function_name = "truncate";
  #ifdef HAVE_FTRUNCATE
 -    path.allow_fd = 1;
 -#endif
 -    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
 -                                     path_converter, &path,
 -                                     _parse_off_t, &length))
 -        return NULL;
 +/*[clinic input]
 +os.ftruncate
 +
 +    fd: int
 +    length: Py_off_t
 +    /
 +
 +Truncate a file, specified by file descriptor, to a specific length.
 +[clinic start generated code]*/
 +
 +PyDoc_STRVAR(os_ftruncate__doc__,
 +"ftruncate($module, fd, length, /)\n"
 +"--\n"
 +"\n"
 +"Truncate a file, specified by file descriptor, to a specific length.");
 +
 +#define OS_FTRUNCATE_METHODDEF    \
 +    {"ftruncate", (PyCFunction)os_ftruncate, METH_VARARGS, os_ftruncate__doc__},
 +
 +static PyObject *
 +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length);
 +
 +static PyObject *
 +os_ftruncate(PyModuleDef *module, PyObject *args)
 +{
 +    PyObject *return_value = NULL;
 +    int fd;
 +    Py_off_t length;
 +
 +    if (!PyArg_ParseTuple(args,
 +        "iO&:ftruncate",
 +        &fd, Py_off_t_converter, &length))
 +        goto exit;
 +    return_value = os_ftruncate_impl(module, fd, length);
 +
 +exit:
 +    return return_value;
 +}
 +
 +static PyObject *
 +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
 +/*[clinic end generated code: output=62326766cb9b76bf input=63b43641e52818f2]*/
 +{
 +    int result;
 +
 +    Py_BEGIN_ALLOW_THREADS
 +    result = ftruncate(fd, length);
 +    Py_END_ALLOW_THREADS
 +    if (result < 0)
 +        return posix_error();
 +    Py_RETURN_NONE;
 +}
 +#endif /* HAVE_FTRUNCATE */
 +
 +
 +#ifdef HAVE_TRUNCATE
 +/*[clinic input]
 +os.truncate
 +    path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
 +    length: Py_off_t
 +
 +Truncate a file, specified by path, to a specific length.
 +
 +On some platforms, path may also be specified as an open file descriptor.
 +  If this functionality is unavailable, using it raises an exception.
 +[clinic start generated code]*/
 +
 +PyDoc_STRVAR(os_truncate__doc__,
 +"truncate($module, /, path, length)\n"
 +"--\n"
 +"\n"
 +"Truncate a file, specified by path, to a specific length.\n"
 +"\n"
 +"On some platforms, path may also be specified as an open file descriptor.\n"
 +"  If this functionality is unavailable, using it raises an exception.");
 +
 +#define OS_TRUNCATE_METHODDEF    \
 +    {"truncate", (PyCFunction)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__},
 +
 +static PyObject *
 +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length);
 +
 +static PyObject *
 +os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs)
 +{
 +    PyObject *return_value = NULL;
 +    static char *_keywords[] = {"path", "length", NULL};
 +    path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE);
 +    Py_off_t length;
 +
 +    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
 +        "O&O&:truncate", _keywords,
 +        path_converter, &path, Py_off_t_converter, &length))
 +        goto exit;
 +    return_value = os_truncate_impl(module, &path, length);
 +
 +exit:
 +    /* Cleanup for path */
 +    path_cleanup(&path);
 +
 +    return return_value;
 +}
 +
 +static PyObject *
 +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
 +/*[clinic end generated code: output=6bd76262d2e027c6 input=77229cf0b50a9b77]*/
 +{
 +    int result;
  
      Py_BEGIN_ALLOW_THREADS
  #ifdef HAVE_FTRUNCATE