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. --- libc/sysdeps/linux/common/bits/getopt.h | 2 +- libc/unistd/Makefile.in | 14 ++++++++++---- libc/unistd/getopt.c | 2 ++ 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'libc') 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. */ -- 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(-) (limited to 'libc') 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 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 +- 13 files changed, 17 insertions(+), 15 deletions(-) (limited to 'libc') 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'; -- cgit v1.2.3