aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2014-08-03 17:40:11 +1000
committerSteve Bennett <steveb@workware.net.au>2014-08-03 17:51:58 +1000
commit0b60827ba7bbbefd991a99dfcae4973d51387f82 (patch)
treef18569cddf2770bf8b108f60f1354c560c459c4e
parenta07760e95c68569b635ecc97465175d9a306ff37 (diff)
downloadjimtcl-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.c49
-rw-r--r--jim-exec.c8
-rw-r--r--jim-file.c19
-rw-r--r--jim.h1
4 files changed, 54 insertions, 23 deletions
diff --git a/jim-aio.c b/jim-aio.c
index 22c77b9..70fc1e3 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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);
diff --git a/jim-exec.c b/jim-exec.c
index a6fdb02..e952ee7 100644
--- a/jim-exec.c
+++ b/jim-exec.c
@@ -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");
diff --git a/jim-file.c b/jim-file.c
index 6d10a2b..ea65f49 100644
--- a/jim-file.c
+++ b/jim-file.c
@@ -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,
diff --git a/jim.h b/jim.h
index c278a9b..ece4b74 100644
--- a/jim.h
+++ b/jim.h
@@ -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);