diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | lib/open-safer.c | 12 | ||||
-rw-r--r-- | lib/open.c | 11 | ||||
-rw-r--r-- | lib/openat.c | 11 | ||||
-rw-r--r-- | m4/fcntl-safer.m4 | 6 | ||||
-rw-r--r-- | m4/mode_t.m4 | 26 | ||||
-rw-r--r-- | m4/open.m4 | 3 | ||||
-rw-r--r-- | m4/openat.m4 | 3 | ||||
-rw-r--r-- | modules/fcntl-safer | 1 | ||||
-rw-r--r-- | modules/open | 1 | ||||
-rw-r--r-- | modules/openat | 1 |
11 files changed, 65 insertions, 26 deletions
@@ -1,3 +1,19 @@ +2009-05-21 Bruno Haible <bruno@clisp.org> + + Simplify use of mode_t varargs. + * lib/open.c (open): Use PROMOTED_MODE_T instead of a conditional that + uses 'mode_t' or 'int'. + * lib/openat.c (openat): Likewise. + * lib/open-safer.c (open_safer): Likewise. + * m4/mode_t.m4: New file. + * m4/open.m4 (gl_PREREQ_OPEN): Require gl_PROMOTED_TYPE_MODE_T. + * m4/openat.m4 (gl_PREREQ_OPENAT): Likewise. + * m4/fcntl-safer.m4 (gl_FCNTL_SAFER): Likewise. + * modules/open (Files): Add m4/mode_t.m4. + * modules/openat (Files): Likewise. + * modules/fcntl-safer (Files): Likewise. + Suggested by Eric Blake. + 2009-05-21 Pádraig Brady <P@draigbrady.com> * doc/glibc-functions/fallocate.texi: New file. diff --git a/lib/open-safer.c b/lib/open-safer.c index 15bf6a65d0..48d558fa57 100644 --- a/lib/open-safer.c +++ b/lib/open-safer.c @@ -1,6 +1,6 @@ /* Invoke open, but avoid some glitches. - Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2008-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,13 +35,9 @@ open_safer (char const *file, int flags, ...) va_list ap; va_start (ap, flags); - /* Assume mode_t promotes to int if and only if it is smaller. - This assumption isn't guaranteed by the C standard, but we - don't know of any real-world counterexamples. */ - if (sizeof (mode_t) < sizeof (int)) - mode = va_arg (ap, int); - else - mode = va_arg (ap, mode_t); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (ap, PROMOTED_MODE_T); va_end (ap); } diff --git a/lib/open.c b/lib/open.c index 13af274602..326e6d15c0 100644 --- a/lib/open.c +++ b/lib/open.c @@ -1,5 +1,5 @@ /* Open a descriptor to a file. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,12 +51,9 @@ open (const char *filename, int flags, ...) va_list arg; va_start (arg, flags); - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (arg, PROMOTED_MODE_T); va_end (arg); } diff --git a/lib/openat.c b/lib/openat.c index 0c32672215..77a85bffe8 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -1,5 +1,5 @@ /* provide a replacement openat function - Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,12 +47,9 @@ openat (int fd, char const *file, int flags, ...) va_list arg; va_start (arg, flags); - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (arg, PROMOTED_MODE_T); va_end (arg); } diff --git a/m4/fcntl-safer.m4 b/m4/fcntl-safer.m4 index 3475b0a7cf..e2080dfa5d 100644 --- a/m4/fcntl-safer.m4 +++ b/m4/fcntl-safer.m4 @@ -1,5 +1,5 @@ -#serial 5 -dnl Copyright (C) 2005-2007 Free Software Foundation, Inc. +#serial 6 +dnl Copyright (C) 2005-2007, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -8,4 +8,6 @@ AC_DEFUN([gl_FCNTL_SAFER], [ AC_LIBOBJ([open-safer]) AC_LIBOBJ([creat-safer]) + # Prerequisites of lib/open-safer.c. + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) ]) diff --git a/m4/mode_t.m4 b/m4/mode_t.m4 new file mode 100644 index 0000000000..a4dd694d0b --- /dev/null +++ b/m4/mode_t.m4 @@ -0,0 +1,26 @@ +# mode_t.m4 serial 1 +dnl Copyright (C) 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# For using mode_t, it's sufficient to use AC_TYPE_MODE_T and +# include <sys/types.h>. + +# Define PROMOTED_MODE_T to the type that is the result of "default argument +# promotion" (ISO C 6.5.2.2.(6)) of the type mode_t. +AC_DEFUN([gl_PROMOTED_TYPE_MODE_T], +[ + AC_REQUIRE([AC_TYPE_MODE_T]) + AC_CACHE_CHECK([for promoted mode_t type], [gl_cv_promoted_mode_t], [ + dnl Assume mode_t promotes to 'int' if and only if it is smaller than 'int', + dnl and to itself otherwise. This assumption is not guaranteed by the ISO C + dnl standard, but we don't know of any real-world counterexamples. + AC_TRY_COMPILE([#include <sys/types.h>], + [typedef int array[2 * (sizeof (mode_t) < sizeof (int)) - 1];], + [gl_cv_promoted_mode_t='int'], + [gl_cv_promoted_mode_t='mode_t']) + ]) + AC_DEFINE_UNQUOTED([PROMOTED_MODE_T], [$gl_cv_promoted_mode_t], + [Define to the type that is the result of default argument promotions of type mode_t.]) +]) diff --git a/m4/open.m4 b/m4/open.m4 index 6e286c96e8..3202886aa0 100644 --- a/m4/open.m4 +++ b/m4/open.m4 @@ -1,4 +1,4 @@ -# open.m4 serial 5 +# open.m4 serial 6 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -62,5 +62,6 @@ AC_DEFUN([gl_REPLACE_OPEN], AC_DEFUN([gl_PREREQ_OPEN], [ AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) : ]) diff --git a/m4/openat.m4 b/m4/openat.m4 index 10eac5c12e..daa6a539e1 100644 --- a/m4/openat.m4 +++ b/m4/openat.m4 @@ -1,4 +1,4 @@ -# serial 17 +# serial 18 # See if we need to use our replacement for Solaris' openat et al functions. dnl Copyright (C) 2004-2009 Free Software Foundation, Inc. @@ -87,5 +87,6 @@ AC_DEFUN([gl_FUNC_FCHOWNAT], AC_DEFUN([gl_PREREQ_OPENAT], [ + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) : ]) diff --git a/modules/fcntl-safer b/modules/fcntl-safer index 937b54f2a8..253b76b447 100644 --- a/modules/fcntl-safer +++ b/modules/fcntl-safer @@ -7,6 +7,7 @@ lib/creat-safer.c lib/fcntl-safer.h lib/open-safer.c m4/fcntl-safer.m4 +m4/mode_t.m4 Depends-on: open diff --git a/modules/open b/modules/open index f792adf1ad..e89efde20c 100644 --- a/modules/open +++ b/modules/open @@ -4,6 +4,7 @@ open() function: open a descriptor to a file. Files: lib/open.c m4/open.m4 +m4/mode_t.m4 Depends-on: fcntl diff --git a/modules/openat b/modules/openat index f0c70b145e..561687d9d0 100644 --- a/modules/openat +++ b/modules/openat @@ -12,6 +12,7 @@ lib/openat.h lib/openat-priv.h lib/openat-proc.c m4/openat.m4 +m4/mode_t.m4 Depends-on: dirname |