From 926a698c5ac69b599014ce147cc814343f0aaa4f Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 12 Dec 2014 14:43:55 +0100 Subject: config: move STDIO_FUTEXES up a bit Signed-off-by: Bernhard Reutner-Fischer --- extra/Configs/Config.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 32180f72d..00480e9eb 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1430,6 +1430,13 @@ config UCLIBC_HAS_STRING_ARCH_OPT These are small and fast, the only reason _not_ to say Y here is for debugging purposes. +config UCLIBC_HAS_STDIO_FUTEXES + bool "Use futexes for multithreaded I/O locking" + depends on UCLIBC_HAS_THREADS_NATIVE + help + If you want to compile uClibc to use futexes for low-level + I/O locking, answer Y. Otherwise, answer N. + config UCLIBC_HAS_CTYPE_TABLES bool "Use Table Versions Of 'ctype.h' Functions." default y @@ -1889,13 +1896,6 @@ config UCLIBC_HAS_GNU_GETOPT Most people will answer Y. -config UCLIBC_HAS_STDIO_FUTEXES - bool "Use futexes for multithreaded I/O locking" - depends on UCLIBC_HAS_THREADS_NATIVE - help - If you want to compile uClibc to use futexes for low-level - I/O locking, answer Y. Otherwise, answer N. - config UCLIBC_HAS_GETOPT_LONG bool "Support getopt_long/getopt_long_only" depends on !UCLIBC_HAS_GNU_GETOPT -- cgit v1.2.3 From d6da534cbf05dc4d09221881afd49b275ca7cd29 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 12 Dec 2014 16:06:17 +0100 Subject: test: disable ptytest unless HAS_PTY Signed-off-by: Bernhard Reutner-Fischer --- test/stdlib/Makefile.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/stdlib/Makefile.in b/test/stdlib/Makefile.in index 0bb06975e..53e5a7280 100644 --- a/test/stdlib/Makefile.in +++ b/test/stdlib/Makefile.in @@ -5,3 +5,9 @@ DODIFF_qsort := 1 DODIFF_testatexit := 1 DODIFF_teston_exit := 1 DODIFF_teststrtol := 1 + +TESTS_DISABLED := +ifeq ($(UCLIBC_HAS_PTY),) +TESTS_DISABLED += ptytest +endif + -- cgit v1.2.3 From 067637375658047d70c296606ae17ef0bc86499d Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 12 Dec 2014 16:18:12 +0100 Subject: unistd: allow to turn off getopt_long The GNU variant of getopt() previously had no way to turn off getopt_long() support. --- Makefile.in | 2 +- extra/Configs/Config.in | 14 +++++++------- extra/config/conf.c | 5 ++--- include/getopt.h | 2 +- libc/sysdeps/linux/common/bits/getopt.h | 2 +- libc/unistd/Makefile.in | 14 ++++++++++---- libc/unistd/getopt.c | 2 ++ test/nptl/tst-cancel7.c | 7 +++++-- test/nptl/tst-mqueue7.c | 6 ++++-- test/test-skeleton.c | 10 +++++++++- 10 files changed, 42 insertions(+), 22 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3b8e04348..5d60ddaba 100644 --- a/Makefile.in +++ b/Makefile.in @@ -276,7 +276,7 @@ HEADERS_RM-$(UCLIBC_HAS_GETTEXT_AWARENESS) += libintl.h HEADERS_RM-$(UCLIBC_HAS_GLIBC_CUSTOM_PRINTF) += printf.h HEADERS_RM-$(UCLIBC_HAS_GLOB) += glob.h HEADERS_RM-$(UCLIBC_HAS_GNU_ERROR) += error.h -HEADERS_RM-$(UCLIBC_HAS_GNU_GETOPT)$(UCLIBC_HAS_GETOPT_LONG) += getopt.h +HEADERS_RM-$(UCLIBC_HAS_GETOPT_LONG) += getopt.h HEADERS_RM-$(UCLIBC_HAS_IPV6) += netinet/ip6.h netinet/icmp6.h HEADERS_RM-$(UCLIBC_HAS_BACKTRACE) += execinfo.h HEADERS_RM-$(UCLIBC_HAS_LOCALE) += iconv.h bits/uClibc_ctype.h diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 00480e9eb..8e603b2ad 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1893,25 +1893,25 @@ config UCLIBC_HAS_GNU_GETOPT help Answer Y if you want to include full gnu getopt() instead of a (much smaller) SUSv3 compatible getopt(). + Note that getopt_long, getopt_long_only as well as getsubopt + are implemented on top of this choice. Most people will answer Y. config UCLIBC_HAS_GETOPT_LONG - bool "Support getopt_long/getopt_long_only" - depends on !UCLIBC_HAS_GNU_GETOPT + bool "Support getopt_long/getopt_long_only (glibc-compat)" default y help - Answer Y if you want to include getopt_long[_only() used by many - apps, even busybox. + Answer Y if you want to include getopt_long[_only()] used by many + apps. Most people will answer Y. config UCLIBC_HAS_GNU_GETSUBOPT - bool "Support glibc getsubopt" + bool "Support getsubopt" default y help - Answer Y if you want to include glibc getsubopt() instead of a - smaller SUSv3 compatible getsubopt(). + Answer Y if you want to include getsubopt(). Most people will answer Y. endmenu diff --git a/extra/config/conf.c b/extra/config/conf.c index db0905319..b24c1c355 100644 --- a/extra/config/conf.c +++ b/extra/config/conf.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -447,7 +446,7 @@ static void check_conf(struct menu *menu) } #if 00 // || !defined __UCLIBC__ || \ - (defined UCLIBC_HAS_GETOPT_LONG || defined UCLIBC_HAS_GNU_GETOPT) + defined __UCLIBC_HAS_GETOPT_LONG__ static struct option long_opts[] = { {"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldconfig", no_argument, NULL, oldconfig}, @@ -526,7 +525,7 @@ int main(int ac, char **av) tty_stdio = isatty(0) && isatty(1) && isatty(2); #if 00// !defined __UCLIBC__ || \ - (defined UCLIBC_HAS_GETOPT_LONG || defined UCLIBC_HAS_GNU_GETOPT) + defined __UCLIBC_HAS_GETOPT_LONG__ while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) #else char *gch = "asonymArDSld"; diff --git a/include/getopt.h b/include/getopt.h index a682f9ca8..de9da2686 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -1,4 +1,4 @@ -/* This file will not be installed if not using gnu getopt. */ +/* This file will not be installed if not using getopt_long. */ #include diff --git a/libc/sysdeps/linux/common/bits/getopt.h b/libc/sysdeps/linux/common/bits/getopt.h index a49f023ce..dababe07d 100644 --- a/libc/sysdeps/linux/common/bits/getopt.h +++ b/libc/sysdeps/linux/common/bits/getopt.h @@ -126,7 +126,7 @@ extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) __THROW; libc_hidden_proto(getopt) -#if defined __UCLIBC_HAS_GNU_GETOPT__ || defined __UCLIBC_HAS_GETOPT_LONG__ +#if defined __UCLIBC_HAS_GETOPT_LONG__ #ifndef __need_getopt extern int getopt_long (int ___argc, char *const *___argv, const char *__shortopts, diff --git a/libc/unistd/Makefile.in b/libc/unistd/Makefile.in index b15d60a16..659008d4d 100644 --- a/libc/unistd/Makefile.in +++ b/libc/unistd/Makefile.in @@ -16,10 +16,16 @@ OMIT-$(ARCH_USE_MMU) += __exec_alloc.c OMIT-$(if $(UCLIBC_SUSV3_LEGACY),,y) += ualarm.c usleep.c #OMIT-$(UCLIBC_HAS_THREADS_NATIVE) += sleep.c -# XXX: GNU_GETOPT comes with getopt_long unconditionally, which is wrong -GO_LONG := $(if $(UCLIBC_HAS_GNU_GETOPT),getopt_long-simple.c) -OMIT-y += $(if $(UCLIBC_HAS_GNU_GETOPT),getopt-susv3.c $(GO_LONG),getopt.c) -OMIT-y += $(if $(UCLIBC_HAS_GNU_GETSUBOPT),getsubopt-susv3.c,getsubopt.c) +ifeq ($(UCLIBC_HAS_GNU_GETOPT),y) +# GNU getopt family +OMIT-y += getopt-susv3.c getopt_long-simple.c getsubopt-susv3.c +OMIT-y += $(if $(UCLIBC_HAS_GNU_GETSUBOPT),,getsubopt.c) +else +# SuS getopt family +OMIT-y += getopt.c getsubopt.c +OMIT-y += $(if $(UCLIBC_HAS_GETOPT_LONG),,getopt_long-simple.c) +OMIT-y += $(if $(UCLIBC_HAS_GNU_GETSUBOPT),,getsubopt-susv3.c) +endif CSRC-y := $(filter-out $(OMIT-y),$(CSRC-y)) diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c index 3944c7c1f..f63482bc8 100644 --- a/libc/unistd/getopt.c +++ b/libc/unistd/getopt.c @@ -1162,6 +1162,7 @@ getopt (int argc, char *const *argv, const char *optstring) } libc_hidden_def(getopt) +#if defined __UCLIBC_HAS_GETOPT_LONG__ int getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index) @@ -1180,5 +1181,6 @@ getopt_long_only (int argc, char *const *argv, const char *options, { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } +#endif /* __UCLIBC_HAS_GETOPT_LONG__ */ #endif /* Not ELIDE_CODE. */ diff --git a/test/nptl/tst-cancel7.c b/test/nptl/tst-cancel7.c index 3bdfa9fa6..fe543f73f 100644 --- a/test/nptl/tst-cancel7.c +++ b/test/nptl/tst-cancel7.c @@ -196,13 +196,16 @@ do_cleanup (void) #define OPT_COMMAND 10000 #define OPT_PIDFILE 10001 #define CMDLINE_OPTIONS \ + "c:p:" +/* { "command", required_argument, NULL, OPT_COMMAND }, \ { "pidfile", required_argument, NULL, OPT_PIDFILE }, +*/ #define CMDLINE_PROCESS \ - case OPT_COMMAND: \ + case 'c': \ command = optarg; \ break; \ - case OPT_PIDFILE: \ + case 'p': \ pidfile = optarg; \ break; // #define CLEANUP_HANDLER do_cleanup () diff --git a/test/nptl/tst-mqueue7.c b/test/nptl/tst-mqueue7.c index e8d53ad83..01d7cd7d6 100644 --- a/test/nptl/tst-mqueue7.c +++ b/test/nptl/tst-mqueue7.c @@ -32,10 +32,12 @@ static mqd_t after_exec = (mqd_t) -1; #define CMDLINE_OPTIONS \ + "a:" +/* { "after-exec", required_argument, NULL, OPT_AFTEREXEC }, - +*/ #define CMDLINE_PROCESS \ - case OPT_AFTEREXEC: \ + case 'a': \ after_exec = (mqd_t) strtoul (optarg, NULL, 0); \ break; diff --git a/test/test-skeleton.c b/test/test-skeleton.c index 6d4a8b636..743339f8d 100644 --- a/test/test-skeleton.c +++ b/test/test-skeleton.c @@ -18,7 +18,6 @@ . */ #include -#include #include #include #include @@ -46,6 +45,7 @@ #define OPT_DIRECT 1000 #define OPT_TESTDIR 1001 +#if 0 /* Not used in uClibc */ static struct option options[] = { #ifdef CMDLINE_OPTIONS @@ -55,6 +55,7 @@ static struct option options[] = { "test-dir", required_argument, NULL, OPT_TESTDIR }, { NULL, 0, NULL, 0 } }; +#endif /* PID of the test itself. */ static pid_t pid; @@ -234,7 +235,14 @@ main (int argc, char *argv[]) setbuf (stdout, NULL); #endif +#if 0 /* Not used in uClibc */ while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1) +#else +# ifndef CMDLINE_OPTIONS +# define CMDLINE_OPTIONS "" +# endif + while ((opt = getopt (argc, argv, "+" CMDLINE_OPTIONS)) >= 0) +#endif switch (opt) { case '?': -- cgit v1.2.3 From f8e05f3850e51673522216f23533bf7146359dcd Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Mon, 15 Dec 2014 16:13:01 +0100 Subject: stdio: Fix printing 0.0 We were relying on FE_DIVBYZERO being turned off when printing "%f", +-.0 Avoid the whole issue by looking at the sign-bit (in a rough approximation). Note that we do not handle gracefully: printf ("\n%llf\n", -0.0); printf ("\n%llf\n", 0.0); nor %Lf for both when NOT cast to long double. Avoiding an FPE due to broken numbers like these does not make sense to me. Signed-off-by: Bernhard Reutner-Fischer --- libc/stdio/_fpmaxtostr.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c index f7ea792c4..35805844a 100644 --- a/libc/stdio/_fpmaxtostr.c +++ b/libc/stdio/_fpmaxtostr.c @@ -45,11 +45,6 @@ */ #define isnan(x) ((x) != (x)) -/* Without seminumerical functions to examine the sign bit, this is - * about the best we can do to test for '-0'. - */ -#define zeroisnegative(x) ((1./(x)) < 0) - /*****************************************************************************/ /* Don't change anything that follows peroid!!! ;-) */ /*****************************************************************************/ @@ -262,7 +257,13 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, if (x == 0) { /* Handle 0 now to avoid false positive. */ #ifdef __UCLIBC_HAVE_SIGNED_ZERO__ - if (zeroisnegative(x)) { /* Handle 'signed' zero. */ + union { + double x; + struct { + unsigned int l1, l2; + } i; + } u = {x}; + if (u.i.l1 ^ u.i.l2) { /* Handle 'signed' zero. */ *sign_str = '-'; } #endif /* __UCLIBC_HAVE_SIGNED_ZERO__ */ -- cgit v1.2.3 From bff3a664e6a2a367bf159c3089df1fe6f093bfb1 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Mon, 15 Dec 2014 17:32:57 +0100 Subject: test: Some more tests under conditionals Signed-off-by: Bernhard Reutner-Fischer --- test/Rules.mak | 3 +++ test/misc/Makefile.in | 8 ++++++++ test/misc/bug-glob2.c | 1 - test/misc/tst-inotify.c | 7 +++---- test/misc/tst-utmp.c | 45 +++++++++++++++++++++++++-------------------- test/pwd_grp/getgroups.c | 11 ++++++----- test/test-skeleton.c | 7 +++++++ 7 files changed, 52 insertions(+), 30 deletions(-) diff --git a/test/Rules.mak b/test/Rules.mak index ed72db246..805a3498d 100644 --- a/test/Rules.mak +++ b/test/Rules.mak @@ -78,6 +78,9 @@ CFLAGS := -nostdinc -I$(top_builddir)$(LOCAL_INSTALL_PATH)/usr/include CFLAGS += $(XCOMMON_CFLAGS) $(KERNEL_INCLUDES) $(CC_INC) CFLAGS += $(OPTIMIZATION) $(CPU_CFLAGS) $(XWARNINGS) +$(eval $(call check-gcc-var,-Wno-missing-field-initializers)) +CFLAGS += $(CFLAG_-Wno-missing-field-initializers) + # Can't add $(OPTIMIZATION) here, it may be target-specific. # Just adding -Os for now. HOST_CFLAGS += $(XCOMMON_CFLAGS) -Os $(XWARNINGS) -std=gnu99 diff --git a/test/misc/Makefile.in b/test/misc/Makefile.in index 52a3e7164..1e0da6f43 100644 --- a/test/misc/Makefile.in +++ b/test/misc/Makefile.in @@ -8,6 +8,14 @@ TESTS_DISABLED += tst-statfs # assuming host has LFS on endif CFLAGS_dirent64 := -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +ifeq ($(UCLIBC_LINUX_SPECIFIC),) +TESTS_DISABLED += tst-inotify +endif + +ifeq ($(UCLIBC_HAS_GLOB),) +TESTS_DISABLED += bug-glob2 +endif + DODIFF_dirent := 1 DODIFF_dirent64 := 1 DODIFF_tst-statfs := 1 diff --git a/test/misc/bug-glob2.c b/test/misc/bug-glob2.c index 98e3bf737..069891b03 100644 --- a/test/misc/bug-glob2.c +++ b/test/misc/bug-glob2.c @@ -18,7 +18,6 @@ . */ #include -#include #include #include #include diff --git a/test/misc/tst-inotify.c b/test/misc/tst-inotify.c index 9d940f7fd..f9f6830e3 100644 --- a/test/misc/tst-inotify.c +++ b/test/misc/tst-inotify.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,7 @@ do_test(void) /* nonblocking inotify should return immediately with no events */ ret = read(ifd, &e, sizeof(e)); if (ret != -1 || errno != EAGAIN) { - error(0, 0, "first read() returned %d", ret); + fprintf(stderr, "first read() returned %d\n", ret); result = 1; } @@ -49,12 +48,12 @@ do_test(void) /* now check whether our event was seen */ ret = read(ifd, &e, sizeof(e)); if (ret != sizeof(e)) { - error(0, 0, "second read() returned %d", ret); + fprintf(stderr, "second read() returned %d\n", ret); result = 1; } if (!(e.mask & IN_DELETE_SELF)) { - error(0, 0, "incorrect event mask: %" PRIx32, e.mask); + fprintf(stderr, "incorrect event mask: %" PRIx32 "\n", e.mask); result = 1; } diff --git a/test/misc/tst-utmp.c b/test/misc/tst-utmp.c index ca92cf210..08a6f8ea3 100644 --- a/test/misc/tst-utmp.c +++ b/test/misc/tst-utmp.c @@ -18,7 +18,6 @@ . */ #include -#include #include #include #include @@ -69,8 +68,11 @@ do_prepare (int argc, char *argv[]) /* Open our test file. */ fd = mkstemp (name); - if (fd == -1) - error (EXIT_FAILURE, errno, "cannot open test file `%s'", name); + if (fd == -1) { + fprintf (stderr, "cannot open test file `%s': ", name); + perror (NULL); + exit (EXIT_FAILURE); + } } struct utmp entry[] = @@ -110,7 +112,7 @@ do_init (void) { if (pututline (&entry[n]) == NULL) { - error (0, errno, "cannot write UTMP entry"); + perror ("cannot write UTMP entry"); return 1; } } @@ -135,7 +137,7 @@ do_check (void) if (n < num_entries && memcmp (ut, &entry[n], sizeof (struct utmp))) { - error (0, 0, "UTMP entry does not match"); + fprintf (stderr, "UTMP entry does not match\n"); return 1; } @@ -144,7 +146,7 @@ do_check (void) if (n != num_entries) { - error (0, 0, "number of UTMP entries is incorrect"); + fprintf (stderr, "number of UTMP entries is incorrect\n"); return 1; } @@ -176,7 +178,7 @@ simulate_login (const char *line, const char *user) if (pututline (&entry[n]) == NULL) { - error (0, errno, "cannot write UTMP entry"); + perror ("cannot write UTMP entry"); return 1; } @@ -186,7 +188,7 @@ simulate_login (const char *line, const char *user) } } - error (0, 0, "no entries available"); + fprintf (stderr, "no entries available\n"); return 1; } @@ -210,7 +212,7 @@ simulate_logout (const char *line) if (pututline (&entry[n]) == NULL) { - error (0, errno, "cannot write UTMP entry"); + perror ("cannot write UTMP entry"); return 1; } @@ -220,7 +222,7 @@ simulate_logout (const char *line) } } - error (0, 0, "no entry found for `%s'", line); + fprintf (stderr, "no entry found for `%s'\n", line); return 1; } @@ -237,7 +239,8 @@ check_login (const char *line) up = getutline (&ut); if (up == NULL) { - error (0, errno, "cannot get entry for line `%s'", line); + fprintf (stderr, "cannot get entry for line `%s': ", line); + perror(NULL); return 1; } @@ -249,7 +252,7 @@ check_login (const char *line) { if (memcmp (up, &entry[n], sizeof (struct utmp))) { - error (0, 0, "UTMP entry does not match"); + fprintf (stderr, "UTMP entry does not match\n"); return 1; } @@ -257,7 +260,7 @@ check_login (const char *line) } } - error (0, 0, "bogus entry for line `%s'", line); + fprintf (stderr, "bogus entry for line `%s'\n", line); return 1; } @@ -271,7 +274,7 @@ check_logout (const char *line) strcpy (ut.ut_line, line); if (getutline (&ut) != NULL) { - error (0, 0, "bogus login entry for `%s'", line); + fprintf (stderr, "bogus login entry for `%s'\n", line); return 1; } @@ -294,7 +297,8 @@ check_id (const char *id) up = getutid (&ut); if (up == NULL) { - error (0, errno, "cannot get entry for ID `%s'", id); + fprintf (stderr, "cannot get entry for ID `%s': ", id); + perror (NULL); return 1; } @@ -306,7 +310,7 @@ check_id (const char *id) { if (memcmp (up, &entry[n], sizeof (struct utmp))) { - error (0, 0, "UTMP entry does not match"); + fprintf (stderr, "UTMP entry does not match\n"); return 1; } @@ -314,7 +318,7 @@ check_id (const char *id) } } - error (0, 0, "bogus entry for ID `%s'", id); + fprintf (stderr, "bogus entry for ID `%s'\n", id); return 1; } @@ -331,7 +335,8 @@ check_type (int type) up = getutid (&ut); if (up == NULL) { - error (0, errno, "cannot get entry for type `%d'", type); + fprintf (stderr, "cannot get entry for type `%d': ", type); + perror (NULL); return 1; } @@ -343,7 +348,7 @@ check_type (int type) { if (memcmp (up, &entry[n], sizeof (struct utmp))) { - error (0, 0, "UTMP entry does not match"); + fprintf (stderr, "UTMP entry does not match\n"); return 1; } @@ -351,7 +356,7 @@ check_type (int type) } } - error (0, 0, "bogus entry for type `%d'", type); + fprintf (stderr, "bogus entry for type `%d'\n", type); return 1; } diff --git a/test/pwd_grp/getgroups.c b/test/pwd_grp/getgroups.c index 5769b180b..c34355215 100644 --- a/test/pwd_grp/getgroups.c +++ b/test/pwd_grp/getgroups.c @@ -13,7 +13,6 @@ #include #include #include -#include /* The number of errors encountered so far. */ static int problems = 0; @@ -25,7 +24,7 @@ static void print_group(gid_t gid) grp = getgrgid(gid); if (grp == NULL) { - warn("cannot find name for group ID %u", gid); + fprintf(stderr, "cannot find name for group ID %u\n", gid); problems++; } @@ -46,12 +45,14 @@ static int xgetgroups(gid_t gid, int *n_groups, gid_t ** groups) /* Add 1 just in case max_n_groups is zero. */ g = (gid_t *) malloc(max_n_groups * sizeof(gid_t) + 1); - if (g == NULL) - err(EXIT_FAILURE, "out of memory"); + if (g == NULL) { + fprintf(stderr, "out of memory\n"); + exit(EXIT_FAILURE); + } ng = getgroups(max_n_groups, g); if (ng < 0) { - warn("cannot get supplemental group list"); + fprintf(stderr, "cannot get supplemental group list\n"); ++fail; free(g); } diff --git a/test/test-skeleton.c b/test/test-skeleton.c index 743339f8d..69ef99f76 100644 --- a/test/test-skeleton.c +++ b/test/test-skeleton.c @@ -145,7 +145,9 @@ signal_handler (int sig __attribute__ ((unused))) /* Wait for it to terminate. */ for (i = 0; i < 5; ++i) { +#ifdef __UCLIBC_HAS_REALTIME__ struct timespec ts; +#endif killed = waitpid (pid, &status, WNOHANG|WUNTRACED); if (killed != 0) break; @@ -154,9 +156,14 @@ signal_handler (int sig __attribute__ ((unused))) nanosleep() call return prematurely, all the better. We won't restart it since this probably means the child process finally died. */ +#ifdef __UCLIBC_HAS_REALTIME__ ts.tv_sec = 0; ts.tv_nsec = 100000000; nanosleep (&ts, NULL); +#else + /* No nanosleep, just sleep 1s instead of 0.1s */ + sleep(1); +#endif } if (killed != 0 && killed != pid) { -- cgit v1.2.3 From 638a23483b40c5b606ee323e6612e7e454e5154b Mon Sep 17 00:00:00 2001 From: "Anthony G. Basile" Date: Mon, 27 Oct 2014 16:13:34 -0400 Subject: mkostemp: fix implementation mkostemp(char *template, int flags) generates a unique temporary filename from a template. The flags parameter accepts three of the same flags as open(2): O_APPEND, O_CLOEXEC, and O_SYNC. The current implementation of mkostemp(3) does not respect the flags and in fact confuses the flags with the file mode which should always be S_IRUSR | S_IWUSR. This patch corrects this issue. Signed-off-by: Anthony G. Basile Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/getaddrinfo.c | 2 +- libc/misc/internals/tempname.c | 6 ++--- libc/misc/internals/tempname.h | 2 +- libc/stdio/tempnam.c | 2 +- libc/stdio/tmpfile.c | 2 +- libc/stdio/tmpnam.c | 2 +- libc/stdio/tmpnam_r.c | 2 +- libc/stdlib/mkdtemp.c | 2 +- libc/stdlib/mkostemp.c | 4 +++- libc/stdlib/mkostemp64.c | 2 +- libc/stdlib/mkstemp.c | 2 +- libc/stdlib/mkstemp64.c | 2 +- libc/stdlib/mktemp.c | 2 +- libpthread/nptl/sem_open.c | 2 +- test/.gitignore | 2 ++ test/stdlib/test-mkostemp-O_CLOEXEC.c | 45 +++++++++++++++++++++++++++++++++++ test/stdlib/test-mkostemp-child.c | 22 +++++++++++++++++ 17 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 test/stdlib/test-mkostemp-O_CLOEXEC.c create mode 100644 test/stdlib/test-mkostemp-child.c diff --git a/libc/inet/getaddrinfo.c b/libc/inet/getaddrinfo.c index b61d69c0e..168adb115 100644 --- a/libc/inet/getaddrinfo.c +++ b/libc/inet/getaddrinfo.c @@ -308,7 +308,7 @@ gaih_local(const char *name, const struct gaih_service *service, char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path; if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0 - || __gen_tempname(buf, __GT_NOCREATE, 0) != 0 + || __gen_tempname(buf, __GT_NOCREATE, 0, 0) != 0 ) { return -EAI_SYSTEM; } diff --git a/libc/misc/internals/tempname.c b/libc/misc/internals/tempname.c index 18fd823c1..edcc31c1a 100644 --- a/libc/misc/internals/tempname.c +++ b/libc/misc/internals/tempname.c @@ -177,7 +177,7 @@ static void brain_damaged_fillrand(unsigned char *buf, unsigned int len) __GT_DIR: create a directory with given mode. */ -int attribute_hidden __gen_tempname (char *tmpl, int kind, mode_t mode) +int attribute_hidden __gen_tempname (char *tmpl, int kind, int flags, mode_t mode) { char *XXXXXX; unsigned int i; @@ -219,11 +219,11 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind, mode_t mode) fd = 0; } case __GT_FILE: - fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, mode); + fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode); break; #if defined __UCLIBC_HAS_LFS__ case __GT_BIGFILE: - fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, mode); + fd = open64 (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode); break; #endif case __GT_DIR: diff --git a/libc/misc/internals/tempname.h b/libc/misc/internals/tempname.h index e75b632d8..edfe26d8c 100644 --- a/libc/misc/internals/tempname.h +++ b/libc/misc/internals/tempname.h @@ -10,7 +10,7 @@ extern int ___path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx /*, int try_tmpdir */) attribute_hidden; #define __path_search(tmpl, tmpl_len, dir, pfx, try_tmpdir) ___path_search(tmpl, tmpl_len, dir, pfx) -extern int __gen_tempname (char *__tmpl, int __kind, mode_t mode) attribute_hidden; +extern int __gen_tempname (char *__tmpl, int __kind, int flags, mode_t mode) attribute_hidden; /* The __kind argument to __gen_tempname may be one of: */ #define __GT_FILE 0 /* create a file */ diff --git a/libc/stdio/tempnam.c b/libc/stdio/tempnam.c index 232ed02c5..74bb26ed5 100644 --- a/libc/stdio/tempnam.c +++ b/libc/stdio/tempnam.c @@ -35,7 +35,7 @@ tempnam (const char *dir, const char *pfx) if (__path_search (buf, FILENAME_MAX, dir, pfx, 1)) return NULL; - if (__gen_tempname (buf, __GT_NOCREATE, 0)) + if (__gen_tempname (buf, __GT_NOCREATE, 0, 0)) return NULL; return strdup (buf); diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index a9bf4743a..83c85b53d 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -35,7 +35,7 @@ FILE * tmpfile (void) if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) return NULL; - fd = __gen_tempname (buf, __GT_FILE, S_IRUSR | S_IWUSR); + fd = __gen_tempname (buf, __GT_FILE, 0, S_IRUSR | S_IWUSR); if (fd < 0) return NULL; diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c index 88b9bff1f..ffed862c1 100644 --- a/libc/stdio/tmpnam.c +++ b/libc/stdio/tmpnam.c @@ -40,7 +40,7 @@ tmpnam (char *s) 0)) return NULL; - if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0), 0)) + if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE, 0, 0), 0)) return NULL; if (s == NULL) diff --git a/libc/stdio/tmpnam_r.c b/libc/stdio/tmpnam_r.c index 8cde84d7a..bfd60a437 100644 --- a/libc/stdio/tmpnam_r.c +++ b/libc/stdio/tmpnam_r.c @@ -27,7 +27,7 @@ char * tmpnam_r (char *s) if (__path_search (s, L_tmpnam, NULL, NULL, 0)) return NULL; - if (__gen_tempname (s, __GT_NOCREATE, 0)) + if (__gen_tempname (s, __GT_NOCREATE, 0, 0)) return NULL; return s; diff --git a/libc/stdlib/mkdtemp.c b/libc/stdlib/mkdtemp.c index da7598a6f..e6d4a364c 100644 --- a/libc/stdlib/mkdtemp.c +++ b/libc/stdlib/mkdtemp.c @@ -29,7 +29,7 @@ (This function comes from OpenBSD.) */ char * mkdtemp (char *template) { - if (__gen_tempname (template, __GT_DIR, S_IRUSR | S_IWUSR | S_IXUSR)) + if (__gen_tempname (template, __GT_DIR, 0, S_IRUSR | S_IWUSR | S_IXUSR)) return NULL; else return template; diff --git a/libc/stdlib/mkostemp.c b/libc/stdlib/mkostemp.c index 0369235dc..912be30a6 100644 --- a/libc/stdlib/mkostemp.c +++ b/libc/stdlib/mkostemp.c @@ -17,6 +17,7 @@ #include #include +#include #include "../misc/internals/tempname.h" /* Generate a unique temporary file name from TEMPLATE. @@ -26,5 +27,6 @@ int mkostemp (char *template, int flags) { - return __gen_tempname (template, __GT_FILE, flags); + flags -= flags & O_ACCMODE; /* Remove O_RDONLY, O_WRONLY, and O_RDWR. */ + return __gen_tempname (template, __GT_FILE, flags, S_IRUSR | S_IWUSR); } diff --git a/libc/stdlib/mkostemp64.c b/libc/stdlib/mkostemp64.c index d21def58a..c6d6d849d 100644 --- a/libc/stdlib/mkostemp64.c +++ b/libc/stdlib/mkostemp64.c @@ -27,5 +27,5 @@ int mkostemp64 (char *template, int flags) { - return __gen_tempname (template, __GT_BIGFILE, flags | O_LARGEFILE); + return __gen_tempname (template, __GT_BIGFILE, flags | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IXUSR); } diff --git a/libc/stdlib/mkstemp.c b/libc/stdlib/mkstemp.c index 61c717511..a3a159590 100644 --- a/libc/stdlib/mkstemp.c +++ b/libc/stdlib/mkstemp.c @@ -26,5 +26,5 @@ Then open the file and return a fd. */ int mkstemp (char *template) { - return __gen_tempname (template, __GT_FILE, S_IRUSR | S_IWUSR); + return __gen_tempname (template, __GT_FILE, 0, S_IRUSR | S_IWUSR); } diff --git a/libc/stdlib/mkstemp64.c b/libc/stdlib/mkstemp64.c index e29be2da4..6f2ee3e83 100644 --- a/libc/stdlib/mkstemp64.c +++ b/libc/stdlib/mkstemp64.c @@ -26,5 +26,5 @@ Then open the file and return a fd. */ int mkstemp64 (char *template) { - return __gen_tempname (template, __GT_BIGFILE, S_IRUSR | S_IWUSR); + return __gen_tempname (template, __GT_BIGFILE, 0, S_IRUSR | S_IWUSR); } diff --git a/libc/stdlib/mktemp.c b/libc/stdlib/mktemp.c index edd001d49..1ff93da3c 100644 --- a/libc/stdlib/mktemp.c +++ b/libc/stdlib/mktemp.c @@ -24,7 +24,7 @@ * they are replaced with a string that makes the filename unique. */ char *mktemp(char *template) { - if (__gen_tempname (template, __GT_NOCREATE, 0) < 0) + if (__gen_tempname (template, __GT_NOCREATE, 0, 0) < 0) /* We return the null string if we can't find a unique file name. */ template[0] = '\0'; diff --git a/libpthread/nptl/sem_open.c b/libpthread/nptl/sem_open.c index 1b3616439..3a7207908 100644 --- a/libpthread/nptl/sem_open.c +++ b/libpthread/nptl/sem_open.c @@ -336,7 +336,7 @@ sem_open (const char *name, int oflag, ...) mempcpy (mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen), "XXXXXX", 7); - fd = __gen_tempname (tmpfname, __GT_FILE, mode); + fd = __gen_tempname (tmpfname, __GT_FILE, 0, mode); if (fd == -1) return SEM_FAILED; diff --git a/test/.gitignore b/test/.gitignore index 8f3203190..5944f0a0f 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -274,6 +274,8 @@ stdlib/testarc4random stdlib/testatexit stdlib/test-canon stdlib/test-canon2 +stdlib/test-mkostemp-O_CLOEXEC +stdlib/test-mkostemp-child stdlib/teston_exit stdlib/teststrtol stdlib/teststrtoq diff --git a/test/stdlib/test-mkostemp-O_CLOEXEC.c b/test/stdlib/test-mkostemp-O_CLOEXEC.c new file mode 100644 index 000000000..9ff229af1 --- /dev/null +++ b/test/stdlib/test-mkostemp-O_CLOEXEC.c @@ -0,0 +1,45 @@ +#define _XOPEN_SOURCE_EXTENDED +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined __ARCH_USE_MMU__ +# define fork vfork +#endif + +int main(int argc, char *argv[]) { + int fd, status; + char buff[5]; + char template[] = "/tmp/test-mkostemp.XXXXXX"; + + fd = mkostemp(template, O_CLOEXEC); + unlink(template); + + snprintf(buff, 5, "%d", fd); + + if(!fork()) + if(execl("./test-mkostemp-child", "test-mkostemp-child", buff, NULL) == -1) + exit(EXIT_FAILURE); + + wait(&status); + + memset(buff, 0, 5); + lseek(fd, 0, SEEK_SET); + errno = 0; + if(read(fd, buff, 5) == -1) + exit(EXIT_FAILURE); + + if(!strncmp(buff, "test", 5)) + exit(EXIT_FAILURE); + else + exit(EXIT_SUCCESS); + + close(fd); + exit(EXIT_SUCCESS); +} diff --git a/test/stdlib/test-mkostemp-child.c b/test/stdlib/test-mkostemp-child.c new file mode 100644 index 000000000..708bd80a1 --- /dev/null +++ b/test/stdlib/test-mkostemp-child.c @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) { + int fd; + + /* This file gets built and run as a test, but its + * really just a helper for test-mkostemp-O_CLOEXEC.c. + * So, we'll always return succcess. + */ + if(argc != 2) + exit(EXIT_SUCCESS); + + sscanf(argv[1], "%d", &fd); + + if(write(fd, "test\0", 5) == -1) + ; /* Don't Panic! Failure is okay here. */ + + close(fd); + exit(EXIT_SUCCESS); +} -- cgit v1.2.3