From 2514e7d5af226b15be3f737286b3ff8c0c91d761 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 22 May 2009 13:48:52 +0200 Subject: [PATCH] Simplify use of mode_t varargs. --- ChangeLog | 16 ++++++++++++++++ lib/open-safer.c | 12 ++++-------- lib/open.c | 11 ++++------- lib/openat.c | 11 ++++------- m4/fcntl-safer.m4 | 6 ++++-- m4/mode_t.m4 | 26 ++++++++++++++++++++++++++ m4/open.m4 | 3 ++- m4/openat.m4 | 3 ++- modules/fcntl-safer | 1 + modules/open | 1 + modules/openat | 1 + 11 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 m4/mode_t.m4 diff --git a/ChangeLog b/ChangeLog index 32f6c6bb0..a731f0169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2009-05-21 Bruno Haible + + 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 * doc/glibc-functions/fallocate.texi: New file. diff --git a/lib/open-safer.c b/lib/open-safer.c index 15bf6a65d..48d558fa5 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 13af27460..326e6d15c 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 0c3267221..77a85bffe 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 3475b0a7c..e2080dfa5 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 000000000..a4dd694d0 --- /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 . + +# 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 ], + [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 6e286c96e..3202886aa 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 10eac5c12..daa6a539e 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 937b54f2a..253b76b44 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 f792adf1a..e89efde20 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 f0c70b145..561687d9d 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 -- 2.11.0