diff options
| author | donal.k.fellows@manchester.ac.uk <dkf> | 2012-11-14 13:01:46 (GMT) | 
|---|---|---|
| committer | donal.k.fellows@manchester.ac.uk <dkf> | 2012-11-14 13:01:46 (GMT) | 
| commit | cacf431730cb2c231a4deb93231823c497b77a17 (patch) | |
| tree | 50025dfed29a1aad376792dac26c592de41f9d6a /unix/tclUnixFCmd.c | |
| parent | 96566452f49919d3085275de74aa4db2b9fbb2dd (diff) | |
| download | tcl-cacf431730cb2c231a4deb93231823c497b77a17.zip tcl-cacf431730cb2c231a4deb93231823c497b77a17.tar.gz tcl-cacf431730cb2c231a4deb93231823c497b77a17.tar.bz2  | |
	* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
	out all the code to do temporary file creation so that it is possible
	to make it correct in one place. Allow overriding of the back-stop
	default temporary file location at compile time by setting the
	TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
	name (defaults to "/tmp" as that is the most common default).
Diffstat (limited to 'unix/tclUnixFCmd.c')
| -rw-r--r-- | unix/tclUnixFCmd.c | 54 | 
1 files changed, 45 insertions, 9 deletions
diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index d3cc6bf..559992f 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -62,6 +62,16 @@  #define DOTREE_F	3	/* regular file */  /* + * Fallback temporary file location the temporary file generation code. Can be + * overridden at compile time for when it is known that temp files can't be + * written to /tmp (hello, iOS!). + */ + +#ifndef TCL_TEMPORARY_FILE_DIRECTORY +#define TCL_TEMPORARY_FILE_DIRECTORY	"/tmp" +#endif + +/*   * Callbacks for file attributes code.   */ @@ -2093,7 +2103,7 @@ TclpObjNormalizePath(  /*   *----------------------------------------------------------------------   * - * TclpOpenTemporaryFile -- + * TclpOpenTemporaryFile, TclUnixOpenTemporaryFile --   *   *	Creates a temporary file, possibly based on the supplied bits and   *	pieces of template supplied in the first three arguments. If the @@ -2103,7 +2113,12 @@ TclpObjNormalizePath(   *	file to go away once it is no longer needed.   *   * Results: - *	A read-write Tcl Channel open on the file. + *	A read-write Tcl Channel open on the file for TclpOpenTemporaryFile, + *	or a file descriptor (or -1 on failure) for TclUnixOpenTemporaryFile. + * + * Side effects: + *	Accesses the filesystem. Will set the contents of the Tcl_Obj fourth + *	argument (if that is non-NULL).   *   *----------------------------------------------------------------------   */ @@ -2115,11 +2130,30 @@ TclpOpenTemporaryFile(      Tcl_Obj *extensionObj,      Tcl_Obj *resultingNameObj)  { -    Tcl_Channel chan; +    int fd = TclUnixOpenTemporaryFile(dirObj, basenameObj, extensionObj, +	    resultingNameObj); + +    if (fd == -1) { +	return NULL; +    } +    return Tcl_MakeFileChannel(INT2PTR(fd), TCL_READABLE|TCL_WRITABLE); +} + +int +TclUnixOpenTemporaryFile( +    Tcl_Obj *dirObj, +    Tcl_Obj *basenameObj, +    Tcl_Obj *extensionObj, +    Tcl_Obj *resultingNameObj) +{      Tcl_DString template, tmp;      const char *string;      int len, fd; +    /* +     * We should also check against making more then TMP_MAX of these. +     */ +      if (dirObj) {  	string = Tcl_GetStringFromObj(dirObj, &len);  	Tcl_UtfToExternalDString(NULL, string, len, &template); @@ -2155,9 +2189,10 @@ TclpOpenTemporaryFile(      }      if (fd == -1) { -	return NULL; +	Tcl_DStringFree(&template); +	return -1;      } -    chan = Tcl_MakeFileChannel(INT2PTR(fd), TCL_READABLE|TCL_WRITABLE); +      if (resultingNameObj) {  	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&template),  		Tcl_DStringLength(&template), &tmp); @@ -2176,7 +2211,7 @@ TclpOpenTemporaryFile(      }      Tcl_DStringFree(&template); -    return chan; +    return fd;  }  /* @@ -2203,11 +2238,12 @@ DefaultTempDir(void)  #endif      /* -     * Assume that "/tmp" is always an existing writable directory; we've no -     * recovery mechanism if it isn't. +     * Assume that the default location ("/tmp" if not overridden) is always +     * an existing writable directory; we've no recovery mechanism if it +     * isn't.       */ -    return "/tmp"; +    return TCL_TEMPORARY_FILE_DIRECTORY;  }  #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)  | 
