Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (révision 70584) +++ Modules/posixmodule.c (copie de travail) @@ -15,7 +15,7 @@ #ifdef __APPLE__ /* - * Step 1 of support for weak-linking a number of symbols existing on + * Step 1 of support for weak-linking a number of symbols existing on * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block * at the end of this file for more information. */ @@ -356,7 +356,7 @@ * as a fd and should merely raise a python exception on error. * The Microsoft CRT doesn't provide an official way to check for the * validity of a file descriptor, but we can emulate its internal behaviour - * by using the exported __pinfo data member and knowledge of the + * by using the exported __pinfo data member and knowledge of the * internal structures involved. * The structures below must be updated for each version of visual studio * according to the file internal.h in the CRT source, until MS comes @@ -752,8 +752,8 @@ #ifdef Py_WIN_WIDE_FILENAMES static PyObject* -win32_1str(PyObject* args, char* func, - char* format, BOOL (__stdcall *funcA)(LPCSTR), +win32_1str(PyObject* args, char* func, + char* format, BOOL (__stdcall *funcA)(LPCSTR), char* wformat, BOOL (__stdcall *funcW)(LPWSTR)) { PyObject *uni; @@ -857,7 +857,7 @@ UTC and local time Therefore, we implement our own stat, based on the Win32 API directly. */ -#define HAVE_STAT_NSEC 1 +#define HAVE_STAT_NSEC 1 struct win32_stat{ int st_dev; @@ -882,7 +882,7 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out) { /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ - /* Cannot simply cast and dereference in_ptr, + /* Cannot simply cast and dereference in_ptr, since it might not be aligned properly */ __int64 in; memcpy(&in, in_ptr, sizeof(in)); @@ -986,7 +986,7 @@ } static BOOL WINAPI -Py_GetFileAttributesExA(LPCSTR pszFile, +Py_GetFileAttributesExA(LPCSTR pszFile, GET_FILEEX_INFO_LEVELS level, LPVOID pv) { @@ -1016,7 +1016,7 @@ } static BOOL WINAPI -Py_GetFileAttributesExW(LPCWSTR pszFile, +Py_GetFileAttributesExW(LPCWSTR pszFile, GET_FILEEX_INFO_LEVELS level, LPVOID pv) { @@ -1045,7 +1045,7 @@ return attributes_from_dir_w(pszFile, pfad); } -static int +static int win32_stat(const char* path, struct win32_stat *result) { WIN32_FILE_ATTRIBUTE_DATA info; @@ -1083,7 +1083,7 @@ return code; } -static int +static int win32_wstat(const wchar_t* path, struct win32_stat *result) { int code; @@ -1127,9 +1127,9 @@ BY_HANDLE_FILE_INFORMATION info; HANDLE h; int type; - + h = (HANDLE)_get_osfhandle(file_number); - + /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ errno = 0; @@ -1394,8 +1394,10 @@ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink)); - PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid)); + PyStructSequence_SET_ITEM(v, 4, + PyLong_FromUnsignedLong((unsigned long)st->st_uid)); + PyStructSequence_SET_ITEM(v, 5, + PyLong_FromUnsignedLong((unsigned long)st->st_gid)); #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); @@ -1588,7 +1590,7 @@ #else result = posix_error_with_filename(pathfree); #endif - } + } else result = _pystat_fromstructstat(&st); @@ -1611,7 +1613,7 @@ { char *path; int mode; - + #ifdef Py_WIN_WIDE_FILENAMES DWORD attr; if (unicode_file_names()) { @@ -1642,12 +1644,12 @@ /* Access is possible if either write access wasn't requested, or the file isn't read-only, or if it's a directory, as there are no read-only directories on Windows. */ - return PyBool_FromLong(!(mode & 2) + return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY)); #else int res; - if (!PyArg_ParseTuple(args, "eti:access", + if (!PyArg_ParseTuple(args, "eti:access", Py_FileSystemDefaultEncoding, &path, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -1971,7 +1973,72 @@ } #endif /* HAVE_FDATASYNC */ +static int +parse_uid(PyObject *elem, uid_t *uid) +{ + if (PyInt_Check(elem)) { + long x = PyInt_AsLong(elem); + *uid = x; + /* read back the value to see if it fitted in uid_t */ + if (*uid != x) { + PyErr_SetString(PyExc_TypeError, "user id too big"); + return 0; + } + return 1; + } + if (PyLong_Check(elem)) { + unsigned long x = PyLong_AsUnsignedLong(elem); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "user id too big"); + return 0; + } + *uid = x; + /* read back the value to see if it fitted in uid_t */ + if (*uid != x) { + PyErr_SetString(PyExc_TypeError, + "user id too big"); + return 0; + } + return 1; + } + PyErr_SetString(PyExc_TypeError, "user id must be integer"); + return 0; +} +static int +parse_gid(PyObject *elem, gid_t *gid) +{ + if (PyInt_Check(elem)) { + long x = PyInt_AsLong(elem); + *gid = x; + /* read back the value to see if it fitted in gid_t */ + if (*gid != x) { + PyErr_SetString(PyExc_TypeError, "group id too big"); + return 0; + } + return 1; + } + if (PyLong_Check(elem)) { + unsigned long x = PyLong_AsUnsignedLong(elem); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "group id too big"); + return 0; + } + *gid = x; + /* read back the value to see if it fitted in gid_t */ + if (*gid != x) { + PyErr_SetString(PyExc_TypeError, + "group id too big"); + return 0; + } + return 1; + } + PyErr_SetString(PyExc_TypeError, "group id must be integer"); + return 0; +} + #ifdef HAVE_CHOWN PyDoc_STRVAR(posix_chown__doc__, "chown(path, uid, gid)\n\n\ @@ -1981,14 +2048,20 @@ posix_chown(PyObject *self, PyObject *args) { char *path = NULL; - long uid, gid; + PyObject *uidobj, *gidobj; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "etll:chown", + if (!PyArg_ParseTuple(args, "etOO:chown", Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) + &uidobj, &gidobj)) return NULL; + if (!parse_uid(uidobj, &uid)) + return NULL; + if (!parse_gid(gidobj, &gid)) + return NULL; Py_BEGIN_ALLOW_THREADS - res = chown(path, (uid_t) uid, (gid_t) gid); + res = chown(path, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_allocated_filename(path); @@ -2007,10 +2080,17 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + PyObject *uidobj, *gidobj; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "iOO:fchown", &fd, &uidobj, &gidobj)) return NULL; + if (!parse_uid(uidobj, &uid)) + return NULL; + if (!parse_gid(gidobj, &gid)) + return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); Py_END_ALLOW_THREADS @@ -2882,7 +2962,7 @@ } PyMem_Free(apath); } - + if (arg == Py_None) { SYSTEMTIME now; GetSystemTime(&now); @@ -5740,38 +5820,9 @@ elem = PySequence_GetItem(groups, i); if (!elem) return NULL; - if (!PyInt_Check(elem)) { - if (!PyLong_Check(elem)) { - PyErr_SetString(PyExc_TypeError, - "groups must be integers"); - Py_DECREF(elem); - return NULL; - } else { - unsigned long x = PyLong_AsUnsignedLong(elem); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - grouplist[i] = x; - /* read back the value to see if it fitted in gid_t */ - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - } - } else { - long x = PyInt_AsLong(elem); - grouplist[i] = x; - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } + if (!parse_gid(elem, &grouplist[i])) { + Py_DECREF(elem); + return NULL; } Py_DECREF(elem); } @@ -6001,7 +6052,7 @@ int arg_is_unicode = 0; #endif - if (!PyArg_ParseTuple(args, "et:readlink", + if (!PyArg_ParseTuple(args, "et:readlink", Py_FileSystemDefaultEncoding, &path)) return NULL; #ifdef Py_USING_UNICODE @@ -6305,7 +6356,7 @@ } -PyDoc_STRVAR(posix_closerange__doc__, +PyDoc_STRVAR(posix_closerange__doc__, "closerange(fd_low, fd_high)\n\n\ Closes all file descriptors in [fd_low, fd_high), ignoring errors."); @@ -8251,10 +8302,10 @@ PyErr_Clear(); goto normal; } - + if (operation) { - woperation = PyUnicode_DecodeASCII(operation, + woperation = PyUnicode_DecodeASCII(operation, strlen(operation), NULL); if (!woperation) { PyErr_Clear(); @@ -8262,7 +8313,7 @@ goto normal; } } - + Py_BEGIN_ALLOW_THREADS rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0, PyUnicode_AS_UNICODE(unipath), @@ -8281,12 +8332,12 @@ #endif normal: - if (!PyArg_ParseTuple(args, "et|s:startfile", - Py_FileSystemDefaultEncoding, &filepath, + if (!PyArg_ParseTuple(args, "et|s:startfile", + Py_FileSystemDefaultEncoding, &filepath, &operation)) return NULL; Py_BEGIN_ALLOW_THREADS - rc = ShellExecute((HWND)0, operation, filepath, + rc = ShellExecute((HWND)0, operation, filepath, NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS if (rc <= (HINSTANCE)32) { @@ -8914,7 +8965,7 @@ /* GNU extensions. */ #ifdef O_ASYNC - /* Send a SIGIO signal whenever input or output + /* Send a SIGIO signal whenever input or output becomes available on file descriptor */ if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1; #endif @@ -9104,10 +9155,10 @@ * Step 2 of weak-linking support on Mac OS X. * * The code below removes functions that are not available on the - * currently active platform. + * currently active platform. * * This block allow one to use a python binary that was build on - * OSX 10.4 on OSX 10.3, without loosing access to new APIs on + * OSX 10.4 on OSX 10.3, without loosing access to new APIs on * OSX 10.4. */ #ifdef HAVE_FSTATVFS