CLOEXEC support in fdopen, freopen, and mkostemp/mkostemps.
Change-Id: I74ea88e0d4973d6ab3c57da7d8bb643c31592b14
diff --git a/libc/bionic/lfs64_support.cpp b/libc/bionic/lfs64_support.cpp
index ab795f5..45d4f7f 100644
--- a/libc/bionic/lfs64_support.cpp
+++ b/libc/bionic/lfs64_support.cpp
@@ -17,11 +17,20 @@
#include <ftw.h>
#include <stdlib.h>
-int mkstemp64(char* filename) {
- // Delegation will work in this case because all the transitive dependencies
- // are already 64-bit ready. In particular, we don't have non-O_LARGEFILE
- // open (our open is actually open64) and stat and stat64 are the same.
- return mkstemp(filename);
+// Delegation will work in these cases because all the transitive dependencies
+// are already 64-bit ready. In particular, we don't have non-O_LARGEFILE
+// open (our open is actually open64) and stat and stat64 are the same.
+int mkstemp64(char* path) {
+ return mkstemp(path);
+}
+int mkostemp64(char* path, int flags) {
+ return mkostemp(path, flags);
+}
+int mkstemps64(char* path, int suffix_length) {
+ return mkstemps(path, suffix_length);
+}
+int mkostemps64(char* path, int suffix_length, int flags) {
+ return mkostemps(path, suffix_length, flags);
}
typedef int (*ftw_fn)(const char*, const struct stat*, int);
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index db56ce3..f57c320 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -46,6 +46,7 @@
#endif
#define O_ASYNC FASYNC
+#define O_RSYNC O_SYNC
#define SPLICE_F_MOVE 1
#define SPLICE_F_NONBLOCK 2
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 52f71dd..80a6578 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -59,8 +59,15 @@
extern char* mkdtemp(char*);
extern char* mktemp(char*) __warnattr("mktemp possibly used unsafely; consider using mkstemp");
-extern int mkstemp(char*);
+
+extern int mkostemp64(char*, int);
+extern int mkostemp(char*, int);
+extern int mkostemps64(char*, int, int);
+extern int mkostemps(char*, int, int);
extern int mkstemp64(char*);
+extern int mkstemp(char*);
+extern int mkstemps64(char*, int);
+extern int mkstemps(char*, int);
extern long strtol(const char *, char **, int);
extern long long strtoll(const char *, char **, int);
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 20bc1a3..475ee1af 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -169,9 +169,7 @@
extern int dup(int);
extern int dup2(int, int);
-#if defined(__USE_GNU)
extern int dup3(int, int, int);
-#endif
extern int fcntl(int, int, ...);
extern int ioctl(int, int, ...);
extern int flock(int, int);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fdopen.c b/libc/upstream-openbsd/lib/libc/stdio/fdopen.c
index 3e47f2c..1c0c813 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fdopen.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fdopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdopen.c,v 1.6 2008/04/21 12:28:35 otto Exp $ */
+/* $OpenBSD: fdopen.c,v 1.7 2014/08/31 02:21:18 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -66,6 +66,7 @@
if ((fp = __sfp()) == NULL)
return (NULL);
fp->_flags = flags;
+
/*
* If opened for appending, but underlying descriptor does not have
* O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
@@ -73,6 +74,13 @@
*/
if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
fp->_flags |= __SAPP;
+
+ /*
+ * If close-on-exec was requested, then turn it on if not already
+ */
+ if ((oflags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC))
+ fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
+
fp->_file = fd;
fp->_cookie = fp;
fp->_read = __sread;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/freopen.c b/libc/upstream-openbsd/lib/libc/stdio/freopen.c
index 3158fb1..82717b1 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/freopen.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/freopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: freopen.c,v 1.13 2009/11/09 00:18:27 kurt Exp $ */
+/* $OpenBSD: freopen.c,v 1.14 2014/08/31 02:21:18 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -134,7 +134,7 @@
* assume stderr is always fd STDERR_FILENO, even if being freopen'd.
*/
if (wantfd >= 0 && f != wantfd) {
- if (dup2(f, wantfd) >= 0) {
+ if (dup3(f, wantfd, oflags & O_CLOEXEC) >= 0) {
(void) close(f);
f = wantfd;
}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/mktemp.c b/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
index cb154c4..2a17e52 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mktemp.c,v 1.33 2014/05/06 22:55:27 millert Exp $ */
+/* $OpenBSD: mktemp.c,v 1.34 2014/08/31 02:21:18 guenther Exp $ */
/*
* Copyright (c) 1996-1998, 2008 Theo de Raadt
* Copyright (c) 1997, 2008-2009 Todd C. Miller
@@ -35,12 +35,14 @@
#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
#define MIN_X 6
+#define MKOTEMP_FLAGS (O_APPEND | O_CLOEXEC | O_DSYNC | O_RSYNC | O_SYNC)
+
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
static int
-mktemp_internal(char *path, int slen, int mode)
+mktemp_internal(char *path, int slen, int mode, int flags)
{
char *start, *cp, *ep;
const char *tempchars = TEMPCHARS;
@@ -63,6 +65,12 @@
return(-1);
}
+ if (flags & ~MKOTEMP_FLAGS) {
+ errno = EINVAL;
+ return(-1);
+ }
+ flags |= O_CREAT | O_EXCL | O_RDWR;
+
tries = INT_MAX;
do {
cp = start;
@@ -85,7 +93,7 @@
return(errno == ENOENT ? 0 : -1);
break;
case MKTEMP_FILE:
- fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
+ fd = open(path, flags, S_IRUSR|S_IWUSR);
if (fd != -1 || errno != EEXIST)
return(fd);
break;
@@ -107,7 +115,7 @@
char *
_mktemp(char *path)
{
- if (mktemp_internal(path, 0, MKTEMP_NAME) == -1)
+ if (mktemp_internal(path, 0, MKTEMP_NAME, 0) == -1)
return(NULL);
return(path);
}
@@ -122,15 +130,27 @@
}
int
+mkostemps(char *path, int slen, int flags)
+{
+ return(mktemp_internal(path, slen, MKTEMP_FILE, flags));
+}
+
+int
mkstemp(char *path)
{
- return(mktemp_internal(path, 0, MKTEMP_FILE));
+ return(mktemp_internal(path, 0, MKTEMP_FILE, 0));
+}
+
+int
+mkostemp(char *path, int flags)
+{
+ return(mktemp_internal(path, 0, MKTEMP_FILE, flags));
}
int
mkstemps(char *path, int slen)
{
- return(mktemp_internal(path, slen, MKTEMP_FILE));
+ return(mktemp_internal(path, slen, MKTEMP_FILE, 0));
}
char *
@@ -138,6 +158,6 @@
{
int error;
- error = mktemp_internal(path, 0, MKTEMP_DIR);
+ error = mktemp_internal(path, 0, MKTEMP_DIR, 0);
return(error ? NULL : path);
}