diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2012-11-14 13:01:46 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2012-11-14 13:01:46 (GMT) |
commit | 2e074de52a82c12f60c06c55d7d61afa28018bc5 (patch) | |
tree | 50025dfed29a1aad376792dac26c592de41f9d6a /unix/tclUnixFCmd.c | |
parent | 2b18d7d0193a3510b0739b88b05e46337d1a8571 (diff) | |
download | tcl-2e074de52a82c12f60c06c55d7d61afa28018bc5.zip tcl-2e074de52a82c12f60c06c55d7d61afa28018bc5.tar.gz tcl-2e074de52a82c12f60c06c55d7d61afa28018bc5.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) |