diff options
Diffstat (limited to 'unix/tclUnixFile.c')
-rw-r--r-- | unix/tclUnixFile.c | 224 |
1 files changed, 88 insertions, 136 deletions
diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index bbfebf1..befa699 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -9,14 +9,12 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclUnixFile.c,v 1.11 2001/08/23 17:37:08 vincentdarley Exp $ + * RCS: @(#) $Id: tclUnixFile.c,v 1.12 2001/08/30 08:53:15 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" -char * TclpGetCwd _ANSI_ARGS_((Tcl_Interp *interp, Tcl_DString *bufferPtr)); - /* *--------------------------------------------------------------------------- @@ -208,6 +206,7 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_DString ds; struct stat statBuf; int matchHidden; + int nativeDirLen; int result = TCL_OK; Tcl_DString dsOrig; Tcl_Obj *fileNamePtr; @@ -241,12 +240,6 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) } } - if ((TclpStat(dirName, &statBuf) != 0) /* INTL: UTF-8. */ - || !S_ISDIR(statBuf.st_mode)) { - Tcl_DStringFree(&dsOrig); - return TCL_OK; - } - /* * Check to see if the pattern needs to compare with hidden files. */ @@ -263,11 +256,19 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) */ native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds); + + if ((stat(native, &statBuf) != 0) /* INTL: UTF-8. */ + || !S_ISDIR(statBuf.st_mode)) { + Tcl_DStringFree(&dsOrig); + Tcl_DStringFree(&ds); + return TCL_OK; + } + d = opendir(native); /* INTL: Native. */ - Tcl_DStringFree(&ds); if (d == NULL) { char savedChar = '\0'; Tcl_ResetResult(interp); + Tcl_DStringFree(&ds); /* * Strip off a trailing '/' if necessary, before reporting the error. @@ -289,7 +290,10 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) return TCL_ERROR; } + nativeDirLen = Tcl_DStringLength(&ds); + while (1) { + Tcl_DString utfDs; char *utf; struct dirent *entryPtr; @@ -319,7 +323,7 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) * and pattern. If so, add the file to the result. */ - utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &ds); + utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &utfDs); if (Tcl_StringMatch(utf, pattern) != 0) { int typeOk = 1; @@ -328,15 +332,23 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) fname = Tcl_DStringValue(&dsOrig); if (types != NULL) { struct stat buf; - + char *nativeEntry; + Tcl_DStringSetLength(&ds, nativeDirLen); + Tcl_DStringAppend(&ds, entryPtr->d_name, -1); + nativeEntry = Tcl_DStringValue(&ds); + /* + * The native name of the file is in entryPtr->d_name. + * We can use this below. + */ + if (types->perm != 0) { - if (TclpStat(fname, &buf) != 0) { + if (stat(nativeEntry, &buf) != 0) { /* * Either the file has disappeared between the - * 'readdir' call and the 'TclpStat' call, or + * 'readdir' call and the 'stat' call, or * the file is a link to a file which doesn't * exist (which we could ascertain with - * TclpLstat), or there is some other strange + * lstat), or there is some other strange * problem. In all these cases, we define this * to mean the file does not match any defined * permission, and therefore it is not @@ -353,11 +365,11 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) ((types->perm & TCL_GLOB_PERM_RONLY) && (buf.st_mode & (S_IWOTH|S_IWGRP|S_IWUSR))) || ((types->perm & TCL_GLOB_PERM_R) && - (TclpAccess(fname, R_OK) != 0)) || + (access(entryPtr->d_name, R_OK) != 0)) || ((types->perm & TCL_GLOB_PERM_W) && - (TclpAccess(fname, W_OK) != 0)) || + (access(entryPtr->d_name, W_OK) != 0)) || ((types->perm & TCL_GLOB_PERM_X) && - (TclpAccess(fname, X_OK) != 0)) + (access(entryPtr->d_name, X_OK) != 0)) )) { typeOk = 0; } @@ -365,7 +377,7 @@ 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 (TclpStat(fname, &buf) != 0) { + if (stat(nativeEntry, &buf) != 0) { /* Posix error occurred */ typeOk = 0; } @@ -395,7 +407,7 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) typeOk = 0; #ifdef S_ISLNK if (types->type & TCL_GLOB_TYPE_LINK) { - if (TclpLstat(fname, &buf) == 0) { + if (lstat(nativeEntry, &buf) == 0) { if (S_ISLNK(buf.st_mode)) { typeOk = 1; } @@ -411,10 +423,11 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_NewStringObj(fname, Tcl_DStringLength(&dsOrig))); } } - Tcl_DStringFree(&ds); + Tcl_DStringFree(&utfDs); } closedir(d); + Tcl_DStringFree(&ds); Tcl_DStringFree(&dsOrig); return result; } @@ -466,7 +479,7 @@ TclpGetUserHome(name, bufferPtr) /* *--------------------------------------------------------------------------- * - * TclpAccess -- + * TclpObjAccess -- * * This function replaces the library version of access(). * @@ -479,26 +492,23 @@ TclpGetUserHome(name, bufferPtr) *--------------------------------------------------------------------------- */ -int -TclpAccess(path, mode) - CONST char *path; /* Path of file to access (UTF-8). */ - int mode; /* Permission setting. */ +int +TclpObjAccess(pathPtr, mode) + Tcl_Obj *pathPtr; /* Path of file to access */ + int mode; /* Permission setting. */ { - int result; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - result = access(native, mode); /* INTL: Native. */ - Tcl_DStringFree(&ds); - - return result; + char *path = Tcl_FSGetNativePath(pathPtr); + if (path == NULL) { + return -1; + } else { + return access(path, mode); + } } /* *--------------------------------------------------------------------------- * - * TclpChdir -- + * TclpObjChdir -- * * This function replaces the library version of chdir(). * @@ -511,25 +521,22 @@ TclpAccess(path, mode) *--------------------------------------------------------------------------- */ -int -TclpChdir(dirName) - CONST char *dirName; /* Path to new working directory (UTF-8). */ +int +TclpObjChdir(pathPtr) + Tcl_Obj *pathPtr; /* Path to new working directory */ { - int result; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds); - result = chdir(native); /* INTL: Native. */ - Tcl_DStringFree(&ds); - - return result; + char *path = Tcl_FSGetNativePath(pathPtr); + if (path == NULL) { + return -1; + } else { + return chdir(path); + } } /* *---------------------------------------------------------------------- * - * TclpLstat -- + * TclpObjLstat -- * * This function replaces the library version of lstat(). * @@ -542,26 +549,23 @@ TclpChdir(dirName) *---------------------------------------------------------------------- */ -int -TclpLstat(path, bufPtr) - CONST char *path; /* Path of file to stat (UTF-8). */ +int +TclpObjLstat(pathPtr, bufPtr) + Tcl_Obj *pathPtr; /* Path of file to stat */ struct stat *bufPtr; /* Filled with results of stat call. */ { - int result; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - result = lstat(native, bufPtr); /* INTL: Native. */ - Tcl_DStringFree(&ds); - - return result; + char *path = Tcl_FSGetNativePath(pathPtr); + if (path == NULL) { + return -1; + } else { + return lstat(path, bufPtr); + } } /* *--------------------------------------------------------------------------- * - * TclpGetCwd -- + * TclpObjGetCwd -- * * This function replaces the library version of getcwd(). * @@ -579,6 +583,22 @@ TclpLstat(path, bufPtr) *---------------------------------------------------------------------- */ +Tcl_Obj* +TclpObjGetCwd(interp) + Tcl_Interp *interp; +{ + Tcl_DString ds; + if (TclpGetCwd(interp, &ds) != NULL) { + Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); + Tcl_IncrRefCount(cwdPtr); + Tcl_DStringFree(&ds); + return cwdPtr; + } else { + return NULL; + } +} + +/* Older string based version */ char * TclpGetCwd(interp, bufferPtr) Tcl_Interp *interp; /* If non-NULL, used for error reporting. */ @@ -648,7 +668,7 @@ TclpReadlink(path, linkPtr) /* *---------------------------------------------------------------------- * - * TclpStat -- + * TclpObjStat -- * * This function replaces the library version of stat(). * @@ -661,87 +681,19 @@ TclpReadlink(path, linkPtr) *---------------------------------------------------------------------- */ -int -TclpStat(path, bufPtr) - CONST char *path; /* Path of file to stat (in UTF-8). */ - struct stat *bufPtr; /* Filled with results of stat call. */ -{ - int result; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - result = stat(native, bufPtr); /* INTL: Native. */ - Tcl_DStringFree(&ds); - - return result; -} - -int -TclpObjLstat(pathPtr, buf) - Tcl_Obj *pathPtr; - struct stat *buf; -{ - char *path = Tcl_FSGetNativePath(pathPtr); - if (path == NULL) { - return -1; - } else { - return lstat(path, buf); - } -} - int -TclpObjStat(pathPtr, buf) - Tcl_Obj *pathPtr; - struct stat *buf; -{ - char *path = Tcl_FSGetNativePath(pathPtr); - if (path == NULL) { - return -1; - } else { - return stat(path, buf); - } -} - -Tcl_Obj* -TclpObjGetCwd(interp) - Tcl_Interp *interp; -{ - Tcl_DString ds; - if (TclpGetCwd(interp, &ds) != NULL) { - Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); - Tcl_IncrRefCount(cwdPtr); - Tcl_DStringFree(&ds); - return cwdPtr; - } else { - return NULL; - } -} - -int -TclpObjChdir(pathPtr) - Tcl_Obj *pathPtr; -{ - char *path = Tcl_FSGetNativePath(pathPtr); - if (path == NULL) { - return -1; - } else { - return chdir(path); - } -} - -int -TclpObjAccess(pathPtr, mode) - Tcl_Obj *pathPtr; - int mode; +TclpObjStat(pathPtr, bufPtr) + Tcl_Obj *pathPtr; /* Path of file to stat */ + struct stat *bufPtr; /* Filled with results of stat call. */ { char *path = Tcl_FSGetNativePath(pathPtr); if (path == NULL) { return -1; } else { - return access(path, mode); + return stat(path, bufPtr); } } + #ifdef S_IFLNK |