diff options
Diffstat (limited to 'unix/tclUnixFile.c')
-rw-r--r-- | unix/tclUnixFile.c | 187 |
1 files changed, 118 insertions, 69 deletions
diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index a24966c..2cb0027 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -6,10 +6,8 @@ * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * - * 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.53 2008/04/27 22:21:34 dkf Exp $ + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" @@ -24,7 +22,8 @@ static int NativeMatchType(Tcl_Interp *interp, const char* nativeEntry, * TclpFindExecutable -- * * This function computes the absolute path name of the current - * application, given its argv[0] value. + * application, given its argv[0] value. For Cygwin, argv[0] is + * ignored and the path is determined the same as under win32. * * Results: * None. @@ -40,10 +39,25 @@ TclpFindExecutable( const char *argv0) /* The value of the application's argv[0] * (native). */ { + Tcl_Encoding encoding; +#ifdef __CYGWIN__ + int length; + char buf[PATH_MAX * 2]; + char name[PATH_MAX * TCL_UTF_MAX + 1]; + GetModuleFileNameW(NULL, buf, PATH_MAX); + cygwin_conv_path(3, buf, name, PATH_MAX); + length = strlen(name); + if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) { + /* Strip '.exe' part. */ + length -= 4; + } + encoding = Tcl_GetEncoding(NULL, NULL); + TclSetObjNameOfExecutable( + Tcl_NewStringObj(name, length), encoding); +#else const char *name, *p; Tcl_StatBuf statBuf; Tcl_DString buffer, nameString, cwd, utfName; - Tcl_Encoding encoding; if (argv0 == NULL) { return; @@ -84,18 +98,18 @@ TclpFindExecutable( */ while (1) { - while (isspace(UCHAR(*p))) { /* INTL: BUG */ + while (TclIsSpaceProc(*p)) { p++; } name = p; while ((*p != ':') && (*p != 0)) { p++; } - Tcl_DStringSetLength(&buffer, 0); + TclDStringClear(&buffer); if (p != name) { Tcl_DStringAppend(&buffer, name, p - name); if (p[-1] != '/') { - Tcl_DStringAppend(&buffer, "/", 1); + TclDStringAppendLiteral(&buffer, "/"); } } name = Tcl_DStringAppend(&buffer, argv0, -1); @@ -160,11 +174,10 @@ TclpFindExecutable( Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&cwd), Tcl_DStringLength(&cwd), &buffer); if (Tcl_DStringValue(&cwd)[Tcl_DStringLength(&cwd) -1] != '/') { - Tcl_DStringAppend(&buffer, "/", 1); + TclDStringAppendLiteral(&buffer, "/"); } Tcl_DStringFree(&cwd); - Tcl_DStringAppend(&buffer, Tcl_DStringValue(&nameString), - Tcl_DStringLength(&nameString)); + TclDStringAppendDString(&buffer, &nameString); Tcl_DStringFree(&nameString); encoding = Tcl_GetEncoding(NULL, NULL); @@ -176,6 +189,7 @@ TclpFindExecutable( done: Tcl_DStringFree(&buffer); +#endif } /* @@ -232,9 +246,9 @@ TclpMatchInDirectory( Tcl_Obj *tailPtr; const char *nativeTail; - native = (const char *) Tcl_FSGetNativePath(pathPtr); + native = Tcl_FSGetNativePath(pathPtr); tailPtr = TclPathPart(interp, pathPtr, TCL_PATH_TAIL); - nativeTail = (const char *) Tcl_FSGetNativePath(tailPtr); + nativeTail = Tcl_FSGetNativePath(tailPtr); matchResult = NativeMatchType(interp, native, nativeTail, types); if (matchResult == 1) { Tcl_ListObjAppendElement(interp, resultPtr, pathPtr); @@ -273,7 +287,7 @@ TclpMatchInDirectory( */ if (dirName[dirLength-1] != '/') { - dirName = Tcl_DStringAppend(&dsOrig, "/", 1); + dirName = TclDStringAppendLiteral(&dsOrig, "/"); dirLength++; } } @@ -296,10 +310,9 @@ TclpMatchInDirectory( if (d == NULL) { Tcl_DStringFree(&ds); if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "couldn't read directory \"", - Tcl_DStringValue(&dsOrig), "\": ", - Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't read directory \"%s\": %s", + Tcl_DStringValue(&dsOrig), Tcl_PosixError(interp))); } Tcl_DStringFree(&dsOrig); Tcl_DecrRefCount(fileNamePtr); @@ -314,7 +327,7 @@ TclpMatchInDirectory( matchHiddenPat = (pattern[0] == '.') || ((pattern[0] == '\\') && (pattern[1] == '.')); - matchHidden = matchHiddenPat + matchHidden = matchHiddenPat || (types && (types->perm & TCL_GLOB_PERM_HIDDEN)); while ((entryPtr = TclOSreaddir(d)) != NULL) { /* INTL: Native. */ Tcl_DString utfDs; @@ -457,7 +470,7 @@ NativeMatchType( #ifndef MAC_OSX_TCL || ((types->perm & TCL_GLOB_PERM_HIDDEN) && (*nativeName != '.')) -#endif +#endif /* MAC_OSX_TCL */ ) { return 0; } @@ -475,12 +488,10 @@ NativeMatchType( * check that here: */ - if (types->type & TCL_GLOB_TYPE_LINK) { - if (TclOSlstat(nativeEntry, &buf) == 0) { - if (S_ISLNK(buf.st_mode)) { - return 1; - } - } + if ((types->type & TCL_GLOB_TYPE_LINK) + && (TclOSlstat(nativeEntry, &buf) == 0) + && S_ISLNK(buf.st_mode)) { + return 1; } return 0; } @@ -503,12 +514,10 @@ NativeMatchType( */ } else { #ifdef S_ISLNK - if (types->type & TCL_GLOB_TYPE_LINK) { - if (TclOSlstat(nativeEntry, &buf) == 0) { - if (S_ISLNK(buf.st_mode)) { - goto filetypeOK; - } - } + if ((types->type & TCL_GLOB_TYPE_LINK) + && (TclOSlstat(nativeEntry, &buf) == 0) + && S_ISLNK(buf.st_mode)) { + goto filetypeOK; } #endif /* S_ISLNK */ return 0; @@ -568,7 +577,7 @@ NativeMatchType( *---------------------------------------------------------------------- */ -char * +const char * TclpGetUserHome( const char *name, /* User name for desired home directory. */ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with @@ -578,15 +587,13 @@ TclpGetUserHome( Tcl_DString ds; const char *native = Tcl_UtfToExternalDString(NULL, name, -1, &ds); - pwPtr = getpwnam(native); /* INTL: Native. */ + pwPtr = TclpGetPwNam(native); /* INTL: Native. */ Tcl_DStringFree(&ds); if (pwPtr == NULL) { - endpwent(); return NULL; } Tcl_ExternalToUtfDString(NULL, pwPtr->pw_dir, -1, bufferPtr); - endpwent(); return Tcl_DStringValue(bufferPtr); } @@ -706,13 +713,13 @@ TclpGetNativeCwd( if (getcwd(buffer, MAXPATHLEN+1) == NULL) { /* INTL: Native. */ return NULL; } -#endif +#endif /* USEGETWD */ - if ((clientData == NULL) || strcmp(buffer, (const char*)clientData)) { - char *newCd = ckalloc((unsigned) strlen(buffer) + 1); + if ((clientData == NULL) || strcmp(buffer, (const char *) clientData)) { + char *newCd = ckalloc(strlen(buffer) + 1); strcpy(newCd, buffer); - return (ClientData) newCd; + return newCd; } /* @@ -756,12 +763,12 @@ TclpGetCwd( if (getwd(buffer) == NULL) /* INTL: Native. */ #else if (getcwd(buffer, MAXPATHLEN+1) == NULL) /* INTL: Native. */ -#endif +#endif /* USEGETWD */ { if (interp != NULL) { - Tcl_AppendResult(interp, - "error getting working directory name: ", - Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error getting working directory name: %s", + Tcl_PosixError(interp))); } return NULL; } @@ -812,7 +819,7 @@ TclpReadlink( return Tcl_DStringValue(linkPtr); #else return NULL; -#endif +#endif /* !DJGPP */ } /* @@ -846,7 +853,7 @@ TclpObjStat( #ifdef S_IFLNK -Tcl_Obj* +Tcl_Obj * TclpObjLink( Tcl_Obj *pathPtr, Tcl_Obj *toPtr, @@ -978,12 +985,8 @@ TclpObjLink( } Tcl_ExternalToUtfDString(NULL, link, length, &ds); - linkPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - if (linkPtr != NULL) { - Tcl_IncrRefCount(linkPtr); - } + linkPtr = TclDStringToObj(&ds); + Tcl_IncrRefCount(linkPtr); return linkPtr; } } @@ -1045,19 +1048,9 @@ TclpNativeToNormalized( ClientData clientData) { Tcl_DString ds; - Tcl_Obj *objPtr; - int len; - - const char *copy; - Tcl_ExternalToUtfDString(NULL, (const char*)clientData, -1, &ds); - copy = Tcl_DStringValue(&ds); - len = Tcl_DStringLength(&ds); - - objPtr = Tcl_NewStringObj(copy,len); - Tcl_DStringFree(&ds); - - return objPtr; + Tcl_ExternalToUtfDString(NULL, (const char *) clientData, -1, &ds); + return TclDStringToObj(&ds); } /* @@ -1080,7 +1073,8 @@ ClientData TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { - char *nativePathPtr, *str; + char *nativePathPtr; + const char *str; Tcl_DString ds; Tcl_Obj *validPathPtr; int len; @@ -1111,12 +1105,18 @@ TclNativeCreateNativeRep( str = Tcl_GetStringFromObj(validPathPtr, &len); Tcl_UtfToExternalDString(NULL, str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(char); + if (strlen(Tcl_DStringValue(&ds)) < len - sizeof(char)) { + /* See bug [3118489]: NUL in filenames */ + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; + } Tcl_DecrRefCount(validPathPtr); - nativePathPtr = ckalloc((unsigned) len); + nativePathPtr = ckalloc(len); memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len); Tcl_DStringFree(&ds); - return (ClientData)nativePathPtr; + return nativePathPtr; } /* @@ -1155,7 +1155,7 @@ TclNativeDupInternalRep( copy = ckalloc(len); memcpy(copy, clientData, len); - return (ClientData) copy; + return copy; } /* @@ -1182,6 +1182,55 @@ TclpUtime( return utime(Tcl_FSGetNativePath(pathPtr), tval); } +#ifdef __CYGWIN__ + +int +TclOSstat( + const char *name, + void *cygstat) +{ + struct stat buf; + Tcl_StatBuf *statBuf = cygstat; + int result = stat(name, &buf); + + statBuf->st_mode = buf.st_mode; + statBuf->st_ino = buf.st_ino; + statBuf->st_dev = buf.st_dev; + statBuf->st_rdev = buf.st_rdev; + statBuf->st_nlink = buf.st_nlink; + statBuf->st_uid = buf.st_uid; + statBuf->st_gid = buf.st_gid; + statBuf->st_size = buf.st_size; + statBuf->st_atime = buf.st_atime; + statBuf->st_mtime = buf.st_mtime; + statBuf->st_ctime = buf.st_ctime; + return result; +} + +int +TclOSlstat( + const char *name, + void *cygstat) +{ + struct stat buf; + Tcl_StatBuf *statBuf = cygstat; + int result = lstat(name, &buf); + + statBuf->st_mode = buf.st_mode; + statBuf->st_ino = buf.st_ino; + statBuf->st_dev = buf.st_dev; + statBuf->st_rdev = buf.st_rdev; + statBuf->st_nlink = buf.st_nlink; + statBuf->st_uid = buf.st_uid; + statBuf->st_gid = buf.st_gid; + statBuf->st_size = buf.st_size; + statBuf->st_atime = buf.st_atime; + statBuf->st_mtime = buf.st_mtime; + statBuf->st_ctime = buf.st_ctime; + return result; +} +#endif /* CYGWIN */ + /* * Local Variables: * mode: c |