From 17543c4edf712509641c3f7b8bf44a63b172818e Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Mon, 29 Oct 2001 15:02:44 +0000 Subject: win fs fixes --- ChangeLog | 12 ++++++++++++ generic/tclIOUtil.c | 34 +++++++++++++++------------------- tests/fileName.test | 12 +++++++++++- win/tclWin32Dll.c | 6 +++++- win/tclWinFile.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ win/tclWinInt.h | 5 ++++- 6 files changed, 87 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a22e8b..b7d6c92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-10-29 Vince Darley + + * win/tclWinFile.c: fix to '-types {f r}' bug in + TclpMatchInDirectory (which could cause a UMR, as well as + returning wrong results). Also improved API for 'stat' + to resolve [Bug#219258]. + * win/tclWin32Dll.c + * win/tclWinInt.h: addition of improved stat API to internal + lookup table. + * tests/fileName.test: two new tests for the above bug. + * generic/tclIOUtil.c: some cleanup of comments and #ifdefs + 2001-10-29 Donal K. Fellows * unix/tclUnixFile.c (TclpMatchInDirectory): Argument to access() diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 240b5dc..dc91066 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -17,7 +17,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIOUtil.c,v 1.23 2001/10/18 12:08:11 vincentdarley Exp $ + * RCS: @(#) $Id: tclIOUtil.c,v 1.24 2001/10/29 15:02:44 vincentdarley Exp $ */ #include "tclInt.h" @@ -513,7 +513,7 @@ FsReleaseIterator(void) { * could not be allocated. * * Side effects: - * Memory allocataed and modifies the link list for filesystems. + * Memory allocated and modifies the link list for filesystems. * *---------------------------------------------------------------------- */ @@ -1344,14 +1344,12 @@ Tcl_FSStat(pathPtr, buf) } else { path = Tcl_GetString(transPtr); } -#endif /* USE_OBSOLETE_FS_HOOKS */ /* * Call each of the "stat" function in succession. A non-return * value of -1 indicates the particular function has succeeded. */ -#ifdef USE_OBSOLETE_FS_HOOKS Tcl_MutexLock(&obsoleteFsHookMutex); statProcPtr = statProcList; while ((retVal == -1) && (statProcPtr != NULL)) { @@ -1449,14 +1447,12 @@ Tcl_FSAccess(pathPtr, mode) } else { path = Tcl_GetString(transPtr); } -#endif /* USE_OBSOLETE_FS_HOOKS */ /* * Call each of the "access" function in succession. A non-return * value of -1 indicates the particular function has succeeded. */ -#ifdef USE_OBSOLETE_FS_HOOKS Tcl_MutexLock(&obsoleteFsHookMutex); accessProcPtr = accessProcList; while ((retVal == -1) && (accessProcPtr != NULL)) { @@ -1525,7 +1521,6 @@ Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) } else { path = Tcl_GetString(transPtr); } -#endif /* USE_OBSOLETE_FS_HOOKS */ /* * Call each of the "Tcl_OpenFileChannel" function in succession. @@ -1533,7 +1528,6 @@ Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) * succeeded. */ -#ifdef USE_OBSOLETE_FS_HOOKS Tcl_MutexLock(&obsoleteFsHookMutex); openFileChannelProcPtr = openFileChannelProcList; while ((retVal == NULL) && (openFileChannelProcPtr != NULL)) { @@ -4534,7 +4528,8 @@ NativeUtime(pathPtr, tval) struct utimbuf local_tval; local_tval.actime=tval->actime+gmt_offset; local_tval.modtime=tval->modtime+gmt_offset; - return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)),&local_tval); + return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)), + &local_tval); #else return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)),tval); #endif @@ -4550,8 +4545,8 @@ NativeUtime(pathPtr, tval) * * Insert the passed procedure pointer at the head of the list of * functions which are used during a call to 'TclStat(...)'. The - * passed function should be have exactly like 'TclStat' when called - * during that time (see 'TclStat(...)' for more informatin). + * passed function should behave exactly like 'TclStat' when called + * during that time (see 'TclStat(...)' for more information). * The function will be added even if it already in the list. * * Results: @@ -4559,7 +4554,7 @@ NativeUtime(pathPtr, tval) * could not be allocated. * * Side effects: - * Memory allocataed and modifies the link list for 'TclStat' + * Memory allocated and modifies the link list for 'TclStat' * functions. * *---------------------------------------------------------------------- @@ -4652,10 +4647,11 @@ TclStatDeleteProc (proc) * TclAccessInsertProc -- * * Insert the passed procedure pointer at the head of the list of - * functions which are used during a call to 'TclAccess(...)'. The - * passed function should be have exactly like 'TclAccess' when - * called during that time (see 'TclAccess(...)' for more informatin). - * The function will be added even if it already in the list. + * functions which are used during a call to 'TclAccess(...)'. + * The passed function should behave exactly like 'TclAccess' when + * called during that time (see 'TclAccess(...)' for more + * information). The function will be added even if it already in + * the list. * * Results: * Normally TCL_OK; TCL_ERROR if memory for a new node in the list @@ -4756,9 +4752,9 @@ TclAccessDeleteProc(proc) * * Insert the passed procedure pointer at the head of the list of * functions which are used during a call to - * 'Tcl_OpenFileChannel(...)'. The passed function should be have + * 'Tcl_OpenFileChannel(...)'. The passed function should behave * exactly like 'Tcl_OpenFileChannel' when called during that time - * (see 'Tcl_OpenFileChannel(...)' for more informatin). The + * (see 'Tcl_OpenFileChannel(...)' for more information). The * function will be added even if it already in the list. * * Results: @@ -4766,7 +4762,7 @@ TclAccessDeleteProc(proc) * could not be allocated. * * Side effects: - * Memory allocataed and modifies the link list for + * Memory allocated and modifies the link list for * 'Tcl_OpenFileChannel' functions. * *---------------------------------------------------------------------- diff --git a/tests/fileName.test b/tests/fileName.test index 92f0e30..757a8d9 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -10,7 +10,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: fileName.test,v 1.14 2001/09/04 18:06:34 vincentdarley Exp $ +# RCS: @(#) $Id: fileName.test,v 1.15 2001/10/29 15:02:44 vincentdarley Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest @@ -1327,6 +1327,16 @@ test filename-11.25 {Tcl_GlobCmd} { } [list 0 [lsort [list [file join $globname a1]\ [file join $globname a2]\ [file join $globname a3]]]] +test filename-11.25.1 {Tcl_GlobCmd} { + list [catch {lsort [glob -type {d r} -dir $globname *]} msg] $msg +} [list 0 [lsort [list [file join $globname a1]\ + [file join $globname a2]\ + [file join $globname a3]]]] +test filename-11.25.2 {Tcl_GlobCmd} { + list [catch {lsort [glob -type {d r w} -dir $globname *]} msg] $msg +} [list 0 [lsort [list [file join $globname a1]\ + [file join $globname a2]\ + [file join $globname a3]]]] test filename-11.26 {Tcl_GlobCmd} { list [catch {glob -type d -path $globname *} msg] $msg } [list 0 [list $globname]] diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index ed4051a..ce9bbcb 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWin32Dll.c,v 1.9 2000/03/31 08:52:30 hobbs Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.10 2001/10/29 15:02:44 vincentdarley Exp $ */ #include "tclWinInt.h" @@ -78,6 +78,8 @@ static TclWinProcs asciiProcs = { WCHAR *, TCHAR **)) SearchPathA, (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA, (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA, + (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS, + LPVOID)) GetFileAttributesExA, }; static TclWinProcs unicodeProcs = { @@ -115,6 +117,8 @@ static TclWinProcs unicodeProcs = { WCHAR *, TCHAR **)) SearchPathW, (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW, (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW, + (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS, + LPVOID)) GetFileAttributesExW, }; TclWinProcs *tclWinProcs; diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 67d1385..cc5e9c5 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinFile.c,v 1.17 2001/09/27 00:36:16 dgp Exp $ + * RCS: @(#) $Id: tclWinFile.c,v 1.18 2001/10/29 15:02:44 vincentdarley Exp $ */ #include "tclWinInt.h" @@ -339,8 +339,6 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) typeOk = 0; } } else { - struct stat buf; - if (attr & FILE_ATTRIBUTE_HIDDEN) { /* If invisible */ if ((types->perm == 0) || @@ -369,12 +367,16 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) } } if (typeOk && types->type != 0) { - if (types->perm == 0) { - /* We haven't yet done a stat on the file */ - if (NativeStat(nativeName, &buf) != 0) { - /* Posix error occurred */ - typeOk = 0; - } + struct stat buf; + + if (NativeStat(nativeName, &buf) != 0) { + /* + * Posix error occurred, either the file + * has disappeared, or there is some other + * strange error. In any case we don't + * return this file. + */ + typeOk = 0; } if (typeOk) { /* @@ -791,7 +793,7 @@ TclpGetCwd(interp, bufferPtr) } /* - * Watch for the wierd Windows c:\\UNC syntax. + * Watch for the weird Windows c:\\UNC syntax. */ if (tclWinProcs->useWide) { @@ -831,6 +833,7 @@ TclpObjStat(pathPtr, statPtr) Tcl_Obj *pathPtr; /* Path of file to stat */ struct stat *statPtr; /* Filled with results of stat call. */ { +#ifdef OLD_API Tcl_Obj *transPtr; /* * Eliminate file names containing wildcard characters, or subsequent @@ -842,7 +845,8 @@ TclpObjStat(pathPtr, statPtr) Tcl_SetErrno(ENOENT); return -1; } - +#endif + /* * Ensure correct file sizes by forcing the OS to write any * pending data to disk. This is done only for channels which are @@ -883,14 +887,19 @@ NativeStat(nativePath, statPtr) struct stat *statPtr; /* Filled with results of stat call. */ { Tcl_DString ds; +#ifdef OLD_API WIN32_FIND_DATAT data; HANDLE handle; +#else + WIN32_FILE_ATTRIBUTE_DATA data; +#endif DWORD attr; WCHAR nativeFullPath[MAX_PATH]; TCHAR *nativePart; CONST char *fullPath; int dev, mode; +#ifdef OLD_API handle = (*tclWinProcs->findFirstFileProc)(nativePath, &data); if (handle == INVALID_HANDLE_VALUE) { /* @@ -914,7 +923,15 @@ NativeStat(nativePath, statPtr) } else { FindClose(handle); } - +#else + if((*tclWinProcs->getFileAttributesExProc)(nativePath, + GetFileExInfoStandard, + &data) != TRUE) { + Tcl_SetErrno(ENOENT); + return -1; + } +#endif + (*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH, nativeFullPath, &nativePart); @@ -959,7 +976,11 @@ NativeStat(nativePath, statPtr) } Tcl_DStringFree(&ds); +#ifdef OLD_API attr = data.a.dwFileAttributes; +#else + attr = data.dwFileAttributes; +#endif mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | S_IEXEC : S_IFREG; mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE; if (NativeIsExec(nativePath)) { @@ -981,10 +1002,17 @@ NativeStat(nativePath, statPtr) statPtr->st_uid = 0; statPtr->st_gid = 0; statPtr->st_rdev = (dev_t) dev; +#ifdef OLD_API statPtr->st_size = data.a.nFileSizeLow; statPtr->st_atime = ToCTime(data.a.ftLastAccessTime); statPtr->st_mtime = ToCTime(data.a.ftLastWriteTime); statPtr->st_ctime = ToCTime(data.a.ftCreationTime); +#else + statPtr->st_size = data.nFileSizeLow; + statPtr->st_atime = ToCTime(data.ftLastAccessTime); + statPtr->st_mtime = ToCTime(data.ftLastWriteTime); + statPtr->st_ctime = ToCTime(data.ftCreationTime); +#endif return 0; } diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 287ecb3..199942f 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinInt.h,v 1.11 2001/09/10 17:17:42 andreas_kupries Exp $ + * RCS: @(#) $Id: tclWinInt.h,v 1.12 2001/10/29 15:02:44 vincentdarley Exp $ */ #ifndef _TCLWININT @@ -89,6 +89,9 @@ typedef struct TclWinProcs { CONST TCHAR *, DWORD, WCHAR *, TCHAR **); BOOL (WINAPI *setCurrentDirectoryProc)(CONST TCHAR *); BOOL (WINAPI *setFileAttributesProc)(CONST TCHAR *, DWORD); + BOOL (WINAPI *getFileAttributesExProc)(CONST TCHAR *, + GET_FILEEX_INFO_LEVELS, LPVOID); + } TclWinProcs; EXTERN TclWinProcs *tclWinProcs; -- cgit v0.12