summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixFile.c
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2001-08-23 17:37:07 (GMT)
committervincentdarley <vincentdarley>2001-08-23 17:37:07 (GMT)
commitf319c32167c2c52995fe53b438ef4bc34e9a4914 (patch)
tree6169e1176aad79725e33cee0d99ca91f726feed6 /unix/tclUnixFile.c
parent8d4c60866a8f603ab29fa193c8f4aff83f8beee7 (diff)
downloadtcl-f319c32167c2c52995fe53b438ef4bc34e9a4914.zip
tcl-f319c32167c2c52995fe53b438ef4bc34e9a4914.tar.gz
tcl-f319c32167c2c52995fe53b438ef4bc34e9a4914.tar.bz2
fs update
Diffstat (limited to 'unix/tclUnixFile.c')
-rw-r--r--unix/tclUnixFile.c121
1 files changed, 72 insertions, 49 deletions
diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c
index 308a320..bbfebf1 100644
--- a/unix/tclUnixFile.c
+++ b/unix/tclUnixFile.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: tclUnixFile.c,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $
+ * RCS: @(#) $Id: tclUnixFile.c,v 1.11 2001/08/23 17:37:08 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -210,15 +210,15 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
int matchHidden;
int result = TCL_OK;
Tcl_DString dsOrig;
- char *fileName;
+ Tcl_Obj *fileNamePtr;
int baseLength;
- fileName = Tcl_FSGetTranslatedPath(interp, pathPtr);
- if (fileName == NULL) {
+ fileNamePtr = Tcl_FSGetTranslatedPath(interp, pathPtr);
+ if (fileNamePtr == NULL) {
return TCL_ERROR;
}
Tcl_DStringInit(&dsOrig);
- Tcl_DStringAppend(&dsOrig, fileName, -1);
+ Tcl_DStringAppend(&dsOrig, Tcl_GetString(fileNamePtr), -1);
baseLength = Tcl_DStringLength(&dsOrig);
/*
@@ -315,10 +315,8 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
}
/*
- * Now check to see if the file matches. If there are more
- * characters to be processed, then ensure matching files are
- * directories before calling TclDoGlob. Otherwise, just add
- * the file to the result.
+ * Now check to see if the file matches, according to both type
+ * and pattern. If so, add the file to the result.
*/
utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &ds);
@@ -329,17 +327,29 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
Tcl_DStringAppend(&dsOrig, utf, -1);
fname = Tcl_DStringValue(&dsOrig);
if (types != NULL) {
- if (types->perm != 0) {
- struct stat buf;
+ struct stat buf;
+ if (types->perm != 0) {
if (TclpStat(fname, &buf) != 0) {
- panic("stat failed on known file");
+ /*
+ * Either the file has disappeared between the
+ * 'readdir' call and the 'TclpStat' 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
+ * problem. In all these cases, we define this
+ * to mean the file does not match any defined
+ * permission, and therefore it is not
+ * added to the list of files to return.
+ */
+ typeOk = 0;
}
+
/*
* readonly means that there are NO write permissions
* (even for user), but execute is OK for anybody
*/
- if (
+ if (typeOk && (
((types->perm & TCL_GLOB_PERM_RONLY) &&
(buf.st_mode & (S_IWOTH|S_IWGRP|S_IWUSR))) ||
((types->perm & TCL_GLOB_PERM_R) &&
@@ -348,17 +358,19 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
(TclpAccess(fname, W_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_X) &&
(TclpAccess(fname, X_OK) != 0))
- ) {
+ )) {
typeOk = 0;
}
}
if (typeOk && (types->type != 0)) {
- struct stat buf;
- /*
- * We must match at least one flag to be listed
- */
- typeOk = 0;
- if (TclpLstat(fname, &buf) >= 0) {
+ if (types->perm == 0) {
+ /* We haven't yet done a stat on the file */
+ if (TclpStat(fname, &buf) != 0) {
+ /* Posix error occurred */
+ typeOk = 0;
+ }
+ }
+ if (typeOk) {
/*
* In order bcdpfls as in 'find -t'
*/
@@ -373,19 +385,24 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
S_ISFIFO(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_FILE) &&
S_ISREG(buf.st_mode))
-#ifdef S_ISLNK
- || ((types->type & TCL_GLOB_TYPE_LINK) &&
- S_ISLNK(buf.st_mode))
-#endif
#ifdef S_ISSOCK
|| ((types->type & TCL_GLOB_TYPE_SOCK) &&
S_ISSOCK(buf.st_mode))
#endif
) {
- typeOk = 1;
+ /* Do nothing -- this file is ok */
+ } else {
+ typeOk = 0;
+#ifdef S_ISLNK
+ if (types->type & TCL_GLOB_TYPE_LINK) {
+ if (TclpLstat(fname, &buf) == 0) {
+ if (S_ISLNK(buf.st_mode)) {
+ typeOk = 1;
+ }
+ }
+ }
+#endif
}
- } else {
- /* Posix error occurred */
}
}
}
@@ -729,32 +746,38 @@ TclpObjAccess(pathPtr, mode)
#ifdef S_IFLNK
Tcl_Obj*
-TclpObjReadlink(pathPtr)
+TclpObjLink(pathPtr, toPtr)
Tcl_Obj *pathPtr;
+ Tcl_Obj *toPtr;
{
- char link[MAXPATHLEN];
- int length;
- char *native;
- Tcl_Obj* linkPtr;
-
- if (Tcl_FSGetTranslatedPath(NULL, pathPtr) == NULL) {
- return NULL;
- }
- length = readlink(Tcl_FSGetNativePath(pathPtr), link, sizeof(link));
- if (length < 0) {
+ Tcl_Obj* linkPtr = NULL;
+
+ if (toPtr != NULL) {
return NULL;
+ } else {
+ char link[MAXPATHLEN];
+ int length;
+ char *native;
+
+ if (Tcl_FSGetTranslatedPath(NULL, pathPtr) == NULL) {
+ return NULL;
+ }
+ length = readlink(Tcl_FSGetNativePath(pathPtr), link, sizeof(link));
+ if (length < 0) {
+ return NULL;
+ }
+
+ /*
+ * Allocate and copy the name, taking care since the
+ * name need not be null terminated.
+ */
+ native = (char*)ckalloc((unsigned)(1+length));
+ strncpy(native, link, (unsigned)length);
+ native[length] = '\0';
+
+ linkPtr = Tcl_FSNewNativePath(pathPtr, native);
+ Tcl_IncrRefCount(linkPtr);
}
-
- /*
- * Allocate and copy the name, taking care since the
- * name need not be null terminated.
- */
- native = (char*)ckalloc((unsigned)(1+length));
- strncpy(native, link, (unsigned)length);
- native[length] = '\0';
-
- linkPtr = Tcl_FSNewNativePath(pathPtr, native);
- Tcl_IncrRefCount(linkPtr);
return linkPtr;
}