summaryrefslogtreecommitdiff
path: root/mjit.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-20 05:32:07 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-20 05:32:07 +0000
commit18af42d5a47a7e5642f11fce3b8774b0959064ba (patch)
treefb6e28c6d71ec23cdbcf0668844a0a25ca20fd4c /mjit.c
parent04178d396b99f715bac00df10897a184f2e69c03 (diff)
mjit.c: prefer $TMPDIR and $TMP
* mjit.c (system_tmpdir): prefer `$TMPDIR` and `$TMP` over system defulat temporary directory, if exists, writable, and safe. [ruby-core:85651] [Bug #14496] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'mjit.c')
-rw-r--r--mjit.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/mjit.c b/mjit.c
index 63be36d655..935f041a33 100644
--- a/mjit.c
+++ b/mjit.c
@@ -1228,16 +1228,15 @@ UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
#endif
static char *
-system_tmpdir(void)
+system_default_tmpdir(void)
{
- char *tmpdir;
/* c.f. ext/etc/etc.c:etc_systmpdir() */
#ifdef _WIN32
WCHAR tmppath[_MAX_PATH];
UINT len = rb_w32_system_tmpdir(tmppath, numberof(tmppath));
if (len) {
int blen = WideCharToMultiByte(CP_UTF8, 0, tmppath, len, NULL, 0, NULL, NULL);
- tmpdir= xmalloc(blen + 1);
+ char *tmpdir = xmalloc(blen + 1);
WideCharToMultiByte(CP_UTF8, 0, tmppath, len, tmpdir, blen, NULL, NULL);
tmpdir[blen] = '\0';
return tmpdir;
@@ -1249,7 +1248,7 @@ system_tmpdir(void)
char path[MAXPATHLEN];
size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
if (len > 0) {
- tmpdir = xmalloc(len);
+ char *tmpdir = xmalloc(len);
if (len > sizeof(path)) {
confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, len);
}
@@ -1259,11 +1258,44 @@ system_tmpdir(void)
return tmpdir;
}
#endif
- if (!(tmpdir = getenv("TMPDIR")) &&
- !(tmpdir = getenv("TMP"))) {
- return get_string("/tmp");
+ return 0;
+}
+
+static int
+check_tmpdir(const char *dir)
+{
+ struct stat st;
+
+ if (!dir) return FALSE;
+ if (stat(dir, &st)) return FALSE;
+ if (!S_ISDIR(st.st_mode)) return FALSE;
+#ifndef _WIN32
+# ifndef S_IWOTH
+# define S_IWOTH 002
+# endif
+ if (st.st_mode & S_IWOTH) {
+# ifdef S_ISVTX
+ if (!(st.st_mode & S_ISVTX)) return FALSE;
+# else
+ return FALSE;
+# endif
}
- return get_string(tmpdir);
+#endif
+ return access(dir, W_OK) == 0;
+}
+
+static char *
+system_tmpdir(void)
+{
+ char *tmpdir;
+# define RETURN_ENV(name) \
+ if (check_tmpdir(tmpdir = getenv(name))) return get_string(tmpdir)
+ RETURN_ENV("TMPDIR");
+ RETURN_ENV("TMP");
+ tmpdir = system_default_tmpdir();
+ if (check_tmpdir(tmpdir)) return tmpdir;
+ return get_string("/tmp");
+# undef RETURN_ENV
}
/* Default permitted number of units with a JIT code kept in
@@ -1298,6 +1330,7 @@ mjit_init(struct mjit_options *opts)
cc_path = CC_PATH;
tmp_dir = system_tmpdir();
+ verbose(2, "MJIT: tmp_dir is %s", tmp_dir);
init_header_filename();
pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch");