diff options
author | Steve Bennett <steveb@workware.net.au> | 2014-08-03 17:40:11 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2014-08-03 17:51:58 +1000 |
commit | 0b60827ba7bbbefd991a99dfcae4973d51387f82 (patch) | |
tree | f18569cddf2770bf8b108f60f1354c560c459c4e | |
parent | a07760e95c68569b635ecc97465175d9a306ff37 (diff) | |
download | jimtcl-0b60827ba7bbbefd991a99dfcae4973d51387f82.zip jimtcl-0b60827ba7bbbefd991a99dfcae4973d51387f82.tar.gz jimtcl-0b60827ba7bbbefd991a99dfcae4973d51387f82.tar.bz2 |
Temporary file creation should respect $TMPDIR
This applies to [exec] and [file tempfile]
Reported-by: Jakub Wilk
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim-aio.c | 49 | ||||
-rw-r--r-- | jim-exec.c | 8 | ||||
-rw-r--r-- | jim-file.c | 19 | ||||
-rw-r--r-- | jim.h | 1 |
4 files changed, 54 insertions, 23 deletions
@@ -45,6 +45,7 @@ #include <fcntl.h> #ifdef HAVE_UNISTD_H #include <unistd.h> +#include <sys/stat.h> #endif #include "jim.h" @@ -1411,6 +1412,54 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #endif /* JIM_BOOTSTRAP */ +/** + * Returns the file descriptor of a writable, newly created temp file + * or -1 on error. + * + * On success, leaves the filename in the interpreter result, otherwise + * leaves an error message. + */ +int Jim_MakeTempFile(Jim_Interp *interp, const char *template) +{ +#ifdef HAVE_MKSTEMP + int fd; + mode_t mask; + Jim_Obj *filenameObj; + + if (template == NULL) { + const char *tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) { + tmpdir = "/tmp/"; + } + filenameObj = Jim_NewStringObj(interp, tmpdir, -1); + if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') { + Jim_AppendString(interp, filenameObj, "/", 1); + } + Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1); + } + else { + filenameObj = Jim_NewStringObj(interp, template, -1); + } + + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); + + /* Update the template name directly with the filename */ + fd = mkstemp(filenameObj->bytes); + umask(mask); + if (fd < 0) { + Jim_SetResultString(interp, "Failed to create tempfile", -1); + Jim_FreeNewObj(interp, filenameObj); + return -1; + } + + Jim_SetResult(interp, filenameObj); + return fd; +#else + Jim_SetResultString(interp, "tempfile not supported", -1); + return -1; +#endif +} + FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) { Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); @@ -1576,15 +1576,13 @@ static int JimRewindFd(int fd) static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) { - char inName[] = "/tmp/tcl.tmp.XXXXXX"; - mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); - int fd = mkstemp(inName); - umask(mask); + int fd = Jim_MakeTempFile(interp, NULL); + if (fd == JIM_BAD_FD) { Jim_SetResultErrno(interp, "couldn't create temp file"); return -1; } - unlink(inName); + unlink(Jim_String(Jim_GetResult(interp))); if (contents) { if (write(fd, contents, len) != len) { Jim_SetResultErrno(interp, "couldn't write temp file"); @@ -483,32 +483,17 @@ static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } -#ifdef HAVE_MKSTEMP static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - int fd; - char *filename; - const char *template = "/tmp/tcl.tmp.XXXXXX"; - mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); + int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL); - if (argc >= 1) { - template = Jim_String(argv[0]); - } - filename = Jim_StrDup(template); - - fd = mkstemp(filename); - umask(mask); if (fd < 0) { - Jim_SetResultString(interp, "Failed to create tempfile", -1); - Jim_Free(filename); return JIM_ERR; } close(fd); - Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, filename, -1)); return JIM_OK; } -#endif static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -826,7 +811,6 @@ static const jim_subcmd_type file_command_table[] = { -1, /* Description: Creates the directories */ }, -#ifdef HAVE_MKSTEMP { "tempfile", "?template?", file_cmd_tempfile, @@ -834,7 +818,6 @@ static const jim_subcmd_type file_command_table[] = { 1, /* Description: Creates a temporary filename */ }, -#endif { "rename", "?-force? source dest", file_cmd_rename, @@ -614,6 +614,7 @@ JIM_EXPORT char *Jim_StrDupLen(const char *s, int l); /* environment */ JIM_EXPORT char **Jim_GetEnviron(void); JIM_EXPORT void Jim_SetEnviron(char **env); +JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *template); /* evaluation */ JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); |