summaryrefslogtreecommitdiff
path: root/Utilities/cmlibarchive/libarchive/archive_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_util.c')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index e0852a3b5..34d8081cb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2012 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
@@ -50,6 +50,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
#include "archive_private.h"
#include "archive_string.h"
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
/* Generic initialization of 'struct archive' objects. */
int
__archive_clean(struct archive *a)
@@ -239,12 +243,13 @@ __archive_mktemp(const char *tmpdir)
errno = ENOMEM;
goto exit_tmpfile;
}
- GetTempPathW(l, tmp);
+ GetTempPathW((DWORD)l, tmp);
archive_wstrcpy(&temp_name, tmp);
free(tmp);
} else {
- archive_wstring_append_from_mbs(&temp_name, tmpdir,
- strlen(tmpdir));
+ if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
+ strlen(tmpdir)) < 0)
+ goto exit_tmpfile;
if (temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/');
}
@@ -292,7 +297,8 @@ __archive_mktemp(const char *tmpdir)
/* Generate a random file name through CryptGenRandom(). */
p = xp;
- if (!CryptGenRandom(hProv, (ep - p)*sizeof(wchar_t), (BYTE*)p)) {
+ if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
+ (BYTE*)p)) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
@@ -384,6 +390,7 @@ __archive_mktemp(const char *tmpdir)
fd = mkstemp(temp_name.s);
if (fd < 0)
goto exit_tmpfile;
+ __archive_ensure_cloexec_flag(fd);
unlink(temp_name.s);
exit_tmpfile:
archive_string_free(&temp_name);
@@ -437,7 +444,8 @@ __archive_mktemp(const char *tmpdir)
archive_strcat(&temp_name, "XXXXXXXXXX");
ep = temp_name.s + archive_strlen(&temp_name);
- fd = open("/dev/random", O_RDONLY);
+ fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
+ __archive_ensure_cloexec_flag(fd);
if (fd < 0)
seed = time(NULL);
else {
@@ -451,10 +459,12 @@ __archive_mktemp(const char *tmpdir)
p = tp;
while (p < ep)
*p++ = num[((unsigned)rand_r(&seed)) % sizeof(num)];
- fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR, 0600);
+ fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
+ 0600);
} while (fd < 0 && errno == EEXIST);
if (fd < 0)
goto exit_tmpfile;
+ __archive_ensure_cloexec_flag(fd);
unlink(temp_name.s);
exit_tmpfile:
archive_string_free(&temp_name);
@@ -463,3 +473,29 @@ exit_tmpfile:
#endif /* HAVE_MKSTEMP */
#endif /* !_WIN32 || __CYGWIN__ */
+
+/*
+ * Set FD_CLOEXEC flag to a file descriptor if it is not set.
+ * We have to set the flag if the platform does not provide O_CLOEXEC
+ * or F_DUPFD_CLOEXEC flags.
+ *
+ * Note: This function is absolutely called after creating a new file
+ * descriptor even if the platform seemingly provides O_CLOEXEC or
+ * F_DUPFD_CLOEXEC macros because it is possible that the platform
+ * merely declares those macros, especially Linux 2.6.18 - 2.6.24 do it.
+ */
+void
+__archive_ensure_cloexec_flag(int fd)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)fd; /* UNSED */
+#else
+ int flags;
+
+ if (fd >= 0) {
+ flags = fcntl(fd, F_GETFD);
+ if (flags != -1 && (flags & FD_CLOEXEC) == 0)
+ fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+ }
+#endif
+}