diff options
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 127 |
1 files changed, 84 insertions, 43 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 01fcfb2..12b3472 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -844,14 +844,48 @@ check_gfax() *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW"); } +static BOOL +attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad) +{ + HANDLE hFindFile; + WIN32_FIND_DATAA FileData; + hFindFile = FindFirstFileA(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + +static BOOL +attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad) +{ + HANDLE hFindFile; + WIN32_FIND_DATAW FileData; + hFindFile = FindFirstFileW(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + static BOOL WINAPI Py_GetFileAttributesExA(LPCSTR pszFile, GET_FILEEX_INFO_LEVELS level, LPVOID pv) { BOOL result; - HANDLE hFindFile; - WIN32_FIND_DATAA FileData; LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; /* First try to use the system's implementation, if that is available and either succeeds to gives an error other than @@ -873,17 +907,7 @@ Py_GetFileAttributesExA(LPCSTR pszFile, accept). */ if (GetFileAttributesA(pszFile) == 0xFFFFFFFF) return FALSE; - hFindFile = FindFirstFileA(pszFile, &FileData); - if (hFindFile == INVALID_HANDLE_VALUE) - return FALSE; - FindClose(hFindFile); - pfad->dwFileAttributes = FileData.dwFileAttributes; - pfad->ftCreationTime = FileData.ftCreationTime; - pfad->ftLastAccessTime = FileData.ftLastAccessTime; - pfad->ftLastWriteTime = FileData.ftLastWriteTime; - pfad->nFileSizeHigh = FileData.nFileSizeHigh; - pfad->nFileSizeLow = FileData.nFileSizeLow; - return TRUE; + return attributes_from_dir(pszFile, pfad); } static BOOL WINAPI @@ -892,8 +916,6 @@ Py_GetFileAttributesExW(LPCWSTR pszFile, LPVOID pv) { BOOL result; - HANDLE hFindFile; - WIN32_FIND_DATAW FileData; LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; /* First try to use the system's implementation, if that is available and either succeeds to gives an error other than @@ -915,17 +937,7 @@ Py_GetFileAttributesExW(LPCWSTR pszFile, accept). */ if (GetFileAttributesW(pszFile) == 0xFFFFFFFF) return FALSE; - hFindFile = FindFirstFileW(pszFile, &FileData); - if (hFindFile == INVALID_HANDLE_VALUE) - return FALSE; - FindClose(hFindFile); - pfad->dwFileAttributes = FileData.dwFileAttributes; - pfad->ftCreationTime = FileData.ftCreationTime; - pfad->ftLastAccessTime = FileData.ftLastAccessTime; - pfad->ftLastWriteTime = FileData.ftLastWriteTime; - pfad->nFileSizeHigh = FileData.nFileSizeHigh; - pfad->nFileSizeLow = FileData.nFileSizeLow; - return TRUE; + return attributes_from_dir_w(pszFile, pfad); } static int @@ -936,10 +948,20 @@ win32_stat(const char* path, struct win32_stat *result) char *dot; /* XXX not supported on Win95 and NT 3.x */ if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - return -1; + if (GetLastError() != ERROR_SHARING_VIOLATION) { + /* Protocol violation: we explicitly clear errno, instead of + setting it to a POSIX error. Callers should use GetLastError. */ + errno = 0; + return -1; + } else { + /* Could not get attributes on open file. Fall back to + reading the directory. */ + if (!attributes_from_dir(path, &info)) { + /* Very strange. This should not fail now */ + errno = 0; + return -1; + } + } } code = attribute_data_to_stat(&info, result); if (code != 0) @@ -964,10 +986,20 @@ win32_wstat(const wchar_t* path, struct win32_stat *result) WIN32_FILE_ATTRIBUTE_DATA info; /* XXX not supported on Win95 and NT 3.x */ if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - return -1; + if (GetLastError() != ERROR_SHARING_VIOLATION) { + /* Protocol violation: we explicitly clear errno, instead of + setting it to a POSIX error. Callers should use GetLastError. */ + errno = 0; + return -1; + } else { + /* Could not get attributes on open file. Fall back to + reading the directory. */ + if (!attributes_from_dir_w(path, &info)) { + /* Very strange. This should not fail now */ + errno = 0; + return -1; + } + } } code = attribute_data_to_stat(&info, result); if (code < 0) @@ -4809,18 +4841,19 @@ _PyPopenCreateProcess(char *cmdstring, (sizeof(modulepath)/sizeof(modulepath[0])) -strlen(modulepath)); if (stat(modulepath, &statinfo) != 0) { + size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]); /* Eeek - file-not-found - possibly an embedding situation - see if we can locate it in sys.prefix */ strncpy(modulepath, Py_GetExecPrefix(), - sizeof(modulepath)/sizeof(modulepath[0])); + mplen); + modulepath[mplen-1] = '\0'; if (modulepath[strlen(modulepath)-1] != '\\') strcat(modulepath, "\\"); strncat(modulepath, szConsoleSpawn, - (sizeof(modulepath)/sizeof(modulepath[0])) - -strlen(modulepath)); + mplen-strlen(modulepath)); /* No where else to look - raise an easily identifiable error, rather than leaving Windows to report "file not found" - as the user is probably blissfully @@ -6215,16 +6248,23 @@ static PyObject * posix_fdopen(PyObject *self, PyObject *args) { int fd; - char *mode = "r"; + char *orgmode = "r"; int bufsize = -1; FILE *fp; PyObject *f; - if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) + char *mode; + if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize)) return NULL; - if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') { - PyErr_Format(PyExc_ValueError, - "invalid file mode '%s'", mode); + /* Sanitize mode. See fileobject.c */ + mode = PyMem_MALLOC(strlen(orgmode)+3); + if (!mode) { + PyErr_NoMemory(); + return NULL; + } + strcpy(mode, orgmode); + if (_PyFile_SanitizeMode(mode)) { + PyMem_FREE(mode); return NULL; } Py_BEGIN_ALLOW_THREADS @@ -6245,10 +6285,11 @@ posix_fdopen(PyObject *self, PyObject *args) #else fp = fdopen(fd, mode); #endif + PyMem_FREE(mode); Py_END_ALLOW_THREADS if (fp == NULL) return posix_error(); - f = PyFile_FromFile(fp, "<fdopen>", mode, fclose); + f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose); if (f != NULL) PyFile_SetBufSize(f, bufsize); return f; |