Merge "Fix incorrect parameter types for locale funcs."
diff --git a/libc/Android.mk b/libc/Android.mk
index dae254f..0670930 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -241,7 +241,6 @@
upstream-freebsd/lib/libc/gen/sleep.c \
upstream-freebsd/lib/libc/gen/usleep.c \
upstream-freebsd/lib/libc/stdio/fclose.c \
- upstream-freebsd/lib/libc/stdio/flags.c \
upstream-freebsd/lib/libc/stdio/fopen.c \
upstream-freebsd/lib/libc/stdlib/abs.c \
upstream-freebsd/lib/libc/stdlib/getopt_long.c \
@@ -399,6 +398,7 @@
upstream-openbsd/lib/libc/stdio/fgetws.c \
upstream-openbsd/lib/libc/stdio/fileno.c \
upstream-openbsd/lib/libc/stdio/findfp.c \
+ upstream-openbsd/lib/libc/stdio/flags.c \
upstream-openbsd/lib/libc/stdio/fmemopen.c \
upstream-openbsd/lib/libc/stdio/fprintf.c \
upstream-openbsd/lib/libc/stdio/fpurge.c \
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 0dd3c27..cdb2777 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -59,7 +59,7 @@
endif
cpu_variant_mk := $(LOCAL_PATH)/arch-arm64/$(TARGET_CPU_VARIANT)/$(TARGET_CPU_VARIANT).mk
ifeq ($(wildcard $(cpu_variant_mk)),)
-$(error "TARGET_CPU_VARIANT not set or set to an unknown value. Possible values are generic, generic-neon, denver64. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
+$(error "TARGET_CPU_VARIANT not set or set to an unknown value. Possible values are generic, denver64. Use generic for devices that do not have a CPU similar to any of the supported cpu variants.")
endif
include $(cpu_variant_mk)
libc_common_additional_dependencies += $(cpu_variank_mk)
diff --git a/libc/arch-arm64/generic-neon/bionic/memcpy.S b/libc/arch-arm64/generic-neon/bionic/memcpy.S
deleted file mode 100644
index 320f748..0000000
--- a/libc/arch-arm64/generic-neon/bionic/memcpy.S
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Copyright (c) 2012, Linaro Limited
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Linaro nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Unaligned accesses
- *
- */
-
-#include <private/bionic_asm.h>
-
-#define dstin x0
-#define src x1
-#define count x2
-#define tmp1 x3
-#define tmp1w w3
-#define tmp2 x4
-#define tmp2w w4
-#define tmp3 x5
-#define tmp3w w5
-#define dst x6
-
-#define A_l x7
-#define A_h x8
-#define B_l x9
-#define B_h x10
-#define C_l x11
-#define C_h x12
-#define D_l x13
-#define D_h x14
-
-#define QA_l q0
-#define QA_h q1
-#define QB_l q2
-#define QB_h q3
-
-ENTRY(memcpy)
-
- mov dst, dstin
- cmp count, #64
- b.ge .Lcpy_not_short
- cmp count, #15
- b.le .Ltail15tiny
-
- /* Deal with small copies quickly by dropping straight into the
- * exit block. */
-.Ltail63:
- /* Copy up to 48 bytes of data. At this point we only need the
- * bottom 6 bits of count to be accurate. */
- ands tmp1, count, #0x30
- b.eq .Ltail15
- add dst, dst, tmp1
- add src, src, tmp1
- cmp tmp1w, #0x20
- b.eq 1f
- b.lt 2f
- ldp A_l, A_h, [src, #-48]
- stp A_l, A_h, [dst, #-48]
-1:
- ldp A_l, A_h, [src, #-32]
- stp A_l, A_h, [dst, #-32]
-2:
- ldp A_l, A_h, [src, #-16]
- stp A_l, A_h, [dst, #-16]
-
-.Ltail15:
- ands count, count, #15
- beq 1f
- add src, src, count
- ldp A_l, A_h, [src, #-16]
- add dst, dst, count
- stp A_l, A_h, [dst, #-16]
-1:
- ret
-
-.Ltail15tiny:
- /* Copy up to 15 bytes of data. Does not assume additional data
- being copied. */
- tbz count, #3, 1f
- ldr tmp1, [src], #8
- str tmp1, [dst], #8
-1:
- tbz count, #2, 1f
- ldr tmp1w, [src], #4
- str tmp1w, [dst], #4
-1:
- tbz count, #1, 1f
- ldrh tmp1w, [src], #2
- strh tmp1w, [dst], #2
-1:
- tbz count, #0, 1f
- ldrb tmp1w, [src]
- strb tmp1w, [dst]
-1:
- ret
-
-.Lcpy_not_short:
- /* We don't much care about the alignment of DST, but we want SRC
- * to be 128-bit (16 byte) aligned so that we don't cross cache line
- * boundaries on both loads and stores. */
- neg tmp2, src
- ands tmp2, tmp2, #15 /* Bytes to reach alignment. */
- b.eq 2f
- sub count, count, tmp2
- /* Copy more data than needed; it's faster than jumping
- * around copying sub-Quadword quantities. We know that
- * it can't overrun. */
- ldp A_l, A_h, [src]
- add src, src, tmp2
- stp A_l, A_h, [dst]
- add dst, dst, tmp2
- /* There may be less than 63 bytes to go now. */
- cmp count, #63
- b.le .Ltail63
-2:
- subs count, count, #128
- b.ge .Lcpy_body_large
- /* Less than 128 bytes to copy, so handle 64 here and then jump
- * to the tail. */
- ldp QA_l, QA_h, [src]
- ldp QB_l, QB_h, [src, #32]
- stp QA_l, QA_h, [dst]
- stp QB_l, QB_h, [dst, #32]
- tst count, #0x3f
- add src, src, #64
- add dst, dst, #64
- b.ne .Ltail63
- ret
-
- /* Critical loop. Start at a new cache line boundary. Assuming
- * 64 bytes per line this ensures the entire loop is in one line. */
- .p2align 6
-.Lcpy_body_large:
- /* There are at least 128 bytes to copy. */
- ldp QA_l, QA_h, [src, #0]
- sub dst, dst, #32 /* Pre-bias. */
- ldp QB_l, QB_h, [src, #32]! /* src += 64 - Pre-bias. */
-1:
- stp QA_l, QA_h, [dst, #32]
- ldp QA_l, QA_h, [src, #32]
- stp QB_l, QB_h, [dst, #64]!
- ldp QB_l, QB_h, [src, #64]!
-
- subs count, count, #64
- b.ge 1b
-
- stp QA_l, QA_h, [dst, #32]
- stp QB_l, QB_h, [dst, #64]
- add src, src, #32
- add dst, dst, #64 + 32
- tst count, #0x3f
- b.ne .Ltail63
- ret
-END(memcpy)
diff --git a/libc/arch-arm64/generic-neon/generic-neon.mk b/libc/arch-arm64/generic-neon/generic-neon.mk
deleted file mode 100644
index 77e3861..0000000
--- a/libc/arch-arm64/generic-neon/generic-neon.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-libc_bionic_src_files_arm64 += \
- arch-arm64/generic/bionic/memchr.S \
- arch-arm64/generic/bionic/memcmp.S \
- arch-arm64/generic/bionic/memmove.S \
- arch-arm64/generic/bionic/memset.S \
- arch-arm64/generic/bionic/stpcpy.S \
- arch-arm64/generic/bionic/strchr.S \
- arch-arm64/generic/bionic/strcmp.S \
- arch-arm64/generic/bionic/strcpy.S \
- arch-arm64/generic/bionic/strlen.S \
- arch-arm64/generic/bionic/strncmp.S \
- arch-arm64/generic/bionic/strnlen.S \
- arch-arm64/generic-neon/bionic/memcpy.S \
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 52f371b..fd2bf6c 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..475ee1a 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-freebsd/lib/libc/stdio/flags.c b/libc/upstream-openbsd/lib/libc/stdio/flags.c
similarity index 77%
rename from libc/upstream-freebsd/lib/libc/stdio/flags.c
rename to libc/upstream-openbsd/lib/libc/stdio/flags.c
index 1878c2f..d6df6da 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/flags.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/flags.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: flags.c,v 1.8 2014/08/31 02:21:18 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -30,22 +31,15 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <errno.h>
-
#include "local.h"
/*
* Return the (stdio) flags for a given mode. Store the flags
- * to be passed to an _open() syscall through *optr.
+ * to be passed to an open() syscall through *optr.
* Return 0 on error.
*/
int
@@ -78,34 +72,33 @@
return (0);
}
- /* 'b' (binary) is ignored */
- if (*mode == 'b')
- mode++;
-
- /* [rwa][b]\+ means read and write */
- if (*mode == '+') {
- mode++;
- ret = __SRW;
- m = O_RDWR;
- }
-
- /* 'b' (binary) can appear here, too -- and is ignored again */
- if (*mode == 'b')
- mode++;
-
- /* 'x' means exclusive (fail if the file exists) */
- if (*mode == 'x') {
- mode++;
- if (m == O_RDONLY) {
+ while (*mode != '\0')
+ switch (*mode++) {
+ case 'b':
+ break;
+ case '+':
+ ret = __SRW;
+ m = O_RDWR;
+ break;
+ case 'e':
+ o |= O_CLOEXEC;
+ break;
+ case 'x':
+ if (o & O_CREAT)
+ o |= O_EXCL;
+ break;
+ default:
+ /*
+ * Lots of software passes other extension mode
+ * letters, like Window's 't'
+ */
+#if 0
errno = EINVAL;
return (0);
+#else
+ break;
+#endif
}
- o |= O_EXCL;
- }
-
- /* set close-on-exec */
- if (*mode == 'e')
- o |= O_CLOEXEC;
*optr = m | o;
return (ret);
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);
}
diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h
index c4ee2d5..5c2fe4f 100644
--- a/tests/TemporaryFile.h
+++ b/tests/TemporaryFile.h
@@ -17,24 +17,26 @@
#include <fcntl.h>
#include <unistd.h>
-template<int (*mk_fn)(char*)>
+#include "private/bionic_macros.h"
+
+template <typename T = int (*)(char*)>
class GenericTemporaryFile {
public:
- GenericTemporaryFile(const char* dirpath = NULL) {
- if (dirpath != NULL) {
- init(dirpath);
- } else {
- // Since we might be running on the host or the target, and if we're
- // running on the host we might be running under bionic or glibc,
- // let's just try both possible temporary directories and take the
- // first one that works.
- init("/data/local/tmp");
- if (fd == -1) {
- init("/tmp");
- }
+ GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
+ // Since we might be running on the host or the target, and if we're
+ // running on the host we might be running under bionic or glibc,
+ // let's just try both possible temporary directories and take the
+ // first one that works.
+ init("/data/local/tmp");
+ if (fd == -1) {
+ init("/tmp");
}
}
+ GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
+ init(dirpath);
+ }
+
~GenericTemporaryFile() {
close(fd);
unlink(filename);
@@ -49,13 +51,17 @@
char filename[1024];
private:
+ T mk_fn;
+
void init(const char* tmp_dir) {
snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
fd = mk_fn(filename);
}
+
+ DISALLOW_COPY_AND_ASSIGN(GenericTemporaryFile);
};
-typedef GenericTemporaryFile<mkstemp> TemporaryFile;
+typedef GenericTemporaryFile<> TemporaryFile;
class TemporaryDir {
public:
@@ -77,4 +83,5 @@
return (mkdtemp(dirname) != NULL);
}
+ DISALLOW_COPY_AND_ASSIGN(TemporaryDir);
};
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index 6d3a308..7ffbfe0 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -68,7 +68,7 @@
TEST(ftw, ftw64) {
TemporaryDir td;
- GenericTemporaryFile<mkstemp64> tf(td.dirname);
+ TemporaryFile tf(td.dirname, mkstemp64);
ftw64(td.dirname, check_ftw64, 1);
}
@@ -80,6 +80,6 @@
TEST(ftw, nftw64) {
TemporaryDir td;
- GenericTemporaryFile<mkstemp64> tf(td.dirname);
+ TemporaryFile tf(td.dirname, mkstemp64);
nftw64(td.dirname, check_nftw64, 1, 0);
}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index c01ab68..6a653b4 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -756,3 +756,43 @@
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
+
+TEST(stdio, fdopen_CLOEXEC) {
+ int fd = open("/proc/version", O_RDONLY);
+ ASSERT_TRUE(fd != -1);
+
+ // This fd doesn't have O_CLOEXEC...
+ int flags = fcntl(fd, F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(0, flags & FD_CLOEXEC);
+
+ FILE* fp = fdopen(fd, "re");
+ ASSERT_TRUE(fp != NULL);
+
+ // ...but the new one does.
+ flags = fcntl(fileno(fp), F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
+
+ fclose(fp);
+ close(fd);
+}
+
+TEST(stdio, freopen_CLOEXEC) {
+ FILE* fp = fopen("/proc/version", "r");
+ ASSERT_TRUE(fp != NULL);
+
+ // This FILE* doesn't have O_CLOEXEC...
+ int flags = fcntl(fileno(fp), F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(0, flags & FD_CLOEXEC);
+
+ fp = freopen("/proc/version", "re", fp);
+
+ // ...but the new one does.
+ flags = fcntl(fileno(fp), F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
+
+ fclose(fp);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 667ccd6..e814ef7 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -162,19 +162,33 @@
ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
}
+TEST(stdlib, mkostemp64) {
+ TemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
+ int flags = fcntl(tf.fd, F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
+}
+
+TEST(stdlib, mkostemp) {
+ TemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
+ int flags = fcntl(tf.fd, F_GETFD);
+ ASSERT_TRUE(flags != -1);
+ ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
+}
+
+TEST(stdlib, mkstemp64) {
+ TemporaryFile tf(mkstemp64);
+ struct stat64 sb;
+ ASSERT_EQ(0, fstat64(tf.fd, &sb));
+ ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
+}
+
TEST(stdlib, mkstemp) {
TemporaryFile tf;
struct stat sb;
ASSERT_EQ(0, fstat(tf.fd, &sb));
}
-TEST(stdlib, mkstemp64) {
- GenericTemporaryFile<mkstemp64> tf;
- struct stat64 sb;
- ASSERT_EQ(0, fstat64(tf.fd, &sb));
- ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
-}
-
TEST(stdlib, system) {
int status;