diff options
author | Anthony Green <green@moxielogic.com> | 2014-05-19 18:04:28 -0400 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2014-05-19 18:04:28 -0400 |
commit | 629f1029c47e522e4331988f02f32c203a070e28 (patch) | |
tree | 8ba4966f4f5b0389ccd0dd2f86bcac8f8ba8b500 | |
parent | 0403f332b1f478696c30d3d8a0e2f6eef24aaf88 (diff) | |
parent | c1166d4f653bf6d17ad8c265cf5e8da84e2e76dc (diff) | |
download | libffi-629f1029c47e522e4331988f02f32c203a070e28.tar.gz |
Merge pull request #120 from l0kod/tmpfile
Create temporary file with O_TMPFILE and O_CLOEXEC when available
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/closures.c | 35 |
2 files changed, 31 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac index d3b8b99..d7b6e40 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ EOF AM_MAINTAINER_MODE AC_CHECK_HEADERS(sys/mman.h) -AC_CHECK_FUNCS(mmap) +AC_CHECK_FUNCS([mmap mkostemp]) AC_FUNC_MMAP_BLACKLIST dnl The -no-testsuite modules omit the test subdir. diff --git a/src/closures.c b/src/closures.c index c7863f3..78818d9 100644 --- a/src/closures.c +++ b/src/closures.c @@ -265,9 +265,15 @@ static size_t execsize = 0; /* Open a temporary file name, and immediately unlink it. */ static int -open_temp_exec_file_name (char *name) +open_temp_exec_file_name (char *name, int flags) { - int fd = mkstemp (name); + int fd; + +#ifdef HAVE_MKOSTEMP + fd = mkostemp (name, flags); +#else + fd = mkstemp (name); +#endif if (fd != -1) unlink (name); @@ -280,8 +286,27 @@ static int open_temp_exec_file_dir (const char *dir) { static const char suffix[] = "/ffiXXXXXX"; - size_t lendir = strlen (dir); - char *tempname = __builtin_alloca (lendir + sizeof (suffix)); + int lendir, flags, fd; + char *tempname; + +#ifdef O_CLOEXEC + flags = O_CLOEXEC; +#else + flags = 0; +#endif + +#ifdef O_TMPFILE + fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700); + /* If the running system does not support the O_TMPFILE flag then retry without it. */ + if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) { + return fd; + } else { + errno = 0; + } +#endif + + lendir = strlen (dir); + tempname = __builtin_alloca (lendir + sizeof (suffix)); if (!tempname) return -1; @@ -289,7 +314,7 @@ open_temp_exec_file_dir (const char *dir) memcpy (tempname, dir, lendir); memcpy (tempname + lendir, suffix, sizeof (suffix)); - return open_temp_exec_file_name (tempname); + return open_temp_exec_file_name (tempname, flags); } /* Open a temporary file in the directory in the named environment |