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 | 
