diff options
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 2900 |
1 files changed, 1538 insertions, 1362 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 767a665..7c937e0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1,15 +1,14 @@ /* POSIX module implementation */ -/* This file is also used for Windows NT/MS-Win and OS/2. In that case the - module actually calls itself 'nt' or 'os2', not 'posix', and a few +/* This file is also used for Windows NT/MS-Win. In that case the + module actually calls itself 'nt', not 'posix', and a few functions are either unimplemented or implemented differently. The source assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent of the compiler used. Different compilers define their own feature - test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler - independent macro PYOS_OS2 should be defined. On OS/2 the default - compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used - as the compiler specific macro for the EMX port of gcc to OS/2. */ + test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ + + #ifdef __APPLE__ /* @@ -30,11 +29,6 @@ #include "posixmodule.h" #endif -#if defined(__VMS) -# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" -# include <unixio.h> -#endif /* defined(__VMS) */ - #ifdef __cplusplus extern "C" { #endif @@ -46,22 +40,6 @@ disguised Unix interface). Refer to the library manual and\n\ corresponding Unix manual entries for more information on calls."); -#if defined(PYOS_OS2) -#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4" -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#define INCL_NOPMAPI -#include <os2.h> -#if defined(PYCC_GCC) -#include <ctype.h> -#include <io.h> -#include <stdio.h> -#include <process.h> -#endif -#include "osdefs.h" -#endif - #ifdef HAVE_SYS_UIO_H #include <sys/uio.h> #endif @@ -114,7 +92,7 @@ corresponding Unix manual entries for more information on calls."); #undef HAVE_SCHED_SETAFFINITY #endif -#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) +#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) #define USE_XATTRS #endif @@ -132,6 +110,18 @@ corresponding Unix manual entries for more information on calls."); #include <dlfcn.h> #endif +#ifdef __hpux +#include <sys/mpctl.h> +#endif + +#if defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) +#include <sys/sysctl.h> +#endif + #if defined(MS_WINDOWS) # define TERMSIZE_USE_CONIO #elif defined(HAVE_SYS_IOCTL_H) @@ -146,29 +136,19 @@ corresponding Unix manual entries for more information on calls."); /* Various compilers have only certain posix functions */ /* XXX Gosh I wish these were all moved into pyconfig.h */ -#if defined(PYCC_VACPP) && defined(PYOS_OS2) -#include <process.h> -#else #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ -#define HAVE_GETCWD 1 #define HAVE_OPENDIR 1 #define HAVE_SYSTEM 1 -#if defined(__OS2__) -#define HAVE_EXECV 1 -#define HAVE_WAIT 1 -#endif #include <process.h> #else #ifdef __BORLANDC__ /* Borland compiler */ #define HAVE_EXECV 1 -#define HAVE_GETCWD 1 #define HAVE_OPENDIR 1 #define HAVE_PIPE 1 #define HAVE_SYSTEM 1 #define HAVE_WAIT 1 #else #ifdef _MSC_VER /* Microsoft compiler */ -#define HAVE_GETCWD 1 #define HAVE_GETPPID 1 #define HAVE_GETLOGIN 1 #define HAVE_SPAWNV 1 @@ -179,16 +159,12 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_FSYNC 1 #define fsync _commit #else -#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS) -/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */ -#else /* all other compilers */ /* Unix functions that the configure script doesn't check for */ #define HAVE_EXECV 1 #define HAVE_FORK 1 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ #define HAVE_FORK1 1 #endif -#define HAVE_GETCWD 1 #define HAVE_GETEGID 1 #define HAVE_GETEUID 1 #define HAVE_GETGID 1 @@ -200,14 +176,15 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_SYSTEM 1 #define HAVE_WAIT 1 #define HAVE_TTYNAME 1 -#endif /* PYOS_OS2 && PYCC_GCC && __VMS */ #endif /* _MSC_VER */ #endif /* __BORLANDC__ */ #endif /* ! __WATCOMC__ || __QNX__ */ -#endif /* ! __IBMC__ */ - +/*[clinic input] +module os +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/ #ifndef _MSC_VER @@ -335,10 +312,6 @@ static int win32_can_symlink = 0; #endif #endif /* _MSC_VER */ -#if defined(PYCC_VACPP) && defined(PYOS_OS2) -#include <io.h> -#endif /* OS2 */ - #ifndef MAXPATHLEN #if defined(PATH_MAX) && PATH_MAX > 1024 #define MAXPATHLEN PATH_MAX @@ -380,7 +353,7 @@ static int win32_can_symlink = 0; #undef STAT #undef FSTAT #undef STRUCT_STAT -#if defined(MS_WIN64) || defined(MS_WINDOWS) +#ifdef MS_WINDOWS # define STAT win32_stat # define LSTAT win32_lstat # define FSTAT win32_fstat @@ -403,6 +376,8 @@ static int win32_can_symlink = 0; #endif #endif +#define DWORD_MAX 4294967295U + #ifdef MS_WINDOWS static int @@ -436,113 +411,241 @@ _PyLong_FromGid(gid_t gid) int _Py_Uid_Converter(PyObject *obj, void *p) { + uid_t uid; + PyObject *index; int overflow; long result; - if (PyFloat_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); + unsigned long uresult; + + index = PyNumber_Index(obj); + if (index == NULL) { + PyErr_Format(PyExc_TypeError, + "uid should be integer, not %.200s", + Py_TYPE(obj)->tp_name); return 0; } - result = PyLong_AsLongAndOverflow(obj, &overflow); - if (overflow < 0) - goto OverflowDown; - if (!overflow && result == -1) { - /* error or -1 */ - if (PyErr_Occurred()) - return 0; - *(uid_t *)p = (uid_t)-1; - } - else { - /* unsigned uid_t */ - unsigned long uresult; - if (overflow > 0) { - uresult = PyLong_AsUnsignedLong(obj); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - goto OverflowUp; - return 0; - } - if ((uid_t)uresult == (uid_t)-1) - goto OverflowUp; - } else { - if (result < 0) - goto OverflowDown; - uresult = result; + + /* + * Handling uid_t is complicated for two reasons: + * * Although uid_t is (always?) unsigned, it still + * accepts -1. + * * We don't know its size in advance--it may be + * bigger than an int, or it may be smaller than + * a long. + * + * So a bit of defensive programming is in order. + * Start with interpreting the value passed + * in as a signed long and see if it works. + */ + + result = PyLong_AsLongAndOverflow(index, &overflow); + + if (!overflow) { + uid = (uid_t)result; + + if (result == -1) { + if (PyErr_Occurred()) + goto fail; + /* It's a legitimate -1, we're done. */ + goto success; } + + /* Any other negative number is disallowed. */ + if (result < 0) + goto underflow; + + /* Ensure the value wasn't truncated. */ if (sizeof(uid_t) < sizeof(long) && - (unsigned long)(uid_t)uresult != uresult) - goto OverflowUp; - *(uid_t *)p = (uid_t)uresult; + (long)uid != result) + goto underflow; + goto success; + } + + if (overflow < 0) + goto underflow; + + /* + * Okay, the value overflowed a signed long. If it + * fits in an *unsigned* long, it may still be okay, + * as uid_t may be unsigned long on this platform. + */ + uresult = PyLong_AsUnsignedLong(index); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto overflow; + goto fail; } + + uid = (uid_t)uresult; + + /* + * If uid == (uid_t)-1, the user actually passed in ULONG_MAX, + * but this value would get interpreted as (uid_t)-1 by chown + * and its siblings. That's not what the user meant! So we + * throw an overflow exception instead. (We already + * handled a real -1 with PyLong_AsLongAndOverflow() above.) + */ + if (uid == (uid_t)-1) + goto overflow; + + /* Ensure the value wasn't truncated. */ + if (sizeof(uid_t) < sizeof(long) && + (unsigned long)uid != uresult) + goto overflow; + /* fallthrough */ + +success: + Py_DECREF(index); + *(uid_t *)p = uid; return 1; -OverflowDown: +underflow: PyErr_SetString(PyExc_OverflowError, - "user id is less than minimum"); - return 0; + "uid is less than minimum"); + goto fail; -OverflowUp: +overflow: PyErr_SetString(PyExc_OverflowError, - "user id is greater than maximum"); + "uid is greater than maximum"); + /* fallthrough */ + +fail: + Py_DECREF(index); return 0; } int _Py_Gid_Converter(PyObject *obj, void *p) { + gid_t gid; + PyObject *index; int overflow; long result; - if (PyFloat_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); + unsigned long uresult; + + index = PyNumber_Index(obj); + if (index == NULL) { + PyErr_Format(PyExc_TypeError, + "gid should be integer, not %.200s", + Py_TYPE(obj)->tp_name); return 0; } - result = PyLong_AsLongAndOverflow(obj, &overflow); - if (overflow < 0) - goto OverflowDown; - if (!overflow && result == -1) { - /* error or -1 */ - if (PyErr_Occurred()) - return 0; - *(gid_t *)p = (gid_t)-1; - } - else { - /* unsigned gid_t */ - unsigned long uresult; - if (overflow > 0) { - uresult = PyLong_AsUnsignedLong(obj); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - goto OverflowUp; - return 0; - } - if ((gid_t)uresult == (gid_t)-1) - goto OverflowUp; - } else { - if (result < 0) - goto OverflowDown; - uresult = result; + + /* + * Handling gid_t is complicated for two reasons: + * * Although gid_t is (always?) unsigned, it still + * accepts -1. + * * We don't know its size in advance--it may be + * bigger than an int, or it may be smaller than + * a long. + * + * So a bit of defensive programming is in order. + * Start with interpreting the value passed + * in as a signed long and see if it works. + */ + + result = PyLong_AsLongAndOverflow(index, &overflow); + + if (!overflow) { + gid = (gid_t)result; + + if (result == -1) { + if (PyErr_Occurred()) + goto fail; + /* It's a legitimate -1, we're done. */ + goto success; + } + + /* Any other negative number is disallowed. */ + if (result < 0) { + goto underflow; } + + /* Ensure the value wasn't truncated. */ if (sizeof(gid_t) < sizeof(long) && - (unsigned long)(gid_t)uresult != uresult) - goto OverflowUp; - *(gid_t *)p = (gid_t)uresult; + (long)gid != result) + goto underflow; + goto success; + } + + if (overflow < 0) + goto underflow; + + /* + * Okay, the value overflowed a signed long. If it + * fits in an *unsigned* long, it may still be okay, + * as gid_t may be unsigned long on this platform. + */ + uresult = PyLong_AsUnsignedLong(index); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto overflow; + goto fail; } + + gid = (gid_t)uresult; + + /* + * If gid == (gid_t)-1, the user actually passed in ULONG_MAX, + * but this value would get interpreted as (gid_t)-1 by chown + * and its siblings. That's not what the user meant! So we + * throw an overflow exception instead. (We already + * handled a real -1 with PyLong_AsLongAndOverflow() above.) + */ + if (gid == (gid_t)-1) + goto overflow; + + /* Ensure the value wasn't truncated. */ + if (sizeof(gid_t) < sizeof(long) && + (unsigned long)gid != uresult) + goto overflow; + /* fallthrough */ + +success: + Py_DECREF(index); + *(gid_t *)p = gid; return 1; -OverflowDown: +underflow: PyErr_SetString(PyExc_OverflowError, - "group id is less than minimum"); - return 0; + "gid is less than minimum"); + goto fail; -OverflowUp: +overflow: PyErr_SetString(PyExc_OverflowError, - "group id is greater than maximum"); + "gid is greater than maximum"); + /* fallthrough */ + +fail: + Py_DECREF(index); return 0; } #endif /* MS_WINDOWS */ +#ifdef HAVE_LONG_LONG +# define _PyLong_FromDev PyLong_FromLongLong +#else +# define _PyLong_FromDev PyLong_FromLong +#endif + + +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +static int +_Py_Dev_Converter(PyObject *obj, void *p) +{ +#ifdef HAVE_LONG_LONG + *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); +#else + *((dev_t *)p) = PyLong_AsUnsignedLong(obj); +#endif + if (PyErr_Occurred()) + return 0; + return 1; +} +#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ + + #ifdef AT_FDCWD /* * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); @@ -560,25 +663,29 @@ static int _fd_converter(PyObject *o, int *p, const char *allowed) { int overflow; - long long_value = PyLong_AsLongAndOverflow(o, &overflow); - if (PyFloat_Check(o) || - (long_value == -1 && !overflow && PyErr_Occurred())) { - PyErr_Clear(); + long long_value; + + PyObject *index = PyNumber_Index(o); + if (index == NULL) { PyErr_Format(PyExc_TypeError, - "argument should be %s, not %.200s", - allowed, Py_TYPE(o)->tp_name); + "argument should be %s, not %.200s", + allowed, Py_TYPE(o)->tp_name); return 0; } + + long_value = PyLong_AsLongAndOverflow(index, &overflow); + Py_DECREF(index); if (overflow > 0 || long_value > INT_MAX) { PyErr_SetString(PyExc_OverflowError, - "signed integer is greater than maximum"); + "fd is greater than maximum"); return 0; } if (overflow < 0 || long_value < INT_MIN) { PyErr_SetString(PyExc_OverflowError, - "signed integer is less than minimum"); + "fd is less than minimum"); return 0; } + *p = (int)long_value; return 1; } @@ -626,7 +733,7 @@ dir_fd_converter(PyObject *o, void *p) * path.function_name * If non-NULL, path_converter will use that as the name * of the function in error messages. - * (If path.argument_name is NULL it omits the function name.) + * (If path.function_name is NULL it omits the function name.) * path.argument_name * If non-NULL, path_converter will use that as the name * of the parameter in error messages. @@ -678,8 +785,8 @@ dir_fd_converter(PyObject *o, void *p) * path_cleanup(). However it is safe to do so.) */ typedef struct { - char *function_name; - char *argument_name; + const char *function_name; + const char *argument_name; int nullable; int allow_fd; wchar_t *wide; @@ -690,6 +797,9 @@ typedef struct { PyObject *cleanup; } path_t; +#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \ + {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL} + static void path_cleanup(path_t *path) { if (path->cleanup) { @@ -737,15 +847,19 @@ path_converter(PyObject *o, void *p) { if (unicode) { #ifdef MS_WINDOWS wchar_t *wide; - length = PyUnicode_GET_SIZE(unicode); + + wide = PyUnicode_AsUnicodeAndSize(unicode, &length); + if (!wide) { + Py_DECREF(unicode); + return 0; + } if (length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); Py_DECREF(unicode); return 0; } - - wide = PyUnicode_AsUnicode(unicode); - if (!wide) { + if (wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_TypeError, "embedded null character"); Py_DECREF(unicode); return 0; } @@ -803,7 +917,7 @@ path_converter(PyObject *o, void *p) { length = PyBytes_GET_SIZE(bytes); #ifdef MS_WINDOWS - if (length > MAX_PATH) { + if (length > MAX_PATH-1) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); Py_DECREF(bytes); return 0; @@ -1104,10 +1218,6 @@ convertenviron(void) #else char **e; #endif -#if defined(PYOS_OS2) - APIRET rc; - char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ -#endif d = PyDict_New(); if (d == NULL) @@ -1176,20 +1286,6 @@ convertenviron(void) Py_DECREF(v); } #endif -#if defined(PYOS_OS2) - rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); - if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ - PyObject *v = PyBytes_FromString(buffer); - PyDict_SetItemString(d, "BEGINLIBPATH", v); - Py_DECREF(v); - } - rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); - if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ - PyObject *v = PyBytes_FromString(buffer); - PyDict_SetItemString(d, "ENDLIBPATH", v); - Py_DECREF(v); - } -#endif return d; } @@ -1200,25 +1296,6 @@ posix_error(void) { return PyErr_SetFromErrno(PyExc_OSError); } -static PyObject * -posix_error_with_filename(char* name) -{ - return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); -} - - -static PyObject * -posix_error_with_allocated_filename(PyObject* name) -{ - PyObject *name_str, *rc; - name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name), - PyBytes_GET_SIZE(name)); - Py_DECREF(name); - rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, - name_str); - Py_XDECREF(name_str); - return rc; -} #ifdef MS_WINDOWS static PyObject * @@ -1237,24 +1314,13 @@ win32_error(char* function, const char* filename) } static PyObject * -win32_error_unicode(char* function, wchar_t* filename) -{ - /* XXX - see win32_error for comments on 'function' */ - errno = GetLastError(); - if (filename) - return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename); - else - return PyErr_SetFromWindowsErr(errno); -} - -static PyObject * win32_error_object(char* function, PyObject* filename) { /* XXX - see win32_error for comments on 'function' */ errno = GetLastError(); if (filename) return PyErr_SetExcFromWindowsErrWithFilenameObject( - PyExc_WindowsError, + PyExc_OSError, errno, filename); else @@ -1263,108 +1329,30 @@ win32_error_object(char* function, PyObject* filename) #endif /* MS_WINDOWS */ -/* - * Some functions return Win32 errors, others only ever use posix_error - * (this is for backwards compatibility with exceptions) - */ -static PyObject * -path_posix_error(char *function_name, path_t *path) -{ - if (path->narrow) - return posix_error_with_filename(path->narrow); - return posix_error(); -} - static PyObject * -path_error(char *function_name, path_t *path) +path_error(path_t *path) { #ifdef MS_WINDOWS - if (path->narrow) - return win32_error(function_name, path->narrow); - if (path->wide) - return win32_error_unicode(function_name, path->wide); - return win32_error(function_name, NULL); + return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, + 0, path->object); #else - return path_posix_error(function_name, path); + return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); #endif } -#if defined(PYOS_OS2) -/********************************************************************** - * Helper Function to Trim and Format OS/2 Messages - **********************************************************************/ -static void -os2_formatmsg(char *msgbuf, int msglen, char *reason) -{ - msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ - - if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ - char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; - - while (lastc > msgbuf && Py_ISSPACE(Py_CHARMASK(*lastc))) - *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ - } - - /* Add Optional Reason Text */ - if (reason) { - strcat(msgbuf, " : "); - strcat(msgbuf, reason); - } -} - -/********************************************************************** - * Decode an OS/2 Operating System Error Code - * - * A convenience function to lookup an OS/2 error code and return a - * text message we can use to raise a Python exception. - * - * Notes: - * The messages for errors returned from the OS/2 kernel reside in - * the file OSO001.MSG in the \OS2 directory hierarchy. - * - **********************************************************************/ -static char * -os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) -{ - APIRET rc; - ULONG msglen; - - /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ - Py_BEGIN_ALLOW_THREADS - rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, - errorcode, "oso001.msg", &msglen); - Py_END_ALLOW_THREADS - - if (rc == NO_ERROR) - os2_formatmsg(msgbuf, msglen, reason); - else - PyOS_snprintf(msgbuf, msgbuflen, - "unknown OS error #%d", errorcode); - - return msgbuf; -} - -/* Set an OS/2-specific error and return NULL. OS/2 kernel - errors are not in a global variable e.g. 'errno' nor are - they congruent with posix error numbers. */ static PyObject * -os2_error(int code) +path_error2(path_t *path, path_t *path2) { - char text[1024]; - PyObject *v; - - os2_strerror(text, sizeof(text), code, ""); - - v = Py_BuildValue("(is)", code, text); - if (v != NULL) { - PyErr_SetObject(PyExc_OSError, v); - Py_DECREF(v); - } - return NULL; /* Signal to Python that an Exception is Pending */ +#ifdef MS_WINDOWS + return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError, + 0, path->object, path2->object); +#else + return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, + path->object, path2->object); +#endif } -#endif /* OS2 */ /* POSIX generic methods */ @@ -1388,65 +1376,31 @@ posix_fildes(PyObject *fdobj, int (*func)(int)) } static PyObject * -posix_1str(PyObject *args, char *format, int (*func)(const char*)) +posix_1str(const char *func_name, PyObject *args, char *format, + int (*func)(const char*)) { - PyObject *opath1 = NULL; - char *path1; + path_t path; int res; + memset(&path, 0, sizeof(path)); + path.function_name = func_name; if (!PyArg_ParseTuple(args, format, - PyUnicode_FSConverter, &opath1)) + path_converter, &path)) return NULL; - path1 = PyBytes_AsString(opath1); Py_BEGIN_ALLOW_THREADS - res = (*func)(path1); + res = (*func)(path.narrow); Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(opath1); - Py_DECREF(opath1); + if (res < 0) { + path_error(&path); + path_cleanup(&path); + return NULL; + } + path_cleanup(&path); Py_INCREF(Py_None); return Py_None; } #ifdef MS_WINDOWS -static PyObject* -win32_1str(PyObject* args, char* func, - char* format, BOOL (__stdcall *funcA)(LPCSTR), - char* wformat, BOOL (__stdcall *funcW)(LPWSTR)) -{ - PyObject *uni; - const char *ansi; - BOOL result; - - if (PyArg_ParseTuple(args, wformat, &uni)) - { - wchar_t *wstr = PyUnicode_AsUnicode(uni); - if (wstr == NULL) - return NULL; - Py_BEGIN_ALLOW_THREADS - result = funcW(wstr); - Py_END_ALLOW_THREADS - if (!result) - return win32_error_object(func, uni); - Py_INCREF(Py_None); - return Py_None; - } - PyErr_Clear(); - - if (!PyArg_ParseTuple(args, format, &ansi)) - return NULL; - if (win32_warn_bytes_api()) - return NULL; - Py_BEGIN_ALLOW_THREADS - result = funcA(ansi); - Py_END_ALLOW_THREADS - if (!result) - return win32_error(func, ansi); - Py_INCREF(Py_None); - return Py_None; - -} - /* This is a reimplementation of the C library's chdir function, but one that produces Win32 errors instead of DOS error codes. chdir is essentially a wrapper around SetCurrentDirectory; however, @@ -1455,18 +1409,18 @@ win32_1str(PyObject* args, char* func, static BOOL __stdcall win32_chdir(LPCSTR path) { - char new_path[MAX_PATH+1]; + char new_path[MAX_PATH]; int result; char env[4] = "=x:"; if(!SetCurrentDirectoryA(path)) return FALSE; - result = GetCurrentDirectoryA(MAX_PATH+1, new_path); + result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path); if (!result) return FALSE; /* In the ANSI API, there should not be any paths longer - than MAX_PATH. */ - assert(result <= MAX_PATH+1); + than MAX_PATH-1 (not including the final null character). */ + assert(result < Py_ARRAY_LENGTH(new_path)); if (strncmp(new_path, "\\\\", 2) == 0 || strncmp(new_path, "//", 2) == 0) /* UNC path, nothing to do. */ @@ -1480,24 +1434,24 @@ win32_chdir(LPCSTR path) static BOOL __stdcall win32_wchdir(LPCWSTR path) { - wchar_t _new_path[MAX_PATH+1], *new_path = _new_path; + wchar_t _new_path[MAX_PATH], *new_path = _new_path; int result; wchar_t env[4] = L"=x:"; if(!SetCurrentDirectoryW(path)) return FALSE; - result = GetCurrentDirectoryW(MAX_PATH+1, new_path); + result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path); if (!result) return FALSE; - if (result > MAX_PATH+1) { - new_path = malloc(result * sizeof(wchar_t)); + if (result > Py_ARRAY_LENGTH(new_path)) { + new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); if (!new_path) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } result = GetCurrentDirectoryW(result, new_path); if (!result) { - free(new_path); + PyMem_RawFree(new_path); return FALSE; } } @@ -1508,7 +1462,7 @@ win32_wchdir(LPCWSTR path) env[1] = new_path[0]; result = SetEnvironmentVariableW(env, new_path); if (new_path != _new_path) - free(new_path); + PyMem_RawFree(new_path); return result; } #endif @@ -1523,13 +1477,13 @@ win32_wchdir(LPCWSTR path) #define HAVE_STAT_NSEC 1 struct win32_stat{ - int st_dev; + unsigned long st_dev; __int64 st_ino; unsigned short st_mode; int st_nlink; int st_uid; int st_gid; - int st_rdev; + unsigned long st_rdev; __int64 st_size; time_t st_atime; int st_atime_nsec; @@ -1588,6 +1542,8 @@ attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, stru memset(result, 0, sizeof(*result)); result->st_mode = attributes_to_mode(info->dwFileAttributes); result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; + result->st_dev = info->dwVolumeSerialNumber; + result->st_rdev = result->st_dev; FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); @@ -1595,9 +1551,9 @@ attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, stru result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { /* first clear the S_IFMT bits */ - result->st_mode ^= (result->st_mode & 0170000); + result->st_mode ^= (result->st_mode & S_IFMT); /* now set the bits that make this a symlink */ - result->st_mode |= 0120000; + result->st_mode |= S_IFLNK; } return 0; @@ -1650,7 +1606,7 @@ attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG * } /* Grab GetFinalPathNameByHandle dynamically from kernel32 */ -static int has_GetFinalPathNameByHandle = 0; +static int has_GetFinalPathNameByHandle = -1; static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD); static int @@ -1661,7 +1617,7 @@ check_GetFinalPathNameByHandle() DWORD); /* only recheck */ - if (!has_GetFinalPathNameByHandle) + if (-1 == has_GetFinalPathNameByHandle) { hKernel32 = GetModuleHandleW(L"KERNEL32"); *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, @@ -1687,7 +1643,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path) if(!buf_size) return FALSE; - buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + buf = PyMem_New(wchar_t, buf_size+1); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; @@ -1697,12 +1653,12 @@ get_target_path(HANDLE hdl, wchar_t **target_path) buf, buf_size, VOLUME_NAME_DOS); if(!result_length) { - free(buf); + PyMem_Free(buf); return FALSE; } if(!CloseHandle(hdl)) { - free(buf); + PyMem_Free(buf); return FALSE; } @@ -1793,7 +1749,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, return -1; code = win32_xstat_impl_w(target_path, result, FALSE); - free(target_path); + PyMem_Free(target_path); return code; } } else @@ -1889,7 +1845,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, return -1; code = win32_xstat_impl_w(target_path, result, FALSE); - free(target_path); + PyMem_Free(target_path); return code; } } else @@ -2288,11 +2244,10 @@ _pystat_fromstructstat(STRUCT_STAT *st) #else PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); #endif -#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG)st->st_dev)); +#ifdef MS_WINDOWS + PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); #else - PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev)); + PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); #if defined(MS_WINDOWS) @@ -2423,53 +2378,158 @@ posix_do_stat(char *function_name, path_t *path, result = STAT(path->narrow, &st); Py_END_ALLOW_THREADS - if (result != 0) - return path_error("stat", path); + if (result != 0) { + return path_error(path); + } return _pystat_fromstructstat(&st); } -PyDoc_STRVAR(posix_stat__doc__, -"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\ -Perform a stat system call on the given path.\n\ -\n\ -path may be specified as either a string or as an open file descriptor.\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 supported on your platform; if it is unavailable, using\n\ - it will raise a NotImplementedError.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, stat will examine the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path as\n\ - an open file descriptor."); +#ifdef HAVE_FSTATAT + #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + + +/*[python input] + +class path_t_converter(CConverter): + + type = "path_t" + impl_by_reference = True + parse_by_reference = True + + converter = 'path_converter' + + def converter_init(self, *, allow_fd=False, nullable=False): + # right now path_t doesn't support default values. + # to support a default value, you'll need to override initialize(). + if self.default is not unspecified: + fail("Can't specify a default to the path_t converter!") + + if self.c_default is not None: + fail("Can't specify a c_default to the path_t converter!") + + self.nullable = nullable + self.allow_fd = allow_fd + + def pre_render(self): + def strify(value): + return str(int(bool(value))) + + # add self.py_name here when merging with posixmodule conversion + self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format( + self.function.name, + strify(self.nullable), + strify(self.allow_fd), + ) + + def cleanup(self): + return "path_cleanup(&" + self.name + ");\n" + + +class dir_fd_converter(CConverter): + type = 'int' + converter = 'OS_STAT_DIR_FD_CONVERTER' + + def converter_init(self): + if self.default in (unspecified, None): + self.c_default = 'DEFAULT_DIR_FD' + + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/ + +/*[clinic input] + +os.stat + + path : path_t(allow_fd=True) + Path to be examined; can be string, bytes, or open-file-descriptor int. + + * + + dir_fd : dir_fd = None + If not None, it should be a file descriptor open to a directory, + and path should be a relative string; path will then be relative to + that directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + stat will examine the symbolic link itself instead of the file + the link points to. + +Perform a stat system call on the given path. + +dir_fd and follow_symlinks may not be implemented + on your platform. If they are unavailable, using them will raise a + NotImplementedError. + +It's an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_stat__doc__, +"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Perform a stat system call on the given path.\n" +"\n" +" path\n" +" Path to be examined; can be string, bytes, or open-file-descriptor int.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be a relative string; path will then be relative to\n" +" that directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" stat will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"dir_fd and follow_symlinks may not be implemented\n" +" on your platform. If they are unavailable, using them will raise a\n" +" NotImplementedError.\n" +"\n" +"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor."); + +#define OS_STAT_METHODDEF \ + {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__}, + +static PyObject * +os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks); static PyObject * -posix_stat(PyObject *self, PyObject *args, PyObject *kwargs) +os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("stat", 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - PyObject *return_value; - memset(&path, 0, sizeof(path)); - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords, - path_converter, &path, -#ifdef HAVE_FSTATAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; - return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&p:stat", _keywords, + path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ path_cleanup(&path); + return return_value; } +static PyObject * +os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/ +{ + return posix_do_stat("stat", path, dir_fd, follow_symlinks); +} + PyDoc_STRVAR(posix_lstat__doc__, "lstat(path, *, dir_fd=None) -> stat result\n\n\ Like stat(), but do not follow symbolic links.\n\ @@ -2485,6 +2545,7 @@ posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *return_value; memset(&path, 0, sizeof(path)); + path.function_name = "lstat"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, path_converter, &path, #ifdef HAVE_FSTATAT @@ -2494,44 +2555,122 @@ posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) #endif )) return NULL; - return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks); + return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks); path_cleanup(&path); return return_value; } -PyDoc_STRVAR(posix_access__doc__, -"access(path, mode, *, dir_fd=None, effective_ids=False,\ - follow_symlinks=True)\n\n\ -Use the real uid/gid to test for access to a path. Returns True if granted,\n\ -False otherwise.\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\ -If effective_ids is True, access will use the effective uid/gid instead of\n\ - the real uid/gid.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, access will examine the symbolic link itself instead of the file the\n\ - link points to.\n\ -dir_fd, effective_ids, and follow_symlinks may not be implemented\n\ - on your platform. If they are unavailable, using them will raise a\n\ - NotImplementedError.\n\ -\n\ -Note that most operations will use the effective uid/gid, therefore this\n\ - routine can be used in a suid/sgid environment to test if the invoking user\n\ - has the specified access to the path.\n\ -The mode argument can be F_OK to test existence, or the inclusive-OR\n\ - of R_OK, W_OK, and X_OK."); -static PyObject * -posix_access(PyObject *self, PyObject *args, PyObject *kwargs) +#ifdef HAVE_FACCESSAT + #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter +#else + #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable +#endif +/*[clinic input] +os.access + + path: path_t(allow_fd=True) + Path to be tested; can be string, bytes, or open-file-descriptor int. + + mode: int + Operating-system mode bitfield. Can be F_OK to test existence, + or the inclusive-OR of R_OK, W_OK, and X_OK. + + * + + dir_fd : dir_fd = None + If 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. + + effective_ids: bool = False + If True, access will use the effective uid/gid instead of + the real uid/gid. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + access will examine the symbolic link itself instead of the file + the link points to. + +Use the real uid/gid to test for access to a path. + +{parameters} +dir_fd, effective_ids, and follow_symlinks may not be implemented + on your platform. If they are unavailable, using them will raise a + NotImplementedError. + +Note that most operations will use the effective uid/gid, therefore this + routine can be used in a suid/sgid environment to test if the invoking user + has the specified access to the path. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_access__doc__, +"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Use the real uid/gid to test for access to a path.\n" +"\n" +" path\n" +" Path to be tested; can be string, bytes, or open-file-descriptor int.\n" +" mode\n" +" Operating-system mode bitfield. Can be F_OK to test existence,\n" +" or the inclusive-OR of R_OK, W_OK, and X_OK.\n" +" dir_fd\n" +" If 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\n" +" directory.\n" +" effective_ids\n" +" If True, access will use the effective uid/gid instead of\n" +" the real uid/gid.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" access will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"dir_fd, effective_ids, and follow_symlinks may not be implemented\n" +" on your platform. If they are unavailable, using them will raise a\n" +" NotImplementedError.\n" +"\n" +"Note that most operations will use the effective uid/gid, therefore this\n" +" routine can be used in a suid/sgid environment to test if the invoking user\n" +" has the specified access to the path."); + +#define OS_ACCESS_METHODDEF \ + {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__}, + +static PyObject * +os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks); + +static PyObject * +os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids", - "follow_symlinks", NULL}; - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("access", 0, 1); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i|$O&pp:access", _keywords, + path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + goto exit; + return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks) +/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/ +{ PyObject *return_value = NULL; #ifdef MS_WINDOWS @@ -2540,17 +2679,6 @@ posix_access(PyObject *self, PyObject *args, PyObject *kwargs) int result; #endif - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords, - path_converter, &path, &mode, -#ifdef HAVE_FACCESSAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &effective_ids, &follow_symlinks)) - return NULL; - #ifndef HAVE_FACCESSAT if (follow_symlinks_specified("access", follow_symlinks)) goto exit; @@ -2563,10 +2691,10 @@ posix_access(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide != NULL) - attr = GetFileAttributesW(path.wide); + if (path->wide != NULL) + attr = GetFileAttributesW(path->wide); else - attr = GetFileAttributesA(path.narrow); + attr = GetFileAttributesA(path->narrow); Py_END_ALLOW_THREADS /* @@ -2578,7 +2706,7 @@ posix_access(PyObject *self, PyObject *args, PyObject *kwargs) * (Directories cannot be read-only on Windows.) */ return_value = PyBool_FromLong( - (attr != 0xFFFFFFFF) && + (attr != INVALID_FILE_ATTRIBUTES) && (!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY))); @@ -2594,11 +2722,11 @@ posix_access(PyObject *self, PyObject *args, PyObject *kwargs) flags |= AT_SYMLINK_NOFOLLOW; if (effective_ids) flags |= AT_EACCESS; - result = faccessat(dir_fd, path.narrow, mode, flags); + result = faccessat(dir_fd, path->narrow, mode, flags); } else #endif - result = access(path.narrow, mode); + result = access(path->narrow, mode); Py_END_ALLOW_THREADS return_value = PyBool_FromLong(!result); #endif @@ -2606,7 +2734,6 @@ posix_access(PyObject *self, PyObject *args, PyObject *kwargs) #ifndef HAVE_FACCESSAT exit: #endif - path_cleanup(&path); return return_value; } @@ -2623,35 +2750,68 @@ exit: #define X_OK 1 #endif + #ifdef HAVE_TTYNAME -PyDoc_STRVAR(posix_ttyname__doc__, -"ttyname(fd) -> string\n\n\ -Return the name of the terminal device connected to 'fd'."); + +/*[clinic input] +os.ttyname -> DecodeFSDefault + + fd: int + Integer file descriptor handle. + + / + +Return the name of the terminal device connected to 'fd'. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_ttyname__doc__, +"ttyname($module, fd, /)\n" +"--\n" +"\n" +"Return the name of the terminal device connected to \'fd\'.\n" +"\n" +" fd\n" +" Integer file descriptor handle."); + +#define OS_TTYNAME_METHODDEF \ + {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__}, + +static char * +os_ttyname_impl(PyModuleDef *module, int fd); static PyObject * -posix_ttyname(PyObject *self, PyObject *args) +os_ttyname(PyModuleDef *module, PyObject *args) { - int id; - char *ret; + PyObject *return_value = NULL; + int fd; + char *_return_value; - if (!PyArg_ParseTuple(args, "i:ttyname", &id)) - return NULL; + if (!PyArg_ParseTuple(args, + "i:ttyname", + &fd)) + goto exit; + _return_value = os_ttyname_impl(module, fd); + if (_return_value == NULL) + goto exit; + return_value = PyUnicode_DecodeFSDefault(_return_value); -#if defined(__VMS) - /* file descriptor 0 only, the default input device (stdin) */ - if (id == 0) { - ret = ttyname(); - } - else { - ret = NULL; - } -#else - ret = ttyname(id); -#endif +exit: + return return_value; +} + +static char * +os_ttyname_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/ +{ + char *ret; + + ret = ttyname(fd); if (ret == NULL) - return posix_error(); - return PyUnicode_DecodeFSDefault(ret); + posix_error(); + return ret; } +#else +#define OS_TTYNAME_METHODDEF #endif #ifdef HAVE_CTERMID @@ -2693,6 +2853,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "chdir"; #ifdef HAVE_FCHDIR path.allow_fd = 1; #endif @@ -2708,8 +2869,6 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) else result = win32_chdir(path.narrow); result = !result; /* on unix, success = 0, on windows, success = !0 */ -#elif defined(PYOS_OS2) && defined(PYCC_GCC) - result = _chdir2(path.narrow); #else #ifdef HAVE_FCHDIR if (path.fd != -1) @@ -2721,7 +2880,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_error("chdir", &path); + return_value = path_error(&path); goto exit; } @@ -2785,6 +2944,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) #endif memset(&path, 0, sizeof(path)); + path.function_name = "chmod"; #ifdef HAVE_FCHMOD path.allow_fd = 1; #endif @@ -2810,7 +2970,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) attr = GetFileAttributesW(path.wide); else attr = GetFileAttributesA(path.narrow); - if (attr == 0xFFFFFFFF) + if (attr == INVALID_FILE_ATTRIBUTES) result = 0; else { if (mode & _S_IWRITE) @@ -2825,7 +2985,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (!result) { - return_value = win32_error_object("chmod", path.object); + return_value = path_error(&path); goto exit; } #else /* MS_WINDOWS */ @@ -2879,7 +3039,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) } else #endif - return_value = path_error("chmod", &path); + return_value = path_error(&path); goto exit; } #endif @@ -2923,20 +3083,23 @@ Equivalent to chmod(path, mode, follow_symlinks=False)."); static PyObject * posix_lchmod(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + path_t path; int i; int res; - if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter, - &opath, &i)) + memset(&path, 0, sizeof(path)); + path.function_name = "lchmod"; + if (!PyArg_ParseTuple(args, "O&i:lchmod", + path_converter, &path, &i)) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS - res = lchmod(path, i); + res = lchmod(path.narrow, i); Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(opath); - Py_DECREF(opath); + if (res < 0) { + path_error(&path); + path_cleanup(&path); + return NULL; + } + path_cleanup(&path); Py_RETURN_NONE; } #endif /* HAVE_LCHMOD */ @@ -2964,6 +3127,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "chflags"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, path_converter, &path, &flags, &follow_symlinks)) @@ -2984,7 +3148,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_posix_error("chflags", &path); + return_value = path_error(&path); goto exit; } @@ -3007,22 +3171,24 @@ Equivalent to chflags(path, flags, follow_symlinks=False)."); static PyObject * posix_lchflags(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + path_t path; unsigned long flags; int res; + memset(&path, 0, sizeof(path)); + path.function_name = "lchflags"; if (!PyArg_ParseTuple(args, "O&k:lchflags", - PyUnicode_FSConverter, &opath, &flags)) + path_converter, &path, &flags)) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS - res = lchflags(path, flags); + res = lchflags(path.narrow, flags); Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(opath); - Py_DECREF(opath); - Py_INCREF(Py_None); - return Py_None; + if (res < 0) { + path_error(&path); + path_cleanup(&path); + return NULL; + } + path_cleanup(&path); + Py_RETURN_NONE; } #endif /* HAVE_LCHFLAGS */ @@ -3034,7 +3200,7 @@ Change root directory to path."); static PyObject * posix_chroot(PyObject *self, PyObject *args) { - return posix_1str(args, "O&:chroot", chroot); + return posix_1str("chroot", args, "O&:chroot", chroot); } #endif @@ -3116,6 +3282,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) "follow_symlinks", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "chown"; #ifdef HAVE_FCHOWN path.allow_fd = 1; #endif @@ -3173,7 +3340,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_posix_error("chown", &path); + return_value = path_error(&path); goto exit; } @@ -3222,49 +3389,54 @@ Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); static PyObject * posix_lchown(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + path_t path; uid_t uid; gid_t gid; int res; + memset(&path, 0, sizeof(path)); + path.function_name = "lchown"; if (!PyArg_ParseTuple(args, "O&O&O&:lchown", - PyUnicode_FSConverter, &opath, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS - res = lchown(path, uid, gid); + res = lchown(path.narrow, uid, gid); Py_END_ALLOW_THREADS - if (res < 0) - return posix_error_with_allocated_filename(opath); - Py_DECREF(opath); + if (res < 0) { + path_error(&path); + path_cleanup(&path); + return NULL; + } + path_cleanup(&path); Py_INCREF(Py_None); return Py_None; } #endif /* HAVE_LCHOWN */ -#ifdef HAVE_GETCWD static PyObject * posix_getcwd(int use_bytes) { - char buf[1026]; - char *res; + char *buf, *tmpbuf; + char *cwd; + const size_t chunk = 1024; + size_t buflen = 0; + PyObject *obj; #ifdef MS_WINDOWS if (!use_bytes) { - wchar_t wbuf[1026]; + wchar_t wbuf[MAXPATHLEN]; wchar_t *wbuf2 = wbuf; PyObject *resobj; DWORD len; Py_BEGIN_ALLOW_THREADS - len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf); + len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); /* If the buffer is large enough, len does not include the terminating \0. If the buffer is too small, len includes the space needed for the terminator. */ - if (len >= sizeof wbuf/ sizeof wbuf[0]) { - wbuf2 = malloc(len * sizeof(wchar_t)); + if (len >= Py_ARRAY_LENGTH(wbuf)) { + wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); if (wbuf2) len = GetCurrentDirectoryW(len, wbuf2); } @@ -3274,11 +3446,13 @@ posix_getcwd(int use_bytes) return NULL; } if (!len) { - if (wbuf2 != wbuf) free(wbuf2); - return win32_error("getcwdu", NULL); + if (wbuf2 != wbuf) + PyMem_RawFree(wbuf2); + return PyErr_SetFromWindowsErr(0); } resobj = PyUnicode_FromWideChar(wbuf2, len); - if (wbuf2 != wbuf) free(wbuf2); + if (wbuf2 != wbuf) + PyMem_RawFree(wbuf2); return resobj; } @@ -3286,18 +3460,31 @@ posix_getcwd(int use_bytes) return NULL; #endif + buf = cwd = NULL; Py_BEGIN_ALLOW_THREADS -#if defined(PYOS_OS2) && defined(PYCC_GCC) - res = _getcwd2(buf, sizeof buf); -#else - res = getcwd(buf, sizeof buf); -#endif + do { + buflen += chunk; + tmpbuf = PyMem_RawRealloc(buf, buflen); + if (tmpbuf == NULL) + break; + + buf = tmpbuf; + cwd = getcwd(buf, buflen); + } while (cwd == NULL && errno == ERANGE); Py_END_ALLOW_THREADS - if (res == NULL) + + if (cwd == NULL) { + PyMem_RawFree(buf); return posix_error(); + } + if (use_bytes) - return PyBytes_FromStringAndSize(buf, strlen(buf)); - return PyUnicode_DecodeFSDefault(buf); + obj = PyBytes_FromStringAndSize(buf, strlen(buf)); + else + obj = PyUnicode_DecodeFSDefault(buf); + PyMem_RawFree(buf); + + return obj; } PyDoc_STRVAR(posix_getcwd__doc__, @@ -3319,7 +3506,6 @@ posix_getcwd_bytes(PyObject *self) { return posix_getcwd(1); } -#endif #if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) #define HAVE_LINK 1 @@ -3358,6 +3544,8 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs) memset(&src, 0, sizeof(src)); memset(&dst, 0, sizeof(dst)); + src.function_name = "link"; + dst.function_name = "link"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, path_converter, &src, path_converter, &dst, @@ -3388,7 +3576,7 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (!result) { - return_value = win32_error_object("link", dst.object); + return_value = path_error2(&src, &dst); goto exit; } #else @@ -3406,7 +3594,7 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_error("link", &dst); + return_value = path_error2(&src, &dst); goto exit; } #endif @@ -3436,72 +3624,35 @@ On some platforms, path may also be specified as an open file descriptor;\n\ the file descriptor must refer to a directory.\n\ If this functionality is unavailable, using it raises NotImplementedError."); +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) static PyObject * -posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) +_listdir_windows_no_opendir(path_t *path, PyObject *list) { - path_t path; - PyObject *list = NULL; static char *keywords[] = {"path", NULL}; -#ifdef HAVE_FDOPENDIR - int fd = -1; -#endif /* HAVE_FDOPENDIR */ - -#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; BOOL result; WIN32_FIND_DATA FileData; - char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */ + char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ char *bufptr = namebuf; /* only claim to have space for MAX_PATH */ - Py_ssize_t len = sizeof(namebuf)-5; + Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; PyObject *po = NULL; wchar_t *wnamebuf = NULL; -#elif defined(PYOS_OS2) -#ifndef MAX_PATH -#define MAX_PATH CCHMAXPATH -#endif - char *pt; - PyObject *v; - char namebuf[MAX_PATH+5]; - HDIR hdir = 1; - ULONG srchcnt = 1; - FILEFINDBUF3 ep; - APIRET rc; -#else - PyObject *v; - DIR *dirp = NULL; - struct dirent *ep; - int return_str; /* if false, return bytes */ -#endif - - memset(&path, 0, sizeof(path)); - path.nullable = 1; -#ifdef HAVE_FDOPENDIR - path.allow_fd = 1; - path.fd = -1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, - path_converter, &path - )) - return NULL; - /* XXX Should redo this putting the (now four) versions of opendir - in separate files instead of having them all here... */ -#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - if (!path.narrow) { + if (!path->narrow) { WIN32_FIND_DATAW wFileData; wchar_t *po_wchars; - if (!path.wide) { /* Default arg: "." */ + if (!path->wide) { /* Default arg: "." */ po_wchars = L"."; len = 1; } else { - po_wchars = path.wide; - len = wcslen(path.wide); + po_wchars = path->wide; + len = wcslen(path->wide); } /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = malloc((len + 5) * sizeof(wchar_t)); + wnamebuf = PyMem_New(wchar_t, len + 5); if (!wnamebuf) { PyErr_NoMemory(); goto exit; @@ -3509,8 +3660,8 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) wcscpy(wnamebuf, po_wchars); if (len > 0) { wchar_t wch = wnamebuf[len-1]; - if (wch != L'/' && wch != L'\\' && wch != L':') - wnamebuf[len++] = L'\\'; + if (wch != SEP && wch != ALTSEP && wch != L':') + wnamebuf[len++] = SEP; wcscpy(wnamebuf + len, L"*.*"); } if ((list = PyList_New(0)) == NULL) { @@ -3524,8 +3675,7 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) if (error == ERROR_FILE_NOT_FOUND) goto exit; Py_DECREF(list); - list = NULL; - win32_error_unicode("FindFirstFileW", wnamebuf); + list = path_error(path); goto exit; } do { @@ -3554,19 +3704,19 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { Py_DECREF(list); - list = win32_error_unicode("FindNextFileW", wnamebuf); + list = path_error(path); goto exit; } } while (result == TRUE); goto exit; } - strcpy(namebuf, path.narrow); - len = path.length; + strcpy(namebuf, path->narrow); + len = path->length; if (len > 0) { char ch = namebuf[len-1]; - if (ch != SEP && ch != ALTSEP && ch != ':') - namebuf[len++] = '/'; + if (ch != '\\' && ch != '/' && ch != ':') + namebuf[len++] = '\\'; strcpy(namebuf + len, "*.*"); } @@ -3581,7 +3731,7 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) if (error == ERROR_FILE_NOT_FOUND) goto exit; Py_DECREF(list); - list = win32_error("FindFirstFile", namebuf); + list = path_error(path); goto exit; } do { @@ -3609,7 +3759,7 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { Py_DECREF(list); - list = win32_error("FindNextFile", namebuf); + list = path_error(path); goto exit; } } while (result == TRUE); @@ -3619,92 +3769,35 @@ exit: if (FindClose(hFindFile) == FALSE) { if (list != NULL) { Py_DECREF(list); - list = win32_error_object("FindClose", path.object); + list = path_error(path); } } } - if (wnamebuf) - free(wnamebuf); - path_cleanup(&path); + PyMem_Free(wnamebuf); return list; +} /* end of _listdir_windows_no_opendir */ -#elif defined(PYOS_OS2) - if (path.length >= MAX_PATH) { - PyErr_SetString(PyExc_ValueError, "path too long"); - goto exit; - } - strcpy(namebuf, path.narrow); - for (pt = namebuf; *pt; pt++) - if (*pt == ALTSEP) - *pt = SEP; - if (namebuf[len-1] != SEP) - namebuf[len++] = SEP; - strcpy(namebuf + len, "*.*"); - - if ((list = PyList_New(0)) == NULL) { - goto exit; - } - - rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ - &hdir, /* Handle to Use While Search Directory */ - FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, - &ep, sizeof(ep), /* Structure to Receive Directory Entry */ - &srchcnt, /* Max and Actual Count of Entries Per Iteration */ - FIL_STANDARD); /* Format of Entry (EAs or Not) */ - - if (rc != NO_ERROR) { - errno = ENOENT; - Py_DECREF(list); - list = posix_error_with_filename(path.narrow); - goto exit; - } - - if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ - do { - if (ep.achName[0] == '.' - && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0'))) - continue; /* Skip Over "." and ".." Names */ - - strcpy(namebuf, ep.achName); - - /* Leave Case of Name Alone -- In Native Form */ - /* (Removed Forced Lowercasing Code) */ +#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */ - v = PyBytes_FromString(namebuf); - if (v == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - if (PyList_Append(list, v) != 0) { - Py_DECREF(v); - Py_DECREF(list); - list = NULL; - break; - } - Py_DECREF(v); - } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); - } - -exit: - path_cleanup(&path); - - return list; -#else +static PyObject * +_posix_listdir(path_t *path, PyObject *list) +{ + PyObject *v; + DIR *dirp = NULL; + struct dirent *ep; + int return_str; /* if false, return bytes */ +#ifdef HAVE_FDOPENDIR + int fd = -1; +#endif errno = 0; #ifdef HAVE_FDOPENDIR - if (path.fd != -1) { + if (path->fd != -1) { /* closedir() closes the FD, so we duplicate it */ - Py_BEGIN_ALLOW_THREADS - fd = dup(path.fd); - Py_END_ALLOW_THREADS - - if (fd == -1) { - list = posix_error(); - goto exit; - } + fd = _Py_dup(path->fd); + if (fd == -1) + return NULL; return_str = 1; @@ -3716,10 +3809,10 @@ exit: #endif { char *name; - if (path.narrow) { - name = path.narrow; + if (path->narrow) { + name = path->narrow; /* only return bytes if they specified a bytes object */ - return_str = !(PyBytes_Check(path.object)); + return_str = !(PyBytes_Check(path->object)); } else { name = "."; @@ -3732,14 +3825,14 @@ exit: } if (dirp == NULL) { - list = path_error("listdir", &path); + list = path_error(path); #ifdef HAVE_FDOPENDIR if (fd != -1) { Py_BEGIN_ALLOW_THREADS close(fd); Py_END_ALLOW_THREADS } -#endif /* HAVE_FDOPENDIR */ +#endif goto exit; } if ((list = PyList_New(0)) == NULL) { @@ -3755,7 +3848,7 @@ exit: break; } else { Py_DECREF(list); - list = path_error("listdir", &path); + list = path_error(path); goto exit; } } @@ -3785,17 +3878,44 @@ exit: #ifdef HAVE_FDOPENDIR if (fd > -1) rewinddir(dirp); -#endif /* HAVE_FDOPENDIR */ +#endif closedir(dirp); Py_END_ALLOW_THREADS } - path_cleanup(&path); - return list; +} /* end of _posix_listdir */ +#endif /* which OS */ -#endif /* which OS */ -} /* end of posix_listdir */ +static PyObject * +posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) +{ + path_t path; + PyObject *list = NULL; + static char *keywords[] = {"path", NULL}; + PyObject *return_value; + + memset(&path, 0, sizeof(path)); + path.function_name = "listdir"; + path.nullable = 1; +#ifdef HAVE_FDOPENDIR + path.allow_fd = 1; + path.fd = -1; +#endif + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, + path_converter, &path)) { + return NULL; + } + +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) + return_value = _listdir_windows_no_opendir(&path, list); +#else + return_value = _posix_listdir(&path, list); +#endif + path_cleanup(&path); + return return_value; +} #ifdef MS_WINDOWS /* A helper function for abspath on win32 */ @@ -3803,14 +3923,14 @@ static PyObject * posix__getfullpathname(PyObject *self, PyObject *args) { const char *path; - char outbuf[MAX_PATH*2]; + char outbuf[MAX_PATH]; char *temp; PyObject *po; if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) { wchar_t *wpath; - wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf; + wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; wchar_t *wtemp; DWORD result; PyObject *v; @@ -3822,7 +3942,7 @@ posix__getfullpathname(PyObject *self, PyObject *args) Py_ARRAY_LENGTH(woutbuf), woutbuf, &wtemp); if (result > Py_ARRAY_LENGTH(woutbuf)) { - woutbufp = malloc(result * sizeof(wchar_t)); + woutbufp = PyMem_New(wchar_t, result); if (!woutbufp) return PyErr_NoMemory(); result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); @@ -3832,7 +3952,7 @@ posix__getfullpathname(PyObject *self, PyObject *args) else v = win32_error_object("GetFullPathNameW", po); if (woutbufp != woutbuf) - free(woutbufp); + PyMem_Free(woutbufp); return v; } /* Drop the argument parsing error as narrow strings @@ -3902,7 +4022,7 @@ posix__getfinalpathname(PyObject *self, PyObject *args) if(!buf_size) return win32_error_object("GetFinalPathNameByHandle", po); - target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + target_path = PyMem_New(wchar_t, buf_size+1); if(!target_path) return PyErr_NoMemory(); @@ -3916,36 +4036,11 @@ posix__getfinalpathname(PyObject *self, PyObject *args) target_path[result_length] = 0; result = PyUnicode_FromWideChar(target_path, result_length); - free(target_path); + PyMem_Free(target_path); return result; } /* end of posix__getfinalpathname */ -static PyObject * -posix__getfileinformation(PyObject *self, PyObject *args) -{ - HANDLE hFile; - BY_HANDLE_FILE_INFORMATION info; - int fd; - - if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd)) - return NULL; - - if (!_PyVerify_fd(fd)) - return posix_error(); - - hFile = (HANDLE)_get_osfhandle(fd); - if (hFile == INVALID_HANDLE_VALUE) - return posix_error(); - - if (!GetFileInformationByHandle(hFile, &info)) - return win32_error("_getfileinformation", NULL); - - return Py_BuildValue("iii", info.dwVolumeSerialNumber, - info.nFileIndexHigh, - info.nFileIndexLow); -} - PyDoc_STRVAR(posix__isdir__doc__, "Return true if the pathname refers to an existing directory."); @@ -3984,6 +4079,55 @@ check: else Py_RETURN_FALSE; } + +PyDoc_STRVAR(posix__getvolumepathname__doc__, +"Return volume mount point of the specified path."); + +/* A helper function for ismount on windows */ +static PyObject * +posix__getvolumepathname(PyObject *self, PyObject *args) +{ + PyObject *po, *result; + wchar_t *path, *mountpath=NULL; + size_t buflen; + BOOL ret; + + if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) + return NULL; + path = PyUnicode_AsUnicodeAndSize(po, &buflen); + if (path == NULL) + return NULL; + buflen += 1; + + /* Volume path should be shorter than entire path */ + buflen = Py_MAX(buflen, MAX_PATH); + + if (buflen > DWORD_MAX) { + PyErr_SetString(PyExc_OverflowError, "path too long"); + return NULL; + } + + mountpath = PyMem_New(wchar_t, buflen); + if (mountpath == NULL) + return PyErr_NoMemory(); + + Py_BEGIN_ALLOW_THREADS + ret = GetVolumePathNameW(path, mountpath, + Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); + Py_END_ALLOW_THREADS + + if (!ret) { + result = win32_error_object("_getvolumepathname", po); + goto exit; + } + result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); + +exit: + PyMem_Free(mountpath); + return result; +} +/* end of posix__getvolumepathname */ + #endif /* MS_WINDOWS */ PyDoc_STRVAR(posix_mkdir__doc__, @@ -4008,6 +4152,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) int result; memset(&path, 0, sizeof(path)); + path.function_name = "mkdir"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, path_converter, &path, &mode, #ifdef HAVE_MKDIRAT @@ -4027,7 +4172,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (!result) { - return_value = win32_error_object("mkdir", path.object); + return_value = path_error(&path); goto exit; } #else @@ -4044,7 +4189,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) #endif Py_END_ALLOW_THREADS if (result < 0) { - return_value = path_error("mkdir", &path); + return_value = path_error(&path); goto exit; } #endif @@ -4162,6 +4307,8 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) memset(&src, 0, sizeof(src)); memset(&dst, 0, sizeof(dst)); + src.function_name = function_name; + dst.function_name = function_name; strcpy(format, "O&O&|$O&O&:"); strcat(format, function_name); if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, @@ -4195,7 +4342,7 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) Py_END_ALLOW_THREADS if (!result) { - return_value = win32_error_object(function_name, dst.object); + return_value = path_error2(&src, &dst); goto exit; } @@ -4210,7 +4357,7 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) Py_END_ALLOW_THREADS if (result) { - return_value = path_error(function_name, &dst); + return_value = path_error2(&src, &dst); goto exit; } #endif @@ -4274,6 +4421,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; memset(&path, 0, sizeof(path)); + path.function_name = "rmdir"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, path_converter, &path, #ifdef HAVE_UNLINKAT @@ -4302,7 +4450,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_error("rmdir", &path); + return_value = path_error(&path); goto exit; } @@ -4430,6 +4578,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; memset(&path, 0, sizeof(path)); + path.function_name = "unlink"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, path_converter, &path, #ifdef HAVE_UNLINKAT @@ -4458,7 +4607,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_error("unlink", &path); + return_value = path_error(&path); goto exit; } @@ -4546,7 +4695,7 @@ posix_uname(PyObject *self, PyObject *noargs) PyDoc_STRVAR(posix_utime__doc__, -"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\ +"utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\ Set the access and modified time of path.\n\ \n\ path may always be specified as a string.\n\ @@ -4555,10 +4704,10 @@ On some platforms, path may also be specified as an open file descriptor.\n\ \n\ If times is not None, it must be a tuple (atime, mtime);\n\ atime and mtime should be expressed as float seconds since the epoch.\n\ -If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\ +If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n\ atime_ns and mtime_ns should be expressed as integer nanoseconds\n\ since the epoch.\n\ -If both times and ns are None, utime uses the current time.\n\ +If times is None and ns is unspecified, utime uses the current time.\n\ Specifying tuples for both times and ns is an error.\n\ \n\ If dir_fd is not None, it should be a file descriptor open to a directory,\n\ @@ -4580,64 +4729,62 @@ typedef struct { } utime_t; /* - * these macros assume that "utime" is a pointer to a utime_t + * these macros assume that "ut" is a pointer to a utime_t * they also intentionally leak the declaration of a pointer named "time" */ #define UTIME_TO_TIMESPEC \ struct timespec ts[2]; \ struct timespec *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - ts[0].tv_sec = utime->atime_s; \ - ts[0].tv_nsec = utime->atime_ns; \ - ts[1].tv_sec = utime->mtime_s; \ - ts[1].tv_nsec = utime->mtime_ns; \ + ts[0].tv_sec = ut->atime_s; \ + ts[0].tv_nsec = ut->atime_ns; \ + ts[1].tv_sec = ut->mtime_s; \ + ts[1].tv_nsec = ut->mtime_ns; \ time = ts; \ } \ #define UTIME_TO_TIMEVAL \ struct timeval tv[2]; \ struct timeval *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - tv[0].tv_sec = utime->atime_s; \ - tv[0].tv_usec = utime->atime_ns / 1000; \ - tv[1].tv_sec = utime->mtime_s; \ - tv[1].tv_usec = utime->mtime_ns / 1000; \ + tv[0].tv_sec = ut->atime_s; \ + tv[0].tv_usec = ut->atime_ns / 1000; \ + tv[1].tv_sec = ut->mtime_s; \ + tv[1].tv_usec = ut->mtime_ns / 1000; \ time = tv; \ } \ #define UTIME_TO_UTIMBUF \ - struct utimbuf u[2]; \ + struct utimbuf u; \ struct utimbuf *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - u.actime = utime->atime_s; \ - u.modtime = utime->mtime_s; \ - time = u; \ + u.actime = ut->atime_s; \ + u.modtime = ut->mtime_s; \ + time = &u; \ } #define UTIME_TO_TIME_T \ time_t timet[2]; \ - struct timet time; \ - if (utime->now) \ + time_t *time; \ + if (ut->now) \ time = NULL; \ else { \ - timet[0] = utime->atime_s; \ - timet[1] = utime->mtime_s; \ - time = &timet; \ + timet[0] = ut->atime_s; \ + timet[1] = ut->mtime_s; \ + time = timet; \ } \ -#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)) - -#if UTIME_HAVE_DIR_FD +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) static int -utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) +utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks) { #ifdef HAVE_UTIMENSAT int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; @@ -4657,12 +4804,10 @@ utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) #endif -#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)) - -#if UTIME_HAVE_FD +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) static int -utime_fd(utime_t *utime, int fd) +utime_fd(utime_t *ut, int fd) { #ifdef HAVE_FUTIMENS UTIME_TO_TIMESPEC; @@ -4682,7 +4827,7 @@ utime_fd(utime_t *utime, int fd) #if UTIME_HAVE_NOFOLLOW_SYMLINKS static int -utime_nofollow_symlinks(utime_t *utime, char *path) +utime_nofollow_symlinks(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4698,7 +4843,7 @@ utime_nofollow_symlinks(utime_t *utime, char *path) #ifndef MS_WINDOWS static int -utime_default(utime_t *utime, char *path) +utime_default(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4761,15 +4906,16 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; memset(&path, 0, sizeof(path)); + path.function_name = "utime"; memset(&utime, 0, sizeof(utime_t)); -#if UTIME_HAVE_FD +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) path.allow_fd = 1; #endif if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|O$OO&p:utime", keywords, path_converter, &path, ×, &ns, -#if UTIME_HAVE_DIR_FD +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) dir_fd_converter, &dir_fd, #else dir_fd_unavailable, &dir_fd, @@ -4796,9 +4942,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) } utime.now = 0; if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), - &a_sec, &a_nsec) == -1 || + &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 || _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), - &m_sec, &m_nsec) == -1) { + &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) { goto exit; } utime.atime_s = a_sec; @@ -4856,18 +5002,13 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { - win32_error_object("utime", path.object); + path_error(&path); goto exit; } if (utime.now) { - SYSTEMTIME now; - GetSystemTime(&now); - if (!SystemTimeToFileTime(&now, &mtime) || - !SystemTimeToFileTime(&now, &atime)) { - win32_error("utime", NULL); - goto exit; - } + GetSystemTimeAsFileTime(&mtime); + atime = mtime; } else { time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); @@ -4878,7 +5019,7 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) as that may confuse the user into believing that something is wrong with the file, when it also could be the time stamp that gives a problem. */ - win32_error("utime", NULL); + PyErr_SetFromWindowsErr(0); goto exit; } #else /* MS_WINDOWS */ @@ -4890,13 +5031,13 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) else #endif -#if UTIME_HAVE_DIR_FD +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks); else #endif -#if UTIME_HAVE_FD +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) if (path.fd != -1) result = utime_fd(&utime, path.fd); else @@ -4961,8 +5102,10 @@ int fsconvert_strdup(PyObject *o, char**out) return 0; size = PyBytes_GET_SIZE(bytes); *out = PyMem_Malloc(size+1); - if (!*out) + if (!*out) { + PyErr_NoMemory(); return 0; + } memcpy(*out, PyBytes_AsString(bytes), size+1); Py_DECREF(bytes); return 1; @@ -4990,8 +5133,10 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) } envc = 0; keys = PyMapping_Keys(env); + if (!keys) + goto error; vals = PyMapping_Values(env); - if (!keys || !vals) + if (!vals) goto error; if (!PyList_Check(keys) || !PyList_Check(vals)) { PyErr_Format(PyExc_TypeError, @@ -5012,10 +5157,6 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) goto error; } -#if defined(PYOS_OS2) - /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ - if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { -#endif k = PyBytes_AsString(key2); v = PyBytes_AsString(val2); len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2; @@ -5031,9 +5172,6 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) envlist[envc++] = p; Py_DECREF(key2); Py_DECREF(val2); -#if defined(PYOS_OS2) - } -#endif } Py_DECREF(vals); Py_DECREF(keys); @@ -5159,6 +5297,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) like posix.environ. */ memset(&path, 0, sizeof(path)); + path.function_name = "execve"; #ifdef HAVE_FEXECVE path.allow_fd = 1; #endif @@ -5198,7 +5337,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) /* If we get here it's definitely an error */ - path_posix_error("execve", &path); + path_error(&path); while (--envc >= 0) PyMem_DEL(envlist[envc]); @@ -5274,18 +5413,12 @@ posix_spawnv(PyObject *self, PyObject *args) } argvlist[argc] = NULL; -#if defined(PYOS_OS2) && defined(PYCC_GCC) - Py_BEGIN_ALLOW_THREADS - spawnval = spawnv(mode, path, argvlist); - Py_END_ALLOW_THREADS -#else if (mode == _OLD_P_OVERLAY) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS spawnval = _spawnv(mode, path, argvlist); Py_END_ALLOW_THREADS -#endif free_string_array(argvlist, argc); Py_DECREF(opath); @@ -5293,11 +5426,7 @@ posix_spawnv(PyObject *self, PyObject *args) if (spawnval == -1) return posix_error(); else -#if SIZEOF_LONG == SIZEOF_VOID_P - return Py_BuildValue("l", (long) spawnval); -#else - return Py_BuildValue("L", (PY_LONG_LONG) spawnval); -#endif + return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); } @@ -5373,27 +5502,17 @@ posix_spawnve(PyObject *self, PyObject *args) if (envlist == NULL) goto fail_1; -#if defined(PYOS_OS2) && defined(PYCC_GCC) - Py_BEGIN_ALLOW_THREADS - spawnval = spawnve(mode, path, argvlist, envlist); - Py_END_ALLOW_THREADS -#else if (mode == _OLD_P_OVERLAY) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS spawnval = _spawnve(mode, path, argvlist, envlist); Py_END_ALLOW_THREADS -#endif if (spawnval == -1) (void) posix_error(); else -#if SIZEOF_LONG == SIZEOF_VOID_P - res = Py_BuildValue("l", (long) spawnval); -#else - res = Py_BuildValue("L", (PY_LONG_LONG) spawnval); -#endif + res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); while (--envc >= 0) PyMem_DEL(envlist[envc]); @@ -5405,183 +5524,6 @@ posix_spawnve(PyObject *self, PyObject *args) return res; } -/* OS/2 supports spawnvp & spawnvpe natively */ -#if defined(PYOS_OS2) -PyDoc_STRVAR(posix_spawnvp__doc__, -"spawnvp(mode, file, args)\n\n\ -Execute the program 'file' in a new process, using the environment\n\ -search path to find the file.\n\ -\n\ - mode: mode of process creation\n\ - file: executable file name\n\ - args: tuple or list of strings"); - -static PyObject * -posix_spawnvp(PyObject *self, PyObject *args) -{ - PyObject *opath; - char *path; - PyObject *argv; - char **argvlist; - int mode, i, argc; - Py_intptr_t spawnval; - PyObject *(*getitem)(PyObject *, Py_ssize_t); - - /* spawnvp has three arguments: (mode, path, argv), where - argv is a list or tuple of strings. */ - - if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode, - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); - if (PyList_Check(argv)) { - argc = PyList_Size(argv); - getitem = PyList_GetItem; - } - else if (PyTuple_Check(argv)) { - argc = PyTuple_Size(argv); - getitem = PyTuple_GetItem; - } - else { - PyErr_SetString(PyExc_TypeError, - "spawnvp() arg 2 must be a tuple or list"); - Py_DECREF(opath); - return NULL; - } - - argvlist = PyMem_NEW(char *, argc+1); - if (argvlist == NULL) { - Py_DECREF(opath); - return PyErr_NoMemory(); - } - for (i = 0; i < argc; i++) { - if (!fsconvert_strdup((*getitem)(argv, i), - &argvlist[i])) { - free_string_array(argvlist, i); - PyErr_SetString( - PyExc_TypeError, - "spawnvp() arg 2 must contain only strings"); - Py_DECREF(opath); - return NULL; - } - } - argvlist[argc] = NULL; - - Py_BEGIN_ALLOW_THREADS -#if defined(PYCC_GCC) - spawnval = spawnvp(mode, path, argvlist); -#else - spawnval = _spawnvp(mode, path, argvlist); -#endif - Py_END_ALLOW_THREADS - - free_string_array(argvlist, argc); - Py_DECREF(opath); - - if (spawnval == -1) - return posix_error(); - else - return Py_BuildValue("l", (long) spawnval); -} - - -PyDoc_STRVAR(posix_spawnvpe__doc__, -"spawnvpe(mode, file, args, env)\n\n\ -Execute the program 'file' in a new process, using the environment\n\ -search path to find the file.\n\ -\n\ - mode: mode of process creation\n\ - file: executable file name\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings"); - -static PyObject * -posix_spawnvpe(PyObject *self, PyObject *args) -{ - PyObject *opath; - char *path; - PyObject *argv, *env; - char **argvlist; - char **envlist; - PyObject *res=NULL; - int mode; - Py_ssize_t argc, i, envc; - Py_intptr_t spawnval; - PyObject *(*getitem)(PyObject *, Py_ssize_t); - int lastarg = 0; - - /* spawnvpe has four arguments: (mode, path, argv, env), where - argv is a list or tuple of strings and env is a dictionary - like posix.environ. */ - - if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode, - PyUnicode_FSConverter, - &opath, &argv, &env)) - return NULL; - path = PyBytes_AsString(opath); - if (PyList_Check(argv)) { - argc = PyList_Size(argv); - getitem = PyList_GetItem; - } - else if (PyTuple_Check(argv)) { - argc = PyTuple_Size(argv); - getitem = PyTuple_GetItem; - } - else { - PyErr_SetString(PyExc_TypeError, - "spawnvpe() arg 2 must be a tuple or list"); - goto fail_0; - } - if (!PyMapping_Check(env)) { - PyErr_SetString(PyExc_TypeError, - "spawnvpe() arg 3 must be a mapping object"); - goto fail_0; - } - - argvlist = PyMem_NEW(char *, argc+1); - if (argvlist == NULL) { - PyErr_NoMemory(); - goto fail_0; - } - for (i = 0; i < argc; i++) { - if (!fsconvert_strdup((*getitem)(argv, i), - &argvlist[i])) - { - lastarg = i; - goto fail_1; - } - } - lastarg = argc; - argvlist[argc] = NULL; - - envlist = parse_envlist(env, &envc); - if (envlist == NULL) - goto fail_1; - - Py_BEGIN_ALLOW_THREADS -#if defined(PYCC_GCC) - spawnval = spawnvpe(mode, path, argvlist, envlist); -#else - spawnval = _spawnvpe(mode, path, argvlist, envlist); -#endif - Py_END_ALLOW_THREADS - - if (spawnval == -1) - (void) posix_error(); - else - res = Py_BuildValue("l", (long) spawnval); - - while (--envc >= 0) - PyMem_DEL(envlist[envc]); - PyMem_DEL(envlist); - fail_1: - free_string_array(argvlist, lastarg); - fail_0: - Py_DECREF(opath); - return res; -} -#endif /* PYOS_OS2 */ #endif /* HAVE_SPAWNV */ @@ -6084,7 +6026,7 @@ Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); static PyObject * posix_openpty(PyObject *self, PyObject *noargs) { - int master_fd, slave_fd; + int master_fd = -1, slave_fd = -1; #ifndef HAVE_OPENPTY char * slave_name; #endif @@ -6097,37 +6039,56 @@ posix_openpty(PyObject *self, PyObject *noargs) #ifdef HAVE_OPENPTY if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) - return posix_error(); + goto posix_error; + + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto error; + if (_Py_set_inheritable(slave_fd, 0, NULL) < 0) + goto error; + #elif defined(HAVE__GETPTY) slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); if (slave_name == NULL) - return posix_error(); + goto posix_error; + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto error; - slave_fd = open(slave_name, O_RDWR); + slave_fd = _Py_open(slave_name, O_RDWR); if (slave_fd < 0) - return posix_error(); + goto posix_error; + #else master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ if (master_fd < 0) - return posix_error(); + goto posix_error; + sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); + /* change permission of slave */ if (grantpt(master_fd) < 0) { PyOS_setsig(SIGCHLD, sig_saved); - return posix_error(); + goto posix_error; } + /* unlock slave */ if (unlockpt(master_fd) < 0) { PyOS_setsig(SIGCHLD, sig_saved); - return posix_error(); + goto posix_error; } + PyOS_setsig(SIGCHLD, sig_saved); + slave_name = ptsname(master_fd); /* get name of slave */ if (slave_name == NULL) - return posix_error(); - slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ + goto posix_error; + + slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ if (slave_fd < 0) - return posix_error(); + goto posix_error; + + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto posix_error; + #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ @@ -6139,6 +6100,16 @@ posix_openpty(PyObject *self, PyObject *noargs) return Py_BuildValue("(ii)", master_fd, slave_fd); +posix_error: + posix_error(); +#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) +error: +#endif + if (master_fd != -1) + close(master_fd); + if (slave_fd != -1) + close(slave_fd); + return NULL; } #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ @@ -6263,9 +6234,9 @@ posix_getgrouplist(PyObject *self, PyObject *args) #endif #ifdef __APPLE__ - groups = PyMem_Malloc(ngroups * sizeof(int)); + groups = PyMem_New(int, ngroups); #else - groups = PyMem_Malloc(ngroups * sizeof(gid_t)); + groups = PyMem_New(gid_t, ngroups); #endif if (groups == NULL) return PyErr_NoMemory(); @@ -6343,7 +6314,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* groups will fit in existing array */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6369,7 +6340,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* Avoid malloc(0) */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6631,23 +6602,8 @@ posix_kill(PyObject *self, PyObject *args) int sig; if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) return NULL; -#if defined(PYOS_OS2) && !defined(PYCC_GCC) - if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { - APIRET rc; - if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) - return os2_error(rc); - - } else if (sig == XCPT_SIGNAL_KILLPROC) { - APIRET rc; - if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) - return os2_error(rc); - - } else - return NULL; /* Unrecognized Signal Requested */ -#else if (kill(pid, sig) == -1) return posix_error(); -#endif Py_INCREF(Py_None); return Py_None; } @@ -6685,16 +6641,17 @@ static PyObject * win32_kill(PyObject *self, PyObject *args) { PyObject *result; - DWORD pid, sig, err; + pid_t pid; + DWORD sig, err; HANDLE handle; - if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig)) + if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig)) return NULL; /* Console processes which share a common console can be sent CTRL+C or CTRL+BREAK events, provided they handle said events. */ if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { - if (GenerateConsoleCtrlEvent(sig, pid) == 0) { + if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) { err = GetLastError(); PyErr_SetFromWindowsErr(err); } @@ -6704,7 +6661,7 @@ win32_kill(PyObject *self, PyObject *args) /* If the signal is outside of what GenerateConsoleCtrlEvent can use, attempt to open and terminate the process. */ - handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); if (handle == NULL) { err = GetLastError(); return PyErr_SetFromWindowsErr(err); @@ -7110,7 +7067,7 @@ posix_waitpid(PyObject *self, PyObject *args) Py_intptr_t pid; int status, options; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) + if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options)) return NULL; Py_BEGIN_ALLOW_THREADS pid = _cwait(&status, pid, options); @@ -7119,7 +7076,7 @@ posix_waitpid(PyObject *self, PyObject *args) return posix_error(); /* shift the status left a byte so this is more like the POSIX waitpid */ - return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8); + return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8); } #endif /* HAVE_WAITPID || HAVE_CWAIT */ @@ -7170,6 +7127,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "dir_fd", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "readlink"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, path_converter, &path, #ifdef HAVE_READLINKAT @@ -7190,7 +7148,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (length < 0) { - return_value = path_posix_error("readlink", &path); + return_value = path_error(&path); goto exit; } @@ -7226,8 +7184,9 @@ dir_fd may not be implemented on your platform.\n\ /* Grab CreateSymbolicLinkW dynamically from kernel32 */ static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL; static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL; + static int -check_CreateSymbolicLink() +check_CreateSymbolicLink(void) { HINSTANCE hKernel32; /* only recheck */ @@ -7241,55 +7200,57 @@ check_CreateSymbolicLink() return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA); } -void _dirnameW(WCHAR *path) { - /* Remove the last portion of the path */ - +/* Remove the last portion of the path */ +static void +_dirnameW(WCHAR *path) +{ WCHAR *ptr; /* walk the path from the end until a backslash is encountered */ - for(ptr = path + wcslen(path); ptr != path; ptr--) - { - if(*ptr == *L"\\" || *ptr == *L"/") { + for(ptr = path + wcslen(path); ptr != path; ptr--) { + if (*ptr == L'\\' || *ptr == L'/') break; - } } *ptr = 0; } -void _dirnameA(char *path) { - /* Remove the last portion of the path */ - +/* Remove the last portion of the path */ +static void +_dirnameA(char *path) +{ char *ptr; /* walk the path from the end until a backslash is encountered */ - for(ptr = path + strlen(path); ptr != path; ptr--) - { - if(*ptr == '\\' || *ptr == '/') { + for(ptr = path + strlen(path); ptr != path; ptr--) { + if (*ptr == '\\' || *ptr == '/') break; - } } *ptr = 0; } -int _is_absW(WCHAR *path) { - /* Is this path absolute? */ - +/* Is this path absolute? */ +static int +_is_absW(const WCHAR *path) +{ return path[0] == L'\\' || path[0] == L'/' || path[1] == L':'; } -int _is_absA(char *path) { - /* Is this path absolute? */ - +/* Is this path absolute? */ +static int +_is_absA(const char *path) +{ return path[0] == '\\' || path[0] == '/' || path[1] == ':'; } -void _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) { - /* join root and rest with a backslash */ - int root_len; +/* join root and rest with a backslash */ +static void +_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) +{ + size_t root_len; - if(_is_absW(rest)) { + if (_is_absW(rest)) { wcscpy(dest_path, rest); return; } @@ -7298,17 +7259,19 @@ void _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) { wcscpy(dest_path, root); if(root_len) { - dest_path[root_len] = *L"\\"; - root_len += 1; + dest_path[root_len] = L'\\'; + root_len++; } wcscpy(dest_path+root_len, rest); } -void _joinA(char *dest_path, const char *root, const char *rest) { - /* join root and rest with a backslash */ - int root_len; +/* join root and rest with a backslash */ +static void +_joinA(char *dest_path, const char *root, const char *rest) +{ + size_t root_len; - if(_is_absA(rest)) { + if (_is_absA(rest)) { strcpy(dest_path, rest); return; } @@ -7318,14 +7281,15 @@ void _joinA(char *dest_path, const char *root, const char *rest) { strcpy(dest_path, root); if(root_len) { dest_path[root_len] = '\\'; - root_len += 1; + root_len++; } strcpy(dest_path+root_len, rest); } -int _check_dirW(WCHAR *src, WCHAR *dest) +/* Return True if the path at src relative to dest is a directory */ +static int +_check_dirW(WCHAR *src, WCHAR *dest) { - /* Return True if the path at src relative to dest is a directory */ WIN32_FILE_ATTRIBUTE_DATA src_info; WCHAR dest_parent[MAX_PATH]; WCHAR src_resolved[MAX_PATH] = L""; @@ -7341,18 +7305,19 @@ int _check_dirW(WCHAR *src, WCHAR *dest) ); } -int _check_dirA(char *src, char *dest) +/* Return True if the path at src relative to dest is a directory */ +static int +_check_dirA(char *src, char *dest) { - /* Return True if the path at src relative to dest is a directory */ WIN32_FILE_ATTRIBUTE_DATA src_info; char dest_parent[MAX_PATH]; char src_resolved[MAX_PATH] = ""; /* dest_parent = os.path.dirname(dest) */ strcpy(dest_parent, dest); - _dirnameW(dest_parent); + _dirnameA(dest_parent); /* src_resolved = os.path.join(dest_parent, src) */ - _joinW(src_resolved, dest_parent, src); + _joinA(src_resolved, dest_parent, src); return ( GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info) && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY @@ -7378,8 +7343,10 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) #endif memset(&src, 0, sizeof(src)); + src.function_name = "symlink"; src.argument_name = "src"; memset(&dst, 0, sizeof(dst)); + dst.function_name = "symlink"; dst.argument_name = "dst"; #ifdef MS_WINDOWS @@ -7432,7 +7399,7 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (!result) { - return_value = win32_error_object("symlink", src.object); + return_value = path_error2(&src, &dst); goto exit; } @@ -7448,7 +7415,7 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_error("symlink", &dst); + return_value = path_error2(&src, &dst); goto exit; } #endif @@ -7610,31 +7577,7 @@ Return an object containing floating point numbers indicating process\n\ times. The object behaves like a named tuple with these fields:\n\ (utime, stime, cutime, cstime, elapsed_time)"); -#if defined(PYCC_VACPP) && defined(PYOS_OS2) -static long -system_uptime(void) -{ - ULONG value = 0; - - Py_BEGIN_ALLOW_THREADS - DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); - Py_END_ALLOW_THREADS - - return value; -} - -static PyObject * -posix_times(PyObject *self, PyObject *noargs) -{ - /* Currently Only Uptime is Provided -- Others Later */ - return build_times_result( - (double)0 /* t.tms_utime / HZ */, - (double)0 /* t.tms_stime / HZ */, - (double)0 /* t.tms_cutime / HZ */, - (double)0 /* t.tms_cstime / HZ */, - (double)system_uptime() / 1000); -} -#elif defined(MS_WINDOWS) +#if defined(MS_WINDOWS) static PyObject * posix_times(PyObject *self, PyObject *noargs) { @@ -7656,7 +7599,7 @@ posix_times(PyObject *self, PyObject *noargs) (double)0, (double)0); } -#else /* Neither Windows nor OS/2 */ +#else /* Not Windows */ #define NEED_TICKS_PER_SECOND static long ticks_per_second = -1; static PyObject * @@ -7776,6 +7719,10 @@ posix_tcsetpgrp(PyObject *self, PyObject *args) /* Functions acting on file descriptors */ +#ifdef O_CLOEXEC +extern int _Py_open_cloexec_works; +#endif + PyDoc_STRVAR(posix_open__doc__, "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ Open a file for low level IO. Returns a file handle (integer).\n\ @@ -7795,8 +7742,14 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs) int fd; PyObject *return_value = NULL; static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; +#ifdef O_CLOEXEC + int *atomic_flag_works = &_Py_open_cloexec_works; +#elif !defined(MS_WINDOWS) + int *atomic_flag_works = NULL; +#endif memset(&path, 0, sizeof(path)); + path.function_name = "open"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, path_converter, &path, &flags, &mode, @@ -7808,6 +7761,12 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs) )) return NULL; +#ifdef MS_WINDOWS + flags |= O_NOINHERIT; +#elif defined(O_CLOEXEC) + flags |= O_CLOEXEC; +#endif + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS if (path.wide) @@ -7823,15 +7782,16 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (fd == -1) { -#ifdef MS_WINDOWS - /* force use of posix_error here for exact backwards compatibility */ - if (path.wide) - return_value = posix_error(); - else -#endif - return_value = path_error("open", &path); + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object); + goto exit; + } + +#ifndef MS_WINDOWS + if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { + close(fd); goto exit; } +#endif return_value = PyLong_FromLong((long)fd); @@ -7893,13 +7853,14 @@ static PyObject * posix_dup(PyObject *self, PyObject *args) { int fd; + if (!PyArg_ParseTuple(args, "i:dup", &fd)) return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - fd = dup(fd); - if (fd < 0) - return posix_error(); + + fd = _Py_dup(fd); + if (fd == -1) + return NULL; + return PyLong_FromLong((long)fd); } @@ -7909,16 +7870,82 @@ PyDoc_STRVAR(posix_dup2__doc__, Duplicate file descriptor."); static PyObject * -posix_dup2(PyObject *self, PyObject *args) +posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) { - int fd, fd2, res; - if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) + static char *keywords[] = {"fd", "fd2", "inheritable", NULL}; + int fd, fd2; + int inheritable = 1; + int res; +#if defined(HAVE_DUP3) && \ + !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) + /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ + int dup3_works = -1; +#endif + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords, + &fd, &fd2, &inheritable)) return NULL; + if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); + +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS res = dup2(fd, fd2); + Py_END_ALLOW_THREADS if (res < 0) return posix_error(); + + /* Character files like console cannot be make non-inheritable */ + if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { + close(fd2); + return NULL; + } + +#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC) + Py_BEGIN_ALLOW_THREADS + if (!inheritable) + res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2); + else + res = dup2(fd, fd2); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + +#else + +#ifdef HAVE_DUP3 + if (!inheritable && dup3_works != 0) { + Py_BEGIN_ALLOW_THREADS + res = dup3(fd, fd2, O_CLOEXEC); + Py_END_ALLOW_THREADS + if (res < 0) { + if (dup3_works == -1) + dup3_works = (errno != ENOSYS); + if (dup3_works) + return posix_error(); + } + } + + if (inheritable || dup3_works == 0) + { +#endif + Py_BEGIN_ALLOW_THREADS + res = dup2(fd, fd2); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + + if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { + close(fd2); + return NULL; + } +#ifdef HAVE_DUP3 + } +#endif + +#endif + Py_INCREF(Py_None); return Py_None; } @@ -7962,7 +7989,7 @@ static PyObject * posix_lseek(PyObject *self, PyObject *args) { int fd, how; -#if defined(MS_WIN64) || defined(MS_WINDOWS) +#ifdef MS_WINDOWS PY_LONG_LONG pos, res; #else off_t pos, res; @@ -7990,7 +8017,7 @@ posix_lseek(PyObject *self, PyObject *args) if (!_PyVerify_fd(fd)) return posix_error(); Py_BEGIN_ALLOW_THREADS -#if defined(MS_WIN64) || defined(MS_WINDOWS) +#ifdef MS_WINDOWS res = _lseeki64(fd, pos, how); #else res = lseek(fd, pos, how); @@ -8202,7 +8229,7 @@ posix_write(PyObject *self, PyObject *args) } len = pbuf.len; Py_BEGIN_ALLOW_THREADS -#if defined(MS_WIN64) || defined(MS_WINDOWS) +#ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; size = write(fd, pbuf.buf, (int)len); @@ -8218,10 +8245,10 @@ posix_write(PyObject *self, PyObject *args) #ifdef HAVE_SENDFILE PyDoc_STRVAR(posix_sendfile__doc__, -"sendfile(out, in, offset, nbytes) -> byteswritten\n\ -sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\ +"sendfile(out, in, offset, count) -> byteswritten\n\ +sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\ -> byteswritten\n\ -Copy nbytes bytes from file descriptor in to file descriptor out."); +Copy count bytes from file descriptor in to file descriptor out."); static PyObject * posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) @@ -8239,12 +8266,14 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) off_t sbytes; struct sf_hdtr sf; int flags = 0; - sf.headers = NULL; - sf.trailers = NULL; + /* Beware that "in" clashes with Python's own "in" operator keyword */ static char *keywords[] = {"out", "in", "offset", "count", "headers", "trailers", "flags", NULL}; + sf.headers = NULL; + sf.trailers = NULL; + #ifdef __APPLE__ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes, @@ -8257,7 +8286,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) if (headers != NULL) { if (!PySequence_Check(headers)) { PyErr_SetString(PyExc_TypeError, - "sendfile() headers must be a sequence or None"); + "sendfile() headers must be a sequence"); return NULL; } else { Py_ssize_t i = 0; /* Avoid uninitialized warning */ @@ -8274,7 +8303,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) if (trailers != NULL) { if (!PySequence_Check(trailers)) { PyErr_SetString(PyExc_TypeError, - "sendfile() trailers must be a sequence or None"); + "sendfile() trailers must be a sequence"); return NULL; } else { Py_ssize_t i = 0; /* Avoid uninitialized warning */ @@ -8368,16 +8397,12 @@ posix_fstat(PyObject *self, PyObject *args) int res; if (!PyArg_ParseTuple(args, "i:fstat", &fd)) return NULL; -#ifdef __VMS - /* on OpenVMS we must ensure that all bytes are written to the file */ - fsync(fd); -#endif Py_BEGIN_ALLOW_THREADS res = FSTAT(fd, &st); Py_END_ALLOW_THREADS if (res != 0) { #ifdef MS_WINDOWS - return win32_error("fstat", NULL); + return PyErr_SetFromWindowsErr(0); #else return posix_error(); #endif @@ -8410,35 +8435,69 @@ Create a pipe."); static PyObject * posix_pipe(PyObject *self, PyObject *noargs) { -#if defined(PYOS_OS2) - HFILE read, write; - APIRET rc; - - rc = DosCreatePipe( &read, &write, 4096); - if (rc != NO_ERROR) - return os2_error(rc); - - return Py_BuildValue("(ii)", read, write); -#else -#if !defined(MS_WINDOWS) int fds[2]; - int res; - res = pipe(fds); - if (res != 0) - return posix_error(); - return Py_BuildValue("(ii)", fds[0], fds[1]); -#else /* MS_WINDOWS */ +#ifdef MS_WINDOWS HANDLE read, write; - int read_fd, write_fd; + SECURITY_ATTRIBUTES attr; BOOL ok; - ok = CreatePipe(&read, &write, NULL, 0); +#else + int res; +#endif + +#ifdef MS_WINDOWS + attr.nLength = sizeof(attr); + attr.lpSecurityDescriptor = NULL; + attr.bInheritHandle = FALSE; + + Py_BEGIN_ALLOW_THREADS + ok = CreatePipe(&read, &write, &attr, 0); + if (ok) { + fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY); + fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY); + if (fds[0] == -1 || fds[1] == -1) { + CloseHandle(read); + CloseHandle(write); + ok = 0; + } + } + Py_END_ALLOW_THREADS + if (!ok) - return win32_error("CreatePipe", NULL); - read_fd = _open_osfhandle((Py_intptr_t)read, 0); - write_fd = _open_osfhandle((Py_intptr_t)write, 1); - return Py_BuildValue("(ii)", read_fd, write_fd); -#endif /* MS_WINDOWS */ + return PyErr_SetFromWindowsErr(0); +#else + +#ifdef HAVE_PIPE2 + Py_BEGIN_ALLOW_THREADS + res = pipe2(fds, O_CLOEXEC); + Py_END_ALLOW_THREADS + + if (res != 0 && errno == ENOSYS) + { #endif + Py_BEGIN_ALLOW_THREADS + res = pipe(fds); + Py_END_ALLOW_THREADS + + if (res == 0) { + if (_Py_set_inheritable(fds[0], 0, NULL) < 0) { + close(fds[0]); + close(fds[1]); + return NULL; + } + if (_Py_set_inheritable(fds[1], 0, NULL) < 0) { + close(fds[0]); + close(fds[1]); + return NULL; + } + } +#ifdef HAVE_PIPE2 + } +#endif + + if (res != 0) + return PyErr_SetFromErrno(PyExc_OSError); +#endif /* !MS_WINDOWS */ + return Py_BuildValue("(ii)", fds[0], fds[1]); } #endif /* HAVE_PIPE */ @@ -8597,9 +8656,9 @@ exit: #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) PyDoc_STRVAR(posix_mknod__doc__, -"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\ +"mknod(path, 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\ +named 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. For S_IFCHR and S_IFBLK,\n\ device defines the newly created device special file (probably using\n\ @@ -8616,16 +8675,16 @@ posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs) { path_t path; int mode = 0666; - 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&|ii$O&:mknod", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords, path_converter, &path, - &mode, &device, + &mode, _Py_Dev_Converter, &device, #ifdef HAVE_MKNODAT dir_fd_converter, &dir_fd #else @@ -8665,8 +8724,8 @@ Extracts a device major number from a raw device number."); static PyObject * posix_major(PyObject *self, PyObject *args) { - int device; - if (!PyArg_ParseTuple(args, "i:major", &device)) + dev_t device; + if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device)) return NULL; return PyLong_FromLong((long)major(device)); } @@ -8678,8 +8737,8 @@ Extracts a device minor number from a raw device number."); static PyObject * posix_minor(PyObject *self, PyObject *args) { - int device; - if (!PyArg_ParseTuple(args, "i:minor", &device)) + dev_t device; + if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device)) return NULL; return PyLong_FromLong((long)minor(device)); } @@ -8694,7 +8753,7 @@ posix_makedev(PyObject *self, PyObject *args) int major, minor; if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) return NULL; - return PyLong_FromLong((long)makedev(major, minor)); + return _PyLong_FromDev(makedev(major, minor)); } #endif /* device macros */ @@ -8741,6 +8800,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "length", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "truncate"; #ifdef HAVE_FTRUNCATE path.allow_fd = 1; #endif @@ -8758,7 +8818,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) res = truncate(path.narrow, length); Py_END_ALLOW_THREADS if (res < 0) - result = path_posix_error("truncate", &path); + result = path_error(&path); else { Py_INCREF(Py_None); result = Py_None; @@ -8768,7 +8828,15 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) } #endif -#ifdef HAVE_POSIX_FALLOCATE +/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() + and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is + defined, which is the case in Python on AIX. AIX bug report: + http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ +#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) +# define POSIX_FADVISE_AIX_BUG +#endif + +#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) PyDoc_STRVAR(posix_posix_fallocate__doc__, "posix_fallocate(fd, offset, len)\n\n\ Ensures that enough disk space is allocated for the file specified by fd\n\ @@ -8795,7 +8863,7 @@ posix_posix_fallocate(PyObject *self, PyObject *args) } #endif -#ifdef HAVE_POSIX_FADVISE +#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) PyDoc_STRVAR(posix_posix_fadvise__doc__, "posix_fadvise(fd, offset, len, advice)\n\n\ Announces an intention to access data in a specific pattern thus allowing\n\ @@ -9181,6 +9249,10 @@ _pystatvfs_fromstructstatvfs(struct statvfs st) { PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); #endif + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } return v; } @@ -9230,6 +9302,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) struct statvfs st; memset(&path, 0, sizeof(path)); + path.function_name = "statvfs"; #ifdef HAVE_FSTATVFS path.allow_fd = 1; #endif @@ -9256,7 +9329,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS if (result) { - return_value = path_posix_error("statvfs", &path); + return_value = path_error(&path); goto exit; } @@ -9493,6 +9566,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "name", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "pathconf"; #ifdef HAVE_FPATHCONF path.allow_fd = 1; #endif @@ -9513,7 +9587,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) /* could be a path or name problem */ posix_error(); else - result = path_posix_error("pathconf", &path); + result = path_error(&path); } else result = PyLong_FromLong(limit); @@ -9695,7 +9769,7 @@ posix_confstr(PyObject *self, PyObject *args) PyObject *result = NULL; int name; char buffer[255]; - int len; + size_t len; if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) return NULL; @@ -9712,7 +9786,7 @@ posix_confstr(PyObject *self, PyObject *args) } } - if ((unsigned int)len >= sizeof(buffer)) { + if (len >= sizeof(buffer)) { char *buf = PyMem_Malloc(len); if (buf == NULL) return PyErr_NoMemory(); @@ -10242,7 +10316,7 @@ posix_sysconf(PyObject *self, PyObject *args) int name; if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { - int value; + long value; errno = 0; value = sysconf(name); @@ -10257,7 +10331,7 @@ posix_sysconf(PyObject *self, PyObject *args) /* This code is used to ensure that the tables of configuration value names - * are in sorted order as required by conv_confname(), and also to build the + * are in sorted order as required by conv_confname(), and also to build * the exported dictionaries that are used to publish information about the * names available on the host platform. * @@ -10572,6 +10646,8 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) memset(&path, 0, sizeof(path)); memset(&attribute, 0, sizeof(attribute)); + path.function_name = "getxattr"; + attribute.function_name = "getxattr"; path.allow_fd = 1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, path_converter, &path, @@ -10588,7 +10664,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { - path_error("getxattr", &path); + path_error(&path); goto exit; } buffer = PyBytes_FromStringAndSize(NULL, buffer_size); @@ -10610,7 +10686,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) buffer = NULL; if (errno == ERANGE) continue; - path_error("getxattr", &path); + path_error(&path); goto exit; } @@ -10649,6 +10725,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) "flags", "follow_symlinks", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "setxattr"; path.allow_fd = 1; memset(&attribute, 0, sizeof(attribute)); memset(&value, 0, sizeof(value)); @@ -10676,7 +10753,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS; if (result) { - return_value = path_error("setxattr", &path); + return_value = path_error(&path); goto exit; } @@ -10710,7 +10787,9 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "removexattr"; memset(&attribute, 0, sizeof(attribute)); + attribute.function_name = "removexattr"; path.allow_fd = 1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", keywords, @@ -10732,7 +10811,7 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) Py_END_ALLOW_THREADS; if (result) { - return_value = path_error("removexattr", &path); + return_value = path_error(&path); goto exit; } @@ -10768,6 +10847,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) static char *keywords[] = {"path", "follow_symlinks", NULL}; memset(&path, 0, sizeof(path)); + path.function_name = "listxattr"; path.allow_fd = 1; path.fd = -1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, @@ -10786,7 +10866,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { /* ERANGE */ - path_error("listxattr", &path); + path_error(&path); break; } buffer = PyMem_MALLOC(buffer_size); @@ -10810,7 +10890,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) buffer = NULL; continue; } - path_error("listxattr", &path); + path_error(&path); break; } @@ -10988,14 +11068,154 @@ get_terminal_size(PyObject *self, PyObject *args) } #endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ +PyDoc_STRVAR(posix_cpu_count__doc__, +"cpu_count() -> integer\n\n\ +Return the number of CPUs in the system, or None if this value cannot be\n\ +established."); + +static PyObject * +posix_cpu_count(PyObject *self) +{ + int ncpu = 0; +#ifdef MS_WINDOWS + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + ncpu = sysinfo.dwNumberOfProcessors; +#elif defined(__hpux) + ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); +#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) + int mib[2]; + size_t len = sizeof(ncpu); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) + ncpu = 0; +#endif + if (ncpu >= 1) + return PyLong_FromLong(ncpu); + else + Py_RETURN_NONE; +} + +PyDoc_STRVAR(get_inheritable__doc__, + "get_inheritable(fd) -> bool\n" \ + "\n" \ + "Get the close-on-exe flag of the specified file descriptor."); + +static PyObject* +posix_get_inheritable(PyObject *self, PyObject *args) +{ + int fd; + int inheritable; + + if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd)) + return NULL; + + if (!_PyVerify_fd(fd)) + return posix_error(); + + inheritable = _Py_get_inheritable(fd); + if (inheritable < 0) + return NULL; + return PyBool_FromLong(inheritable); +} + +PyDoc_STRVAR(set_inheritable__doc__, + "set_inheritable(fd, inheritable)\n" \ + "\n" \ + "Set the inheritable flag of the specified file descriptor."); + +static PyObject* +posix_set_inheritable(PyObject *self, PyObject *args) +{ + int fd, inheritable; + + if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable)) + return NULL; + + if (!_PyVerify_fd(fd)) + return posix_error(); + + if (_Py_set_inheritable(fd, inheritable, NULL) < 0) + return NULL; + Py_RETURN_NONE; +} + + +#ifdef MS_WINDOWS +PyDoc_STRVAR(get_handle_inheritable__doc__, + "get_handle_inheritable(fd) -> bool\n" \ + "\n" \ + "Get the close-on-exe flag of the specified file descriptor."); + +static PyObject* +posix_get_handle_inheritable(PyObject *self, PyObject *args) +{ + Py_intptr_t handle; + DWORD flags; + + if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) + return NULL; + + if (!GetHandleInformation((HANDLE)handle, &flags)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + + return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT); +} + +PyDoc_STRVAR(set_handle_inheritable__doc__, + "set_handle_inheritable(fd, inheritable)\n" \ + "\n" \ + "Set the inheritable flag of the specified handle."); + +static PyObject* +posix_set_handle_inheritable(PyObject *self, PyObject *args) +{ + int inheritable = 1; + Py_intptr_t handle; + DWORD flags; + + if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable", + &handle, &inheritable)) + return NULL; + + if (inheritable) + flags = HANDLE_FLAG_INHERIT; + else + flags = 0; + if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + Py_RETURN_NONE; +} +#endif /* MS_WINDOWS */ + + +/*[clinic input] +dump buffer +[clinic start generated code]*/ + +#ifndef OS_TTYNAME_METHODDEF + #define OS_TTYNAME_METHODDEF +#endif /* !defined(OS_TTYNAME_METHODDEF) */ +/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/ + static PyMethodDef posix_methods[] = { - {"access", (PyCFunction)posix_access, - METH_VARARGS | METH_KEYWORDS, - posix_access__doc__}, -#ifdef HAVE_TTYNAME - {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, -#endif + + OS_STAT_METHODDEF + OS_ACCESS_METHODDEF + OS_TTYNAME_METHODDEF + {"chdir", (PyCFunction)posix_chdir, METH_VARARGS | METH_KEYWORDS, posix_chdir__doc__}, @@ -11033,12 +11253,10 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_CTERMID {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, #endif -#ifdef HAVE_GETCWD {"getcwd", (PyCFunction)posix_getcwd_unicode, METH_NOARGS, posix_getcwd__doc__}, {"getcwdb", (PyCFunction)posix_getcwd_bytes, METH_NOARGS, posix_getcwdb__doc__}, -#endif #if defined(HAVE_LINK) || defined(MS_WINDOWS) {"link", (PyCFunction)posix_link, METH_VARARGS | METH_KEYWORDS, @@ -11081,9 +11299,6 @@ static PyMethodDef posix_methods[] = { {"rmdir", (PyCFunction)posix_rmdir, METH_VARARGS | METH_KEYWORDS, posix_rmdir__doc__}, - {"stat", (PyCFunction)posix_stat, - METH_VARARGS | METH_KEYWORDS, - posix_stat__doc__}, {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, #if defined(HAVE_SYMLINK) {"symlink", (PyCFunction)posix_symlink, @@ -11118,10 +11333,6 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_SPAWNV {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, -#if defined(PYOS_OS2) - {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__}, - {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__}, -#endif /* PYOS_OS2 */ #endif /* HAVE_SPAWNV */ #ifdef HAVE_FORK1 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, @@ -11269,7 +11480,8 @@ static PyMethodDef posix_methods[] = { {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, - {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, + {"dup2", (PyCFunction)posix_dup2, + METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__}, #ifdef HAVE_LOCKF {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__}, #endif @@ -11323,10 +11535,10 @@ static PyMethodDef posix_methods[] = { METH_VARARGS | METH_KEYWORDS, posix_truncate__doc__}, #endif -#ifdef HAVE_POSIX_FALLOCATE +#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__}, #endif -#ifdef HAVE_POSIX_FADVISE +#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__}, #endif #ifdef HAVE_PUTENV @@ -11400,9 +11612,9 @@ static PyMethodDef posix_methods[] = { #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, - {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__}, + {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, @@ -11438,69 +11650,20 @@ static PyMethodDef posix_methods[] = { #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, #endif + {"cpu_count", (PyCFunction)posix_cpu_count, + METH_NOARGS, posix_cpu_count__doc__}, + {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__}, + {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__}, +#ifdef MS_WINDOWS + {"get_handle_inheritable", posix_get_handle_inheritable, + METH_VARARGS, get_handle_inheritable__doc__}, + {"set_handle_inheritable", posix_set_handle_inheritable, + METH_VARARGS, set_handle_inheritable__doc__}, +#endif {NULL, NULL} /* Sentinel */ }; -static int -ins(PyObject *module, char *symbol, long value) -{ - return PyModule_AddIntConstant(module, symbol, value); -} - -#if defined(PYOS_OS2) -/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ -static int insertvalues(PyObject *module) -{ - APIRET rc; - ULONG values[QSV_MAX+1]; - PyObject *v; - char *ver, tmp[50]; - - Py_BEGIN_ALLOW_THREADS - rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX); - Py_END_ALLOW_THREADS - - if (rc != NO_ERROR) { - os2_error(rc); - return -1; - } - - if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; - if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1; - if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; - if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; - if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; - if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1; - if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1; - - switch (values[QSV_VERSION_MINOR]) { - case 0: ver = "2.00"; break; - case 10: ver = "2.10"; break; - case 11: ver = "2.11"; break; - case 30: ver = "3.00"; break; - case 40: ver = "4.00"; break; - case 50: ver = "5.00"; break; - default: - PyOS_snprintf(tmp, sizeof(tmp), - "%d-%d", values[QSV_VERSION_MAJOR], - values[QSV_VERSION_MINOR]); - ver = &tmp[0]; - } - - /* Add Indicator of the Version of the Operating System */ - if (PyModule_AddStringConstant(module, "version", tmp) < 0) - return -1; - - /* Add Indicator of Which Drive was Used to Boot the System */ - tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; - tmp[1] = ':'; - tmp[2] = '\0'; - - return PyModule_AddStringConstant(module, "bootdrive", tmp); -} -#endif - #if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) static int enable_symlink() @@ -11531,401 +11694,410 @@ enable_symlink() #endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ static int -all_ins(PyObject *d) +all_ins(PyObject *m) { #ifdef F_OK - if (ins(d, "F_OK", (long)F_OK)) return -1; + if (PyModule_AddIntMacro(m, F_OK)) return -1; #endif #ifdef R_OK - if (ins(d, "R_OK", (long)R_OK)) return -1; + if (PyModule_AddIntMacro(m, R_OK)) return -1; #endif #ifdef W_OK - if (ins(d, "W_OK", (long)W_OK)) return -1; + if (PyModule_AddIntMacro(m, W_OK)) return -1; #endif #ifdef X_OK - if (ins(d, "X_OK", (long)X_OK)) return -1; + if (PyModule_AddIntMacro(m, X_OK)) return -1; #endif #ifdef NGROUPS_MAX - if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; + if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1; #endif #ifdef TMP_MAX - if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; + if (PyModule_AddIntMacro(m, TMP_MAX)) return -1; #endif #ifdef WCONTINUED - if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1; + if (PyModule_AddIntMacro(m, WCONTINUED)) return -1; #endif #ifdef WNOHANG - if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; + if (PyModule_AddIntMacro(m, WNOHANG)) return -1; #endif #ifdef WUNTRACED - if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1; + if (PyModule_AddIntMacro(m, WUNTRACED)) return -1; #endif #ifdef O_RDONLY - if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; + if (PyModule_AddIntMacro(m, O_RDONLY)) return -1; #endif #ifdef O_WRONLY - if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; + if (PyModule_AddIntMacro(m, O_WRONLY)) return -1; #endif #ifdef O_RDWR - if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; + if (PyModule_AddIntMacro(m, O_RDWR)) return -1; #endif #ifdef O_NDELAY - if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; + if (PyModule_AddIntMacro(m, O_NDELAY)) return -1; #endif #ifdef O_NONBLOCK - if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; + if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1; #endif #ifdef O_APPEND - if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; + if (PyModule_AddIntMacro(m, O_APPEND)) return -1; #endif #ifdef O_DSYNC - if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; + if (PyModule_AddIntMacro(m, O_DSYNC)) return -1; #endif #ifdef O_RSYNC - if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; + if (PyModule_AddIntMacro(m, O_RSYNC)) return -1; #endif #ifdef O_SYNC - if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; + if (PyModule_AddIntMacro(m, O_SYNC)) return -1; #endif #ifdef O_NOCTTY - if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; + if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1; #endif #ifdef O_CREAT - if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; + if (PyModule_AddIntMacro(m, O_CREAT)) return -1; #endif #ifdef O_EXCL - if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; + if (PyModule_AddIntMacro(m, O_EXCL)) return -1; #endif #ifdef O_TRUNC - if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; + if (PyModule_AddIntMacro(m, O_TRUNC)) return -1; #endif #ifdef O_BINARY - if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; + if (PyModule_AddIntMacro(m, O_BINARY)) return -1; #endif #ifdef O_TEXT - if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; + if (PyModule_AddIntMacro(m, O_TEXT)) return -1; #endif #ifdef O_XATTR - if (ins(d, "O_XATTR", (long)O_XATTR)) return -1; + if (PyModule_AddIntMacro(m, O_XATTR)) return -1; #endif #ifdef O_LARGEFILE - if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1; + if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; #endif #ifdef O_SHLOCK - if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1; + if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; #endif #ifdef O_EXLOCK - if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1; + if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; #endif #ifdef O_EXEC - if (ins(d, "O_EXEC", (long)O_EXEC)) return -1; + if (PyModule_AddIntMacro(m, O_EXEC)) return -1; #endif #ifdef O_SEARCH - if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1; + if (PyModule_AddIntMacro(m, O_SEARCH)) return -1; +#endif +#ifdef O_PATH + if (PyModule_AddIntMacro(m, O_PATH)) return -1; #endif #ifdef O_TTY_INIT - if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1; + if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1; +#endif +#ifdef O_TMPFILE + if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1; #endif #ifdef PRIO_PROCESS - if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1; + if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1; #endif #ifdef PRIO_PGRP - if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1; + if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1; #endif #ifdef PRIO_USER - if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1; + if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; #endif #ifdef O_CLOEXEC - if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1; + if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; #endif #ifdef O_ACCMODE - if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1; + if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; #endif #ifdef SEEK_HOLE - if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1; + if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; #endif #ifdef SEEK_DATA - if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1; + if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1; #endif /* MS Windows */ #ifdef O_NOINHERIT /* Don't inherit in child processes. */ - if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1; + if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1; #endif #ifdef _O_SHORT_LIVED /* Optimize for short life (keep in memory). */ /* MS forgot to define this one with a non-underscore form too. */ - if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1; + if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1; #endif #ifdef O_TEMPORARY /* Automatically delete when last handle is closed. */ - if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1; + if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1; #endif #ifdef O_RANDOM /* Optimize for random access. */ - if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1; + if (PyModule_AddIntMacro(m, O_RANDOM)) return -1; #endif #ifdef O_SEQUENTIAL /* Optimize for sequential access. */ - if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1; + if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1; #endif /* GNU extensions. */ #ifdef O_ASYNC /* Send a SIGIO signal whenever input or output becomes available on file descriptor */ - if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1; + if (PyModule_AddIntMacro(m, O_ASYNC)) return -1; #endif #ifdef O_DIRECT /* Direct disk access. */ - if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1; + if (PyModule_AddIntMacro(m, O_DIRECT)) return -1; #endif #ifdef O_DIRECTORY /* Must be a directory. */ - if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1; + if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1; #endif #ifdef O_NOFOLLOW /* Do not follow links. */ - if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; + if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; #endif #ifdef O_NOLINKS /* Fails if link count of the named file is greater than 1 */ - if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1; + if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; #endif #ifdef O_NOATIME /* Do not update the access time. */ - if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1; + if (PyModule_AddIntMacro(m, O_NOATIME)) return -1; #endif /* These come from sysexits.h */ #ifdef EX_OK - if (ins(d, "EX_OK", (long)EX_OK)) return -1; + if (PyModule_AddIntMacro(m, EX_OK)) return -1; #endif /* EX_OK */ #ifdef EX_USAGE - if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; + if (PyModule_AddIntMacro(m, EX_USAGE)) return -1; #endif /* EX_USAGE */ #ifdef EX_DATAERR - if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; + if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1; #endif /* EX_DATAERR */ #ifdef EX_NOINPUT - if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; + if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1; #endif /* EX_NOINPUT */ #ifdef EX_NOUSER - if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; + if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1; #endif /* EX_NOUSER */ #ifdef EX_NOHOST - if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; + if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1; #endif /* EX_NOHOST */ #ifdef EX_UNAVAILABLE - if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; + if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1; #endif /* EX_UNAVAILABLE */ #ifdef EX_SOFTWARE - if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; + if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1; #endif /* EX_SOFTWARE */ #ifdef EX_OSERR - if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; + if (PyModule_AddIntMacro(m, EX_OSERR)) return -1; #endif /* EX_OSERR */ #ifdef EX_OSFILE - if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; + if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1; #endif /* EX_OSFILE */ #ifdef EX_CANTCREAT - if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; + if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1; #endif /* EX_CANTCREAT */ #ifdef EX_IOERR - if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; + if (PyModule_AddIntMacro(m, EX_IOERR)) return -1; #endif /* EX_IOERR */ #ifdef EX_TEMPFAIL - if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; + if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1; #endif /* EX_TEMPFAIL */ #ifdef EX_PROTOCOL - if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; + if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1; #endif /* EX_PROTOCOL */ #ifdef EX_NOPERM - if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; + if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1; #endif /* EX_NOPERM */ #ifdef EX_CONFIG - if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; + if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1; #endif /* EX_CONFIG */ #ifdef EX_NOTFOUND - if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; + if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1; #endif /* EX_NOTFOUND */ /* statvfs */ #ifdef ST_RDONLY - if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1; + if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1; #endif /* ST_RDONLY */ #ifdef ST_NOSUID - if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1; + if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; #endif /* ST_NOSUID */ + /* GNU extensions */ +#ifdef ST_NODEV + if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; +#endif /* ST_NODEV */ +#ifdef ST_NOEXEC + if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; +#endif /* ST_NOEXEC */ +#ifdef ST_SYNCHRONOUS + if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; +#endif /* ST_SYNCHRONOUS */ +#ifdef ST_MANDLOCK + if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; +#endif /* ST_MANDLOCK */ +#ifdef ST_WRITE + if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; +#endif /* ST_WRITE */ +#ifdef ST_APPEND + if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; +#endif /* ST_APPEND */ +#ifdef ST_NOATIME + if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; +#endif /* ST_NOATIME */ +#ifdef ST_NODIRATIME + if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; +#endif /* ST_NODIRATIME */ +#ifdef ST_RELATIME + if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; +#endif /* ST_RELATIME */ + /* FreeBSD sendfile() constants */ #ifdef SF_NODISKIO - if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1; + if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; #endif #ifdef SF_MNOWAIT - if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1; + if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; #endif #ifdef SF_SYNC - if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1; + if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; #endif /* constants for posix_fadvise */ #ifdef POSIX_FADV_NORMAL - if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; #endif #ifdef POSIX_FADV_SEQUENTIAL - if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1; #endif #ifdef POSIX_FADV_RANDOM - if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1; #endif #ifdef POSIX_FADV_NOREUSE - if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1; #endif #ifdef POSIX_FADV_WILLNEED - if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1; #endif #ifdef POSIX_FADV_DONTNEED - if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1; + if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1; #endif /* constants for waitid */ #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID) - if (ins(d, "P_PID", (long)P_PID)) return -1; - if (ins(d, "P_PGID", (long)P_PGID)) return -1; - if (ins(d, "P_ALL", (long)P_ALL)) return -1; + if (PyModule_AddIntMacro(m, P_PID)) return -1; + if (PyModule_AddIntMacro(m, P_PGID)) return -1; + if (PyModule_AddIntMacro(m, P_ALL)) return -1; #endif #ifdef WEXITED - if (ins(d, "WEXITED", (long)WEXITED)) return -1; + if (PyModule_AddIntMacro(m, WEXITED)) return -1; #endif #ifdef WNOWAIT - if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1; + if (PyModule_AddIntMacro(m, WNOWAIT)) return -1; #endif #ifdef WSTOPPED - if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1; + if (PyModule_AddIntMacro(m, WSTOPPED)) return -1; #endif #ifdef CLD_EXITED - if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1; + if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1; #endif #ifdef CLD_DUMPED - if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1; + if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; #endif #ifdef CLD_TRAPPED - if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1; + if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1; #endif #ifdef CLD_CONTINUED - if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1; + if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1; #endif /* constants for lockf */ #ifdef F_LOCK - if (ins(d, "F_LOCK", (long)F_LOCK)) return -1; + if (PyModule_AddIntMacro(m, F_LOCK)) return -1; #endif #ifdef F_TLOCK - if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1; + if (PyModule_AddIntMacro(m, F_TLOCK)) return -1; #endif #ifdef F_ULOCK - if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1; + if (PyModule_AddIntMacro(m, F_ULOCK)) return -1; #endif #ifdef F_TEST - if (ins(d, "F_TEST", (long)F_TEST)) return -1; + if (PyModule_AddIntMacro(m, F_TEST)) return -1; #endif #ifdef HAVE_SPAWNV -#if defined(PYOS_OS2) && defined(PYCC_GCC) - if (ins(d, "P_WAIT", (long)P_WAIT)) return -1; - if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1; - if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1; - if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1; - if (ins(d, "P_SESSION", (long)P_SESSION)) return -1; - if (ins(d, "P_DETACH", (long)P_DETACH)) return -1; - if (ins(d, "P_PM", (long)P_PM)) return -1; - if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1; - if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1; - if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1; - if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1; - if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1; - if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1; - if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1; - if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1; - if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1; - if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1; - if (ins(d, "P_TILDE", (long)P_TILDE)) return -1; - if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1; - if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1; -#else - if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; - if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; - if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; - if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; - if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; -#endif + if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; + if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; + if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; + if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; + if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; #endif #ifdef HAVE_SCHED_H - if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1; - if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1; - if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1; + if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1; + if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1; + if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; #ifdef SCHED_SPORADIC - if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC)) return -1; + if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1; #endif #ifdef SCHED_BATCH - if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1; + if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; #endif #ifdef SCHED_IDLE - if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1; + if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1; #endif #ifdef SCHED_RESET_ON_FORK - if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1; + if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1; #endif #ifdef SCHED_SYS - if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1; + if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1; #endif #ifdef SCHED_IA - if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1; + if (PyModule_AddIntMacro(m, SCHED_IA)) return -1; #endif #ifdef SCHED_FSS - if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1; + if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1; #endif #ifdef SCHED_FX - if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1; + if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; #endif #endif #ifdef USE_XATTRS - if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1; - if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1; - if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1; + if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1; + if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1; + if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; #endif #ifdef RTLD_LAZY - if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1; + if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; #endif #ifdef RTLD_NOW - if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1; + if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; #endif #ifdef RTLD_GLOBAL - if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1; + if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; #endif #ifdef RTLD_LOCAL - if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1; + if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; #endif #ifdef RTLD_NODELETE - if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1; + if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; #endif #ifdef RTLD_NOLOAD - if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1; + if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; #endif #ifdef RTLD_DEEPBIND - if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1; + if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; #endif -#if defined(PYOS_OS2) - if (insertvalues(d)) return -1; -#endif return 0; } @@ -11934,10 +12106,6 @@ all_ins(PyObject *d) #define INITFUNC PyInit_nt #define MODNAME "nt" -#elif defined(PYOS_OS2) -#define INITFUNC PyInit_os2 -#define MODNAME "os2" - #else #define INITFUNC PyInit_posix #define MODNAME "posix" @@ -12125,19 +12293,23 @@ INITFUNC(void) if (!initialized) { #if defined(HAVE_WAITID) && !defined(__APPLE__) waitid_result_desc.name = MODNAME ".waitid_result"; - PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc); + if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0) + return NULL; #endif - stat_result_desc.name = MODNAME ".stat_result"; + stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; - PyStructSequence_InitType(&StatResultType, &stat_result_desc); + if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0) + return NULL; structseq_new = StatResultType.tp_new; StatResultType.tp_new = statresult_new; - statvfs_result_desc.name = MODNAME ".statvfs_result"; - PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc); + statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ + if (PyStructSequence_InitType2(&StatVFSResultType, + &statvfs_result_desc) < 0) + return NULL; #ifdef NEED_TICKS_PER_SECOND # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) ticks_per_second = sysconf(_SC_CLK_TCK); @@ -12150,12 +12322,15 @@ INITFUNC(void) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) sched_param_desc.name = MODNAME ".sched_param"; - PyStructSequence_InitType(&SchedParamType, &sched_param_desc); + if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) + return NULL; SchedParamType.tp_new = sched_param_new; #endif /* initialize TerminalSize_info */ - PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc); + if (PyStructSequence_InitType2(&TerminalSizeType, + &TerminalSize_desc) < 0) + return NULL; } #if defined(HAVE_WAITID) && !defined(__APPLE__) Py_INCREF((PyObject*) &WaitidResultType); @@ -12173,11 +12348,13 @@ INITFUNC(void) #endif times_result_desc.name = MODNAME ".times_result"; - PyStructSequence_InitType(&TimesResultType, ×_result_desc); + if (PyStructSequence_InitType2(&TimesResultType, ×_result_desc) < 0) + return NULL; PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType); uname_result_desc.name = MODNAME ".uname_result"; - PyStructSequence_InitType(&UnameResultType, &uname_result_desc); + if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0) + return NULL; PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType); #ifdef __APPLE__ @@ -12255,7 +12432,6 @@ INITFUNC(void) initialized = 1; return m; - } #ifdef __cplusplus |