diff options
Diffstat (limited to 'unix/tclUnixPipe.c')
-rw-r--r-- | unix/tclUnixPipe.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index 105f032..d0a5e53 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -18,6 +18,16 @@ #endif /* + * 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 + +/* * The following macros convert between TclFile's and fd's. The conversion * simple involves shifting fd's up by one to ensure that no valid fd is ever * the same as NULL. @@ -48,6 +58,7 @@ typedef struct PipeState { * Declarations for local functions defined in this file: */ +static const char * DefaultTempDir(void); static int PipeBlockModeProc(ClientData instanceData, int mode); static int PipeCloseProc(ClientData instanceData, Tcl_Interp *interp); @@ -198,7 +209,7 @@ TclpCreateTempFile( * We should also check against making more then TMP_MAX of these. */ - strcpy(fileName, P_tmpdir); /* INTL: Native. */ + strcpy(fileName, DefaultTempDir()); /* INTL: Native. */ if (fileName[strlen(fileName) - 1] != '/') { strcat(fileName, "/"); /* INTL: Native. */ } @@ -250,7 +261,7 @@ TclpTempFileName(void) * We should also check against making more then TMP_MAX of these. */ - strcpy(fileName, P_tmpdir); /* INTL: Native. */ + strcpy(fileName, DefaultTempDir()); /* INTL: Native. */ if (fileName[strlen(fileName) - 1] != '/') { strcat(fileName, "/"); /* INTL: Native. */ } @@ -270,6 +281,44 @@ TclpTempFileName(void) /* *---------------------------------------------------------------------- * + * DefaultTempDir -- + * + * Helper that does *part* of what tempnam() does. + * + *---------------------------------------------------------------------- + */ + +static const char * +DefaultTempDir(void) +{ + const char *dir; + struct stat buf; + + dir = getenv("TMPDIR"); + if (dir && dir[0] && stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode) + && access(dir, W_OK)) { + return dir; + } + +#ifdef P_tmpdir + dir = P_tmpdir; + if (stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode) && access(dir, W_OK)) { + return dir; + } +#endif + + /* + * 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 TCL_TEMPORARY_FILE_DIRECTORY; +} + +/* + *---------------------------------------------------------------------- + * * TclpCreatePipe -- * * Creates a pipe - simply calls the pipe() function. |