summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixFCmd.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2012-11-14 13:01:46 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2012-11-14 13:01:46 (GMT)
commit7ecabf83c6ffcd212364b2b0b35ef18e98ee7ecd (patch)
tree50025dfed29a1aad376792dac26c592de41f9d6a /unix/tclUnixFCmd.c
parent47871a70f2f72a07a20bcf8ab3826068bf227392 (diff)
downloadtcl-7ecabf83c6ffcd212364b2b0b35ef18e98ee7ecd.zip
tcl-7ecabf83c6ffcd212364b2b0b35ef18e98ee7ecd.tar.gz
tcl-7ecabf83c6ffcd212364b2b0b35ef18e98ee7ecd.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.c54
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)