diff options
| author | das <das> | 2006-07-20 06:21:41 (GMT) | 
|---|---|---|
| committer | das <das> | 2006-07-20 06:21:41 (GMT) | 
| commit | bed796e06772e11d807d9394771ef16cf766b2cd (patch) | |
| tree | 87aa93a682398fe04c4b734c7ea00049bf6fba02 /unix/tclUnixFCmd.c | |
| parent | 8cb60c333409bcc5ab4d0388905e7840b41422b2 (diff) | |
| download | tcl-bed796e06772e11d807d9394771ef16cf766b2cd.zip tcl-bed796e06772e11d807d9394771ef16cf766b2cd.tar.gz tcl-bed796e06772e11d807d9394771ef16cf766b2cd.tar.bz2 | |
	* macosx/tclMacOSXNotify.c (Tcl_InitNotifier, Tcl_WaitForEvent): create
	notifier thread lazily upon first call to Tcl_WaitForEvent() rather than
	in Tcl_InitNotifier(). Allows calling exeve() in processes where the
	event loop has not yet been run (Darwin's execve() fails in processes
	with more than one thread), in particular allows embedders to call
	fork() followed by execve(), previously the pthread_atfork() child
	handler's call to Tcl_InitNotifier() would immediately recreate the
	notifier thread in the child after a fork.
	* macosx/tclMacOSXNotify.c (Tcl_InitNotifier):     add support for
	* unix/tclUnixFCmd.c (DoRenameFile, CopyFileAtts): weakly importing
	* unix/tclUnixInit.c (TclpSetInitialEncodings):    symbols not available
	on OSX 10.2 or 10.3, enables binaires built on later OSX versions to run
	on earlier ones.
	* macosx/README: document how to enable weak-linking; cleanup.
	* unix/tclUnixPort.h: add support for weak-linking; conditionalize
	AvailabilityMacros.h inclusion; only disable realpath on 10.2 or earlier
	when threads are enabled.
	* unix/tclLoadDyld.c (TclpLoadMemoryGetBuffer): change runtime Darwin
	* unix/tclUnixInit.c (TclpInitPlatform):        release check to use
	                                                global initialized once.
	* unix/tclUnixFCmd.c (DoRenameFile, TclpObjNormalizePath): add runtime
	Darwin release check to determine if realpath is threadsafe.
	* unix/configure.in: add check on Darwin for compiler support of weak
	* unix/tcl.m4:       import and for AvailabilityMacros.h header; move
	Darwin specific checks & defines that are only relevant to the tcl build
	out of tcl.m4; restrict framework option to Darwin; cleanup quoting.
	* unix/configure: autoconf-2.13
	* unix/tclLoadDyld.c (TclpLoadMemory):
	* unix/tclUnixPipe.c (TclpCreateProcess): fix signed-with-unsigned
	comparison and other warnings from gcc4 -Wextra.
Diffstat (limited to 'unix/tclUnixFCmd.c')
| -rw-r--r-- | unix/tclUnixFCmd.c | 120 | 
1 files changed, 72 insertions, 48 deletions
| diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index 317eca7..84b819e 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -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: tclUnixFCmd.c,v 1.28.2.9 2006/03/28 10:47:09 das Exp $ + * RCS: @(#) $Id: tclUnixFCmd.c,v 1.28.2.10 2006/07/20 06:21:46 das Exp $   *   * Portions of this code were derived from NetBSD source code which has   * the following copyright notice: @@ -189,6 +189,22 @@ Realpath(path, resolved)  #define Realpath realpath  #endif +#ifndef NO_REALPATH +#if defined(__APPLE__) && defined(TCL_THREADS) && \ +	defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ +	MAC_OS_X_VERSION_MIN_REQUIRED < 1030 +/* + * prior to Darwin 7, realpath is not threadsafe, c.f. bug 711232; + * if we might potentially be running on pre-10.3 OSX, + * check Darwin release at runtime before using realpath. + */ +extern long tclMacOSXDarwinRelease; +#define haveRealpath (tclMacOSXDarwinRelease >= 7) +#else +#define haveRealpath 1 +#endif +#endif /* NO_REALPATH */ +  /*   *--------------------------------------------------------------------------- @@ -266,7 +282,7 @@ DoRenameFile(src, dst)       * conditionally compiled because realpath() not defined on all systems.       */ -    if (errno == EINVAL) { +    if (errno == EINVAL && haveRealpath) {  	char srcPath[MAXPATHLEN], dstPath[MAXPATHLEN];  	DIR *dirPtr;  	Tcl_DirEntry *dirEntPtr; @@ -402,6 +418,9 @@ DoCopyFile(src, dst, statBufPtr)  		return TCL_ERROR;  	    }  #ifdef HAVE_COPYFILE +#ifdef WEAK_IMPORT_COPYFILE +	    if (copyfile != NULL) +#endif  	    copyfile(src, dst, NULL, COPYFILE_XATTR|COPYFILE_NOFOLLOW_SRC);  #endif  	    break; @@ -1206,6 +1225,9 @@ CopyFileAtts(src, dst, statBufPtr)  	return TCL_ERROR;      }  #ifdef HAVE_COPYFILE +#ifdef WEAK_IMPORT_COPYFILE +    if (copyfile != NULL) +#endif      copyfile(src, dst, NULL, COPYFILE_XATTR|COPYFILE_ACL);  #endif      return TCL_OK; @@ -1815,7 +1837,7 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)  #ifndef NO_REALPATH      /* For speed, try to get the entire path in one go */ -    if (nextCheckpoint == 0) { +    if (nextCheckpoint == 0 && haveRealpath) {          char *lastDir = strrchr(currentPathEndPosition, '/');  	if (lastDir != NULL) {  	    nativePath = Tcl_UtfToExternalDString(NULL, path,  @@ -1869,57 +1891,59 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)       * have 'realpath'.       */  #ifndef NO_REALPATH -    /*  -     * If we only had '/foo' or '/' then we never increment nextCheckpoint -     * and we don't need or want to go through 'Realpath'.  Also, on some -     * platforms, passing an empty string to 'Realpath' will give us the -     * normalized pwd, which is not what we want at all! -     */ -    if (nextCheckpoint == 0) return 0; -     -    nativePath = Tcl_UtfToExternalDString(NULL, path, nextCheckpoint, &ds); -    if (Realpath(nativePath, normPath) != NULL) { -	int newNormLen; -	wholeStringOk: -	newNormLen = strlen(normPath); -	if ((newNormLen == Tcl_DStringLength(&ds)) -		&& (strcmp(normPath, nativePath) == 0)) { -	    /* String is unchanged */ +    if (haveRealpath) { +	/*  +	 * If we only had '/foo' or '/' then we never increment nextCheckpoint +	 * and we don't need or want to go through 'Realpath'.  Also, on some +	 * platforms, passing an empty string to 'Realpath' will give us the +	 * normalized pwd, which is not what we want at all! +	 */ +	if (nextCheckpoint == 0) return 0; +	 +	nativePath = Tcl_UtfToExternalDString(NULL, path, nextCheckpoint, &ds); +	if (Realpath(nativePath, normPath) != NULL) { +	    int newNormLen; +	    wholeStringOk: +	    newNormLen = strlen(normPath); +	    if ((newNormLen == Tcl_DStringLength(&ds)) +		    && (strcmp(normPath, nativePath) == 0)) { +		/* String is unchanged */ +		Tcl_DStringFree(&ds); +		if (path[nextCheckpoint] != '\0') { +		    nextCheckpoint++; +		} +		return nextCheckpoint; +	    } +	     +	    /*  +	     * Free up the native path and put in its place the +	     * converted, normalized path. +	     */  	    Tcl_DStringFree(&ds); +	    Tcl_ExternalToUtfDString(NULL, normPath, (int) newNormLen, &ds); +      	    if (path[nextCheckpoint] != '\0') { -		nextCheckpoint++; +		/* not at end, append remaining path */ +		int normLen = Tcl_DStringLength(&ds); +		Tcl_DStringAppend(&ds, path + nextCheckpoint, +			pathLen - nextCheckpoint); +		/*  +		 * We recognise up to and including the directory +		 * separator. +		 */	 +		nextCheckpoint = normLen + 1; +	    } else { +		/* We recognise the whole string */  +		nextCheckpoint = Tcl_DStringLength(&ds);  	    } -	    return nextCheckpoint; -	} -	 -	/*  -	 * Free up the native path and put in its place the -	 * converted, normalized path. -	 */ -	Tcl_DStringFree(&ds); -	Tcl_ExternalToUtfDString(NULL, normPath, (int) newNormLen, &ds); - -	if (path[nextCheckpoint] != '\0') { -	    /* not at end, append remaining path */ -	    int normLen = Tcl_DStringLength(&ds); -	    Tcl_DStringAppend(&ds, path + nextCheckpoint, -		    pathLen - nextCheckpoint);  	    /*  -	     * We recognise up to and including the directory -	     * separator. -	     */	 -	    nextCheckpoint = normLen + 1; -	} else { -	    /* We recognise the whole string */  -	    nextCheckpoint = Tcl_DStringLength(&ds); +	     * Overwrite with the normalized path. +	     */ +	    Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds), +		    Tcl_DStringLength(&ds));  	} -	/*  -	 * Overwrite with the normalized path. -	 */ -	Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds), -		Tcl_DStringLength(&ds)); +	Tcl_DStringFree(&ds);      } -    Tcl_DStringFree(&ds);  #endif	/* !NO_REALPATH */      return nextCheckpoint; | 
