bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gnulib] merge from coreutils to gnulib (fd-safer, modechange, readu


From: Paul Eggert
Subject: [bug-gnulib] merge from coreutils to gnulib (fd-safer, modechange, readutmp, ...)
Date: Mon, 02 May 2005 00:05:07 -0700

I installed this patch to merge coreutils changes into gnulib.

Many of the changes have to do with avoiding the use of file
descriptors 0, 1, 2 where that is undesirable.

There are also changes to the APIs for modechange and for readutmp.


Index: ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/ChangeLog,v
retrieving revision 1.275
diff -p -u -r1.275 ChangeLog
--- ChangeLog   2 May 2005 05:29:35 -0000       1.275
+++ ChangeLog   2 May 2005 06:58:36 -0000
@@ -1,3 +1,19 @@
+2005-05-01  Paul Eggert  <address@hidden>
+
+       * modules/getloadavg (Depends-on): Add unistd-safer.
+       * modules/getusershell (Depends-on): Add stdio-safer.
+       * modules/lstat (Depends-on): Remove xalloc.
+       * modules/mkstemp (Depends-on): Add stat-macros.
+       * modules/modechange (Depends-on): Remove xstrtol.
+       Add stat-macros, xalloc.
+       * modules/save-cwd (Depends-on): Add unistd-safer.
+       * modules/stdio-safer (Makefile.am): Remove lib_SOURCES.
+       * modules/unistd-safer (Files): Add lib/fd-safer.c
+       (Makefile.am): Remove lib_SOURCES.
+
+       * MODULES.html.sh (Enhancements for POSIX:2001 functions):
+       Remove fcntl-safer; unistd-safer supersedes it.
+
 2005-05-01  Oskar Liljeblad  <address@hidden>
 
        * modules/getcwd (Depends-on): Add extensions.
Index: MODULES.html.sh
===================================================================
RCS file: /cvsroot/gnulib/gnulib/MODULES.html.sh,v
retrieving revision 1.78
diff -p -u -r1.78 MODULES.html.sh
--- MODULES.html.sh     1 May 2005 14:13:02 -0000       1.78
+++ MODULES.html.sh     2 May 2005 06:58:36 -0000
@@ -1774,7 +1774,6 @@ func_all_modules ()
   func_begin_table
   func_module dirname
   func_module getopt
-  func_module fcntl-safer
   func_module unistd-safer
   func_module fnmatch
   func_module fnmatch-posix
Index: lib/ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/ChangeLog,v
retrieving revision 1.838
diff -p -u -r1.838 ChangeLog
--- lib/ChangeLog       1 May 2005 14:13:01 -0000       1.838
+++ lib/ChangeLog       2 May 2005 06:58:37 -0000
@@ -1,3 +1,85 @@
+2005-05-01  Paul Eggert  <address@hidden>
+
+       Merge from coreutils.  Among other things,
+       add bulletproofing for cases where stdin, stdout, or stderr are closed.
+       * fd-safer.c: New file.
+       * fcntl-safer.h, open-safer.c: Remove.
+       * chdir-long.c: Fix comment "fetish" -> "coreutils".
+       * dup-safer.c: Include unistd-safer.h first.
+       Don't include errno.h.
+       (dup_safer) [!defined F_DUPFD]: Let fd_safer do the real work.
+       * file-type.h: Don't assume invoker included sys/stat.h first.
+       * file-type.c: Rely on file-type.h change.
+       * getloadavg.c: Include unistd-safer.h.
+       (getloadavg): Use safer open.
+       * getusershell.c: Include "stdio-safer.h".
+       (getusershell): Use safer fopen.
+       * long-options.c (long_options): Use NULL rather than 0.
+       * modechange.h (mode_free): Remove; all callers changed to invoke
+       'free'.
+       * modechange.c: Likewise.
+       xstrtol.h, stdbool.h, stddef.h: Don't include; no longer needed.
+       (MODE_DONE): New constant.
+       (struct mode_change): Remove 'next' member.
+       (make_node_op_equals): New function; like the old one of the
+       same name, except it allocates an array.
+       (mode_compile, mode_create_from_ref): Use it.
+       (mode_compile): Allocate result as an array, not a linked list.
+       Parse octal string ourself, so that we catch mistakes like "+0".
+       (mode_adjust): Arg is an array, not a linked list.
+       * modechange.c: Include stat-macros.h, xalloc.h.
+       (S_ISDIR, S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR):
+       (S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, S_IRXWU):
+       (S_IRWXG, S_IRWXO, CHMOD_MODE_BITS):
+       Remove.  This is now stat-macros.h's job.
+       (talloc): Remove.  All callers replaced by xalloc, so that
+       our invokers don't have to worry about reporting memory failures.
+       (make_node_op_equals): Remove.
+       (MODE_ORDINARY_CHAGE, MODE_X_IF_ANY_X, MODE_COPY_EXISTING):
+       New constants.
+       (struct mode_change): Moved here from modechange.h.
+       (mode_append_entry): Remove.
+       (mode_compile): Remove MASKED_OPS arg, since it encouraged
+       apps to have incorrect behavior.  Use simpler algorithm for head
+       and tail.  Don't futz with umask; that's now the job of mode_adjust.
+       Detect more invalid usages rather than having somewhat-random behavior.
+       Don't insert an "a=" action, as that leads to incorrect behavior.
+       (mode_compile, mode_create_from_ref): Return NULL on error instead
+       of an enum, since now there's only one way to have an error.  All
+       callers changed.
+       (mode_adjust): Accept new arg UMASK_VALUE, and interpret it
+       at the correct time.  Simplify calculation of "+u" and its ilk.
+       Don't mishandle "+X".
+       (mode_free): Remove "register" and localize decls.
+       * modechange.h (MODE_X_IF_ANY_X, MODE_COPY_EXISTING):
+       (struct mode_change): Move to modechange.c; callers don't
+       need to see this stuff.
+       (MODE_MASK_EQUALS, MODE_MASK_PLUS, MODE_MASK_MINUS, MODE_MASK_ALL):
+       (MODE_INVALID, MODE_MEMORY_EXHAUSTED, MODE_BAD_REFERENCE): Remove.
+       (mode_change, mode_adjust): Reflect the new signatures noted above.
+       * nanosleep.c (rpl_nanosleep): Include "timespec.h" before macros
+       that might redefine system include files.
+       (siginterrupt) [!HAVE_SIGINTERRUPT]: New macro.
+       (my_usleep): Use NULL rather than (void *) 0.
+       (rpl_nanosleep) [!defined SA_NOCLDSTOP]:
+       Use siginterrupt to specify that system calls should be interrupted.
+       (rpl_nanosleep): Move initialization of suspended closer to call of
+       my_usleep.
+       * readutmp.h (read_utmp): New arg OPTIONS.  All uses changed.
+       * readutmp.c: Likewise.  Include signal.h, stdbool.h.
+       (desirable_utmp_entry): New function.
+       (read_utmp) [defined UTMP_NAME_FUNCTION]: Redo memory allocation
+       using x2nrealloc, to simplify logic.
+       (read_utmp) [!defined UTMP_NAME_FUNCTION]: Check for overflow in
+       size calculation.  Do not assume utmp file is a regular file.
+       * readutmp.h (UT_PID): Moved here from ../src/who.c.
+       (READ_UTMP_CHECK_PIDS): New constant.
+       * save-cwd.c: Include unistd-safer.h.
+       (save_cwd): Use fd_safer.
+       * tempname.c (S_ISDIR, S_IRUSR, S_IRUSR, S_IWUSR, S_IXUSR): Remove.
+       [!_LIBC] Include "stat-macros.h" instead.
+       * unistd-safer.h (fd_safer): New decl.
+
 2005-05-01  Oskar Liljeblad  <address@hidden>
 
        * byteswap_.h: New file.
Index: lib/chdir-long.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/chdir-long.c,v
retrieving revision 1.3
diff -p -u -r1.3 chdir-long.c
--- lib/chdir-long.c    3 Feb 2005 20:38:14 -0000       1.3
+++ lib/chdir-long.c    2 May 2005 06:58:37 -0000
@@ -269,6 +269,6 @@ main (int argc, char *argv[])
 
 /*
 Local Variables:
-compile-command: "gcc -DTEST_CHDIR=1 -DHAVE_CONFIG_H -I.. -g -O -W -Wall 
chdir-long.c libfetish.a"
+compile-command: "gcc -DTEST_CHDIR=1 -DHAVE_CONFIG_H -I.. -g -O -W -Wall 
chdir-long.c libcoreutils.a"
 End:
 */
Index: lib/dup-safer.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/dup-safer.c,v
retrieving revision 1.2
diff -p -u -r1.2 dup-safer.c
--- lib/dup-safer.c     6 Aug 2004 05:16:49 -0000       1.2
+++ lib/dup-safer.c     2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
 /* Invoke dup, but avoid some glitches.
-   Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2004, 2005 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
@@ -21,7 +21,7 @@
 # include <config.h>
 #endif
 
-#include <errno.h>
+#include "unistd-safer.h"
 
 #if HAVE_FCNTL_H
 # include <fcntl.h>
@@ -34,8 +34,6 @@
 # define STDERR_FILENO 2
 #endif
 
-#include <unistd-safer.h>
-
 /* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
    STDERR_FILENO.  */
 
@@ -45,15 +43,8 @@ dup_safer (int fd)
 #ifdef F_DUPFD
   return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
 #else
-  int f = dup (fd);
-  if (0 <= f && f <= STDERR_FILENO)
-    {
-      int f1 = dup_safer (f);
-      int e = errno;
-      close (f);
-      errno = e;
-      f = f1;
-    }
-  return f;
+  /* fd_safer calls us back, but eventually the recursion unwinds and
+     does the right thing.  */
+  return fd_safer (dup (fd));
 #endif
 }
Index: lib/file-type.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/file-type.c,v
retrieving revision 1.6
diff -p -u -r1.6 file-type.c
--- lib/file-type.c     1 Jun 2004 20:27:21 -0000       1.6
+++ lib/file-type.c     2 May 2005 06:58:37 -0000
@@ -1,6 +1,7 @@
 /* Return a string describing the type of a file.
 
-   Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 2001, 2002, 2004, 2005 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
@@ -22,9 +23,8 @@
 # include <config.h>
 #endif
 
-#include <sys/types.h>
-#include <sys/stat.h>
 #include "file-type.h"
+
 #include "stat-macros.h"
 
 #include <gettext.h>
Index: lib/file-type.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/file-type.h,v
retrieving revision 1.7
diff -p -u -r1.7 file-type.h
--- lib/file-type.h     1 Jun 2004 20:27:21 -0000       1.7
+++ lib/file-type.h     2 May 2005 06:58:37 -0000
@@ -1,6 +1,7 @@
 /* Return a string describing the type of a file.
 
-   Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 2001, 2002, 2004, 2005 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
@@ -21,6 +22,9 @@
 #ifndef FILE_TYPE_H
 # define FILE_TYPE_H 1
 
+# include <sys/types.h>
+# include <sys/stat.h>
+
 char const *file_type (struct stat const *);
 
 #endif /* FILE_TYPE_H */
Index: lib/getloadavg.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getloadavg.c,v
retrieving revision 1.24
diff -p -u -r1.24 getloadavg.c
--- lib/getloadavg.c    9 Mar 2005 19:11:23 -0000       1.24
+++ lib/getloadavg.c    2 May 2005 06:58:37 -0000
@@ -452,6 +452,8 @@
 # else
 #  include <sys/file.h>
 # endif
+
+# include "unistd-safer.h"
 
 /* Avoid static vars inside a function since in HPUX they dump as pure.  */
 
@@ -911,7 +913,7 @@ getloadavg (double loadavg[], int nelem)
   if (!getloadavg_initialized)
     {
 #  ifndef SUNOS_5
-      channel = open ("/dev/kmem", 0);
+      channel = fd_safer (open ("/dev/kmem", O_RDONLY));
       if (channel >= 0)
        {
          /* Set the channel to close on exec, so it does not
Index: lib/getusershell.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getusershell.c,v
retrieving revision 1.19
diff -p -u -r1.19 getusershell.c
--- lib/getusershell.c  4 Oct 2004 20:17:39 -0000       1.19
+++ lib/getusershell.c  2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
 /* getusershell.c -- Return names of valid user shells.
 
-   Copyright (C) 1991, 1997, 2000, 2001, 2003, 2004 Free Software
+   Copyright (C) 1991, 1997, 2000, 2001, 2003, 2004, 2005 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+#include "stdio-safer.h"
 #include "xalloc.h"
 
 #if USE_UNLOCKED_IO
@@ -98,7 +99,7 @@ getusershell (void)
 
   if (shellstream == NULL)
     {
-      shellstream = fopen (SHELLS_FILE, "r");
+      shellstream = fopen_safer (SHELLS_FILE, "r");
       if (shellstream == NULL)
        {
          /* No shells file.  Use the default list.  */
Index: lib/long-options.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/long-options.c,v
retrieving revision 1.20
diff -p -u -r1.20 long-options.c
--- lib/long-options.c  24 Jan 2004 07:22:34 -0000      1.20
+++ lib/long-options.c  2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
 /* Utility to accept --help and --version options as unobtrusively as possible.
 
-   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2002, 2003, 2004 Free
+   Copyright (C) 1993, 1994, 1998, 1999, 2000, 2002, 2003, 2004, 2005 Free
    Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -35,9 +35,9 @@
 
 static struct option const long_options[] =
 {
-  {"help", no_argument, 0, 'h'},
-  {"version", no_argument, 0, 'v'},
-  {0, 0, 0, 0}
+  {"help", no_argument, NULL, 'h'},
+  {"version", no_argument, NULL, 'v'},
+  {NULL, 0, NULL, 0}
 };
 
 /* Process long options --help and --version, but only if argc == 2.
Index: lib/modechange.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/modechange.c,v
retrieving revision 1.28
diff -p -u -r1.28 modechange.c
--- lib/modechange.c    4 Oct 2004 04:24:47 -0000       1.28
+++ lib/modechange.c    2 May 2005 06:58:37 -0000
@@ -1,7 +1,7 @@
 /* modechange.c -- file mode manipulation
 
-   Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004 Free
-   Software Foundation, Inc.
+   Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004, 2005
+   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
@@ -19,12 +19,12 @@
 
 /* Written by David MacKenzie <address@hidden> */
 
-/* The ASCII mode string is compiled into a linked list of `struct
+/* The ASCII mode string is compiled into an array of `struct
    modechange', which can then be applied to each file to be changed.
    We do this instead of re-parsing the ASCII string for each file
    because the compiled form requires less computation to use; when
    changing the mode of many files, this probably results in a
-   performance gain. */
+   performance gain.  */
 
 #if HAVE_CONFIG_H
 # include <config.h>
@@ -32,19 +32,10 @@
 
 #include "modechange.h"
 #include <sys/stat.h>
-#include "xstrtol.h"
-#include <stdbool.h>
-#include <stddef.h>
+#include "stat-macros.h"
+#include "xalloc.h"
 #include <stdlib.h>
 
-#if STAT_MACROS_BROKEN
-# undef S_ISDIR
-#endif
-
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-
 /* The traditional octal values corresponding to each mode bit.  */
 #define SUID 04000
 #define SGID 02000
@@ -60,127 +51,78 @@
 #define XOTH 00001
 #define ALLM 07777 /* all octal mode bits */
 
-#ifndef S_ISUID
-# define S_ISUID SUID
-#endif
-#ifndef S_ISGID
-# define S_ISGID SGID
-#endif
-#ifndef S_ISVTX
-# define S_ISVTX SVTX
-#endif
-#ifndef S_IRUSR
-# define S_IRUSR RUSR
-#endif
-#ifndef S_IWUSR
-# define S_IWUSR WUSR
-#endif
-#ifndef S_IXUSR
-# define S_IXUSR XUSR
-#endif
-#ifndef S_IRGRP
-# define S_IRGRP RGRP
-#endif
-#ifndef S_IWGRP
-# define S_IWGRP WGRP
-#endif
-#ifndef S_IXGRP
-# define S_IXGRP XGRP
-#endif
-#ifndef S_IROTH
-# define S_IROTH ROTH
-#endif
-#ifndef S_IWOTH
-# define S_IWOTH WOTH
-#endif
-#ifndef S_IXOTH
-# define S_IXOTH XOTH
-#endif
-#ifndef S_IRWXU
-# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
-#endif
-#ifndef S_IRWXG
-# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
-#endif
-#ifndef S_IRWXO
-# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
-#endif
+/* Special operations flags.  */
+enum
+  {
+    /* For the sentinel at the end of the mode changes array.  */
+    MODE_DONE,
+
+    /* The typical case.  */
+    MODE_ORDINARY_CHANGE,
+
+    /* In addition to the typical case, affect the execute bits if at
+       least one execute bit is set already, or if the file is a
+       directory.  */
+    MODE_X_IF_ANY_X,
+
+    /* Instead of the typical case, copy some existing permissions for
+       u, g, or o onto the other two.  Which of u, g, or o is copied
+       is determined by which bits are set in the `value' field.  */
+    MODE_COPY_EXISTING
+  };
 
-/* All the mode bits that can be affected by chmod.  */
-#define CHMOD_MODE_BITS \
-  (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
-
-/* Return newly allocated memory to hold one element of type TYPE. */
-#define talloc(type) ((type *) malloc (sizeof (type)))
-
-/* Create a mode_change entry with the specified `=ddd'-style
-   mode change operation, where NEW_MODE is `ddd'.  Return the
-   new entry, or NULL upon failure.  */
+/* Description of a mode change.  */
+struct mode_change
+{
+  char op;                     /* One of "=+-".  */
+  char flag;                   /* Special operations flag.  */
+  mode_t affected;             /* Set for u, g, o, or a.  */
+  mode_t value;                        /* Bits to add/remove.  */
+};
+
+/* Return a mode_change array with the specified `=ddd'-style
+   mode change operation, where NEW_MODE is `ddd'.  */
 
 static struct mode_change *
 make_node_op_equals (mode_t new_mode)
 {
-  struct mode_change *p;
-  p = talloc (struct mode_change);
-  if (p == NULL)
-    return p;
-  p->next = NULL;
+  struct mode_change *p = xmalloc (2 * sizeof *p);
   p->op = '=';
-  p->flags = 0;
+  p->flag = MODE_ORDINARY_CHANGE;
+  p->affected = CHMOD_MODE_BITS;
   p->value = new_mode;
-  p->affected = CHMOD_MODE_BITS;       /* Affect all permissions. */
+  p[1].flag = MODE_DONE;
   return p;
 }
 
-/* Append entry E to the end of the link list with the specified
-   HEAD and TAIL.  */
-
-static void
-mode_append_entry (struct mode_change **head,
-                  struct mode_change **tail,
-                  struct mode_change *e)
-{
-  if (*head == NULL)
-    *head = *tail = e;
-  else
-    {
-      (*tail)->next = e;
-      *tail = e;
-    }
-}
-
-/* Return a linked list of file mode change operations created from
+/* Return a pointer to an array of file mode change operations created from
    MODE_STRING, an ASCII string that contains either an octal number
    specifying an absolute mode, or symbolic mode change operations with
    the form:
    [ugoa...][[+-=][rwxXstugo...]...][,...]
-   MASKED_OPS is a bitmask indicating which symbolic mode operators (=+-)
-   should not affect bits set in the umask when no users are given.
-   Operators not selected in MASKED_OPS ignore the umask.
-
-   Return MODE_INVALID if `mode_string' does not contain a valid
-   representation of file mode change operations;
-   return MODE_MEMORY_EXHAUSTED if there is insufficient memory. */
+
+   Return NULL if `mode_string' does not contain a valid
+   representation of file mode change operations.  */
 
 struct mode_change *
-mode_compile (const char *mode_string, unsigned int masked_ops)
+mode_compile (char const *mode_string)
 {
-  struct mode_change *head;    /* First element of the linked list. */
-  struct mode_change *tail;    /* An element of the linked list. */
-  unsigned long octal_value;   /* The mode value, if octal.  */
-  mode_t umask_value;          /* The umask value (surprise). */
-
-  head = NULL;
-#ifdef lint
-  tail = NULL;
-#endif
+  /* The array of mode-change directives to be returned.  */
+  struct mode_change *mc;
+  size_t used = 0;
 
-  if (xstrtoul (mode_string, NULL, 8, &octal_value, "") == LONGINT_OK)
+  if ('0' <= *mode_string && *mode_string < '8')
     {
-      struct mode_change *p;
       mode_t mode;
-      if (octal_value != (octal_value & ALLM))
-       return MODE_INVALID;
+      unsigned int octal_value = 0;
+
+      do
+       {
+         octal_value = 8 * octal_value + *mode_string++ - '0';
+         if (ALLM < octal_value)
+           return NULL;
+       }
+      while ('0' <= *mode_string && *mode_string < '8');
 
       /* Help the compiler optimize the usual case where mode_t uses
         the traditional octal representation.  */
@@ -202,276 +144,207 @@ mode_compile (const char *mode_string, u
                          | (octal_value & WOTH ? S_IWOTH : 0)
                          | (octal_value & XOTH ? S_IXOTH : 0)));
 
-      p = make_node_op_equals (mode);
-      if (p == NULL)
-       return MODE_MEMORY_EXHAUSTED;
-      mode_append_entry (&head, &tail, p);
-      return head;
+      return make_node_op_equals (mode);
     }
 
-  umask_value = umask (0);
-  umask (umask_value);         /* Restore the old value. */
+  /* Allocate enough space to hold the result.  */
+  {
+    size_t needed = 1;
+    char const *p;
+    for (p = mode_string; *p; p++)
+      needed += (*p == '=' || *p == '+' || *p == '-');
+    mc = xnmalloc (needed, sizeof *mc);
+  }
 
-  /* One loop iteration for each "ugoa...=+-rwxXstugo...[=+-rwxXstugo...]". */
+  /* One loop iteration for each `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.  */
   for (;; mode_string++)
     {
-      /* Which bits in the mode are operated on. */
-      mode_t affected_bits = 0;
-      /* `affected_bits' modified by umask. */
-      mode_t affected_masked;
-      /* Operators to actually use umask on. */
-      unsigned int ops_to_mask = 0;
+      /* Which bits in the mode are operated on.  */
+      mode_t affected = 0;
 
-      bool who_specified_p;
-
-      /* Turn on all the bits in `affected_bits' for each group given. */
+      /* Turn on all the bits in `affected' for each group given.  */
       for (;; mode_string++)
        switch (*mode_string)
          {
+         default:
+           goto invalid;
          case 'u':
-           affected_bits |= S_ISUID | S_IRWXU;
+           affected |= S_ISUID | S_IRWXU;
            break;
          case 'g':
-           affected_bits |= S_ISGID | S_IRWXG;
+           affected |= S_ISGID | S_IRWXG;
            break;
          case 'o':
-           affected_bits |= S_ISVTX | S_IRWXO;
+           affected |= S_ISVTX | S_IRWXO;
            break;
          case 'a':
-           affected_bits |= CHMOD_MODE_BITS;
+           affected |= CHMOD_MODE_BITS;
            break;
-         default:
+         case '=': case '+': case '-':
            goto no_more_affected;
          }
+    no_more_affected:;
 
-    no_more_affected:
-      /* If none specified, affect all bits, except perhaps those
-        set in the umask. */
-      if (affected_bits)
-       who_specified_p = true;
-      else
+      do
        {
-         who_specified_p = false;
-         affected_bits = CHMOD_MODE_BITS;
-         ops_to_mask = masked_ops;
-       }
+         char op = *mode_string++;
+         mode_t value;
+         char flag = MODE_COPY_EXISTING;
+         struct mode_change *change;
 
-      while (*mode_string == '=' || *mode_string == '+' || *mode_string == '-')
-       {
-         struct mode_change *change = talloc (struct mode_change);
-         if (change == NULL)
+         switch (*mode_string++)
            {
-             mode_free (head);
-             return MODE_MEMORY_EXHAUSTED;
+           case 'u':
+             /* Set the affected bits to the value of the `u' bits
+                on the same file.  */
+             value = S_IRWXU;
+             break;
+           case 'g':
+             /* Set the affected bits to the value of the `g' bits
+                on the same file.  */
+             value = S_IRWXG;
+             break;
+           case 'o':
+             /* Set the affected bits to the value of the `o' bits
+                on the same file.  */
+             value = S_IRWXO;
+             break;
+
+           default:
+             value = 0;
+             flag = MODE_ORDINARY_CHANGE;
+
+             for (mode_string--;; mode_string++)
+               switch (*mode_string)
+                 {
+                 case 'r':
+                   value |= S_IRUSR | S_IRGRP | S_IROTH;
+                   break;
+                 case 'w':
+                   value |= S_IWUSR | S_IWGRP | S_IWOTH;
+                   break;
+                 case 'x':
+                   value |= S_IXUSR | S_IXGRP | S_IXOTH;
+                   break;
+                 case 'X':
+                   flag = MODE_X_IF_ANY_X;
+                   break;
+                 case 's':
+                   /* Set the setuid/gid bits if `u' or `g' is selected.  */
+                   value |= S_ISUID | S_ISGID;
+                   break;
+                 case 't':
+                   /* Set the "save text image" bit if `o' is selected.  */
+                   value |= S_ISVTX;
+                   break;
+                 default:
+                   goto no_more_values;
+                 }
+           no_more_values:;
            }
 
-         change->next = NULL;
-         change->op = *mode_string;    /* One of "=+-". */
-         affected_masked = affected_bits;
-
-         /* Per the Single Unix Spec, if `who' is not specified and the
-            `=' operator is used, then clear all the bits first.  */
-         if (!who_specified_p &&
-             ops_to_mask & (*mode_string == '=' ? MODE_MASK_EQUALS : 0))
-           {
-             struct mode_change *p = make_node_op_equals (0);
-             if (p == NULL)
-               return MODE_MEMORY_EXHAUSTED;
-             mode_append_entry (&head, &tail, p);
-           }
-
-         if (ops_to_mask & (*mode_string == '=' ? MODE_MASK_EQUALS
-                            : *mode_string == '+' ? MODE_MASK_PLUS
-                            : MODE_MASK_MINUS))
-           affected_masked &= ~umask_value;
-         change->affected = affected_masked;
-         change->value = 0;
-         change->flags = 0;
-
-         /* Add the element to the tail of the list, so the operations
-            are performed in the correct order. */
-         mode_append_entry (&head, &tail, change);
-
-         /* Set `value' according to the bits set in `affected_masked'. */
-         for (++mode_string;; ++mode_string)
-           switch (*mode_string)
-             {
-             case 'r':
-               change->value |= ((S_IRUSR | S_IRGRP | S_IROTH)
-                                 & affected_masked);
-               break;
-             case 'w':
-               change->value |= ((S_IWUSR | S_IWGRP | S_IWOTH)
-                                 & affected_masked);
-               break;
-             case 'X':
-               change->flags |= MODE_X_IF_ANY_X;
-               /* Fall through. */
-             case 'x':
-               change->value |= ((S_IXUSR | S_IXGRP | S_IXOTH)
-                                 & affected_masked);
-               break;
-             case 's':
-               /* Set the setuid/gid bits if `u' or `g' is selected. */
-               change->value |= (S_ISUID | S_ISGID) & affected_masked;
-               break;
-             case 't':
-               /* Set the "save text image" bit if `o' is selected. */
-               change->value |= S_ISVTX & affected_masked;
-               break;
-             case 'u':
-               /* Set the affected bits to the value of the `u' bits
-                  on the same file.  */
-               if (change->value)
-                 goto invalid;
-               change->value = S_IRWXU;
-               change->flags |= MODE_COPY_EXISTING;
-               break;
-             case 'g':
-               /* Set the affected bits to the value of the `g' bits
-                  on the same file.  */
-               if (change->value)
-                 goto invalid;
-               change->value = S_IRWXG;
-               change->flags |= MODE_COPY_EXISTING;
-               break;
-             case 'o':
-               /* Set the affected bits to the value of the `o' bits
-                  on the same file.  */
-               if (change->value)
-                 goto invalid;
-               change->value = S_IRWXO;
-               change->flags |= MODE_COPY_EXISTING;
-               break;
-             default:
-               goto no_more_values;
-             }
-       no_more_values:;
+         change = &mc[used++];
+         change->op = op;
+         change->flag = flag;
+         change->affected = affected;
+         change->value = value;
        }
+      while (*mode_string == '=' || *mode_string == '+'
+            || *mode_string == '-');
 
       if (*mode_string != ',')
        break;
     }
 
   if (*mode_string == 0)
-    return head;
+    {
+      mc[used].flag = MODE_DONE;
+      return mc;
+    }
+
 invalid:
-  mode_free (head);
-  return MODE_INVALID;
+  free (mc);
+  return NULL;
 }
 
 /* Return a file mode change operation that sets permissions to match those
-   of REF_FILE.  Return MODE_BAD_REFERENCE if REF_FILE can't be accessed.  */
+   of REF_FILE.  Return NULL (setting errno) if REF_FILE can't be accessed.  */
 
 struct mode_change *
 mode_create_from_ref (const char *ref_file)
 {
-  struct mode_change *change;  /* the only change element */
   struct stat ref_stats;
 
-  if (stat (ref_file, &ref_stats))
-    return MODE_BAD_REFERENCE;
-
-  change = talloc (struct mode_change);
-
-  if (change == NULL)
-    return MODE_MEMORY_EXHAUSTED;
-
-  change->op = '=';
-  change->flags = 0;
-  change->affected = CHMOD_MODE_BITS;
-  change->value = ref_stats.st_mode;
-  change->next = NULL;
-
-  return change;
+  if (stat (ref_file, &ref_stats) != 0)
+    return NULL;
+  return make_node_op_equals (ref_stats.st_mode);
 }
 
 /* Return file mode OLDMODE, adjusted as indicated by the list of change
-   operations CHANGES.  If OLDMODE is a directory, the type `X'
+   operations CHANGES, which are interpreted assuming the umask is
+   UMASK_VALUE.  If OLDMODE is a directory, the type `X'
    change affects it even if no execute bits were set in OLDMODE.
-   The returned value has the S_IFMT bits cleared. */
+   The returned value has the S_IFMT bits cleared.  */
 
 mode_t
-mode_adjust (mode_t oldmode, const struct mode_change *changes)
+mode_adjust (mode_t oldmode, struct mode_change const *changes,
+            mode_t umask_value)
 {
-  mode_t newmode;      /* The adjusted mode and one operand. */
-  mode_t value;                /* The other operand. */
+  /* The adjusted mode.  */
+  mode_t newmode = oldmode & CHMOD_MODE_BITS;
 
-  newmode = oldmode & CHMOD_MODE_BITS;
-
-  for (; changes; changes = changes->next)
+  for (; changes->flag != MODE_DONE; changes++)
     {
-      if (changes->flags & MODE_COPY_EXISTING)
-       {
-         /* Isolate in `value' the bits in `newmode' to copy, given in
-            the mask `changes->value'. */
-         value = newmode & changes->value;
-
-         if (changes->value & S_IRWXU)
-           /* Copy `u' permissions onto `g' and `o'. */
-           value |= (  (value & S_IRUSR ? S_IRGRP | S_IROTH : 0)
-                     | (value & S_IWUSR ? S_IWGRP | S_IWOTH : 0)
-                     | (value & S_IXUSR ? S_IXGRP | S_IXOTH : 0));
-         else if (changes->value & S_IRWXG)
-           /* Copy `g' permissions onto `u' and `o'. */
-           value |= (  (value & S_IRGRP ? S_IRUSR | S_IROTH : 0)
-                     | (value & S_IWGRP ? S_IWUSR | S_IWOTH : 0)
-                     | (value & S_IXGRP ? S_IXUSR | S_IXOTH : 0));
-         else
-           /* Copy `o' permissions onto `u' and `g'. */
-           value |= (  (value & S_IROTH ? S_IRUSR | S_IRGRP : 0)
-                     | (value & S_IWOTH ? S_IWUSR | S_IWGRP : 0)
-                     | (value & S_IXOTH ? S_IXUSR | S_IXGRP : 0));
-
-         /* In order to change only `u', `g', or `o' permissions,
-            or some combination thereof, clear unselected bits.
-            This cannot be done in mode_compile because the value
-            to which the `changes->affected' mask is applied depends
-            on the old mode of each file. */
-         value &= changes->affected;
-       }
-      else
+      mode_t affected = changes->affected;
+      mode_t value = changes->value;
+
+      switch (changes->flag)
        {
-         value = changes->value;
-         /* If `X', do not affect the execute bits if the file is not a
-            directory and no execute bits are already set. */
-         if ((changes->flags & MODE_X_IF_ANY_X)
-             && !S_ISDIR (oldmode)
-             && (newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)
-           /* Clear the execute bits. */
-           value &= ~ (S_IXUSR | S_IXGRP | S_IXOTH);
+       case MODE_ORDINARY_CHANGE:
+         break;
+
+       case MODE_COPY_EXISTING:
+         /* Isolate in `value' the bits in `newmode' to copy.  */
+         value &= newmode;
+
+         /* Copy the isolated bits to the other two parts.  */
+         value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH)
+                    ? S_IRUSR | S_IRGRP | S_IROTH : 0)
+                   | (value & (S_IWUSR | S_IWGRP | S_IWOTH)
+                      ? S_IWUSR | S_IWGRP | S_IWOTH : 0)
+                   | (value & (S_IXUSR | S_IXGRP | S_IXOTH)
+                      ? S_IXUSR | S_IXGRP | S_IXOTH : 0));
+         break;
+
+       case MODE_X_IF_ANY_X:
+         /* Affect the execute bits if execute bits are already set
+            or if the file is a directory.  */
+         if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) || S_ISDIR (oldmode))
+           value |= S_IXUSR | S_IXGRP | S_IXOTH;
+         break;
        }
 
+      /* If WHO was specified, limit the change to the affected bits.
+        Otherwise, apply the umask.  */
+      value &= (affected ? affected : ~umask_value);
+
       switch (changes->op)
        {
        case '=':
-         /* Preserve the previous values in `newmode' of bits that are
-            not affected by this change operation. */
-         newmode = (newmode & ~changes->affected) | value;
-         break;
+         /* If WHO was specified, preserve the previous values of
+            bits that are not affected by this change operation.
+            Otherwise, clear all the bits.  */
+         newmode = (affected ? newmode & ~affected : 0);
+         /* Fall through.  */
        case '+':
          newmode |= value;
          break;
+
        case '-':
          newmode &= ~value;
          break;
        }
     }
-  return newmode;
-}
-
-/* Free the memory used by the list of file mode change operations
-   CHANGES. */
-
-void
-mode_free (register struct mode_change *changes)
-{
-  register struct mode_change *next;
 
-  while (changes)
-    {
-      next = changes->next;
-      free (changes);
-      changes = next;
-    }
+  return newmode;
 }
Index: lib/modechange.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/modechange.h,v
retrieving revision 1.13
diff -p -u -r1.13 modechange.h
--- lib/modechange.h    7 Aug 2004 00:09:39 -0000       1.13
+++ lib/modechange.h    2 May 2005 06:58:37 -0000
@@ -1,5 +1,7 @@
 /* modechange.h -- definitions for file mode manipulation
-   Copyright (C) 1989, 1990, 1997, 2003, 2004 Free Software Foundation, Inc.
+
+   Copyright (C) 1989, 1990, 1997, 2003, 2004, 2005 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
@@ -22,38 +24,8 @@
 
 # include <sys/types.h>
 
-/* Affect the execute bits only if at least one execute bit is set already,
-   or if the file is a directory. */
-# define MODE_X_IF_ANY_X 01
-
-/* If set, copy some existing permissions for u, g, or o onto the other two.
-   Which of u, g, or o is copied is determined by which bits are set in the
-   `value' field. */
-# define MODE_COPY_EXISTING 02
-
-struct mode_change
-{
-  char op;                     /* One of "=+-". */
-  char flags;                  /* Special operations. */
-  mode_t affected;             /* Set for u/g/o/s/s/t, if to be affected. */
-  mode_t value;                        /* Bits to add/remove. */
-  struct mode_change *next;    /* Link to next change in list. */
-};
-
-/* Masks for mode_compile argument. */
-# define MODE_MASK_EQUALS 1
-# define MODE_MASK_PLUS 2
-# define MODE_MASK_MINUS 4
-# define MODE_MASK_ALL (MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS)
-
-/* Error return values for mode_compile. */
-# define MODE_INVALID (struct mode_change *) 0
-# define MODE_MEMORY_EXHAUSTED (struct mode_change *) 1
-# define MODE_BAD_REFERENCE (struct mode_change *) 2
-
-struct mode_change *mode_compile (const char *, unsigned int);
+struct mode_change *mode_compile (const char *);
 struct mode_change *mode_create_from_ref (const char *);
-mode_t mode_adjust (mode_t, const struct mode_change *);
-void mode_free (struct mode_change *);
+mode_t mode_adjust (mode_t, struct mode_change const *, mode_t);
 
 #endif
Index: lib/nanosleep.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/nanosleep.c,v
retrieving revision 1.13
diff -p -u -r1.13 nanosleep.c
--- lib/nanosleep.c     7 Aug 2004 00:09:39 -0000       1.13
+++ lib/nanosleep.c     2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
 /* Provide a replacement for the POSIX nanosleep function.
-   Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002, 2004, 2005 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
@@ -34,6 +34,8 @@
 # include <unistd.h>
 #endif
 
+#include "timespec.h"
+
 /* Some systems (MSDOS) don't have SIGCONT.
    Using SIGTERM here turns the signal-handling code below
    into a no-op on such systems. */
@@ -41,7 +43,9 @@
 # define SIGCONT SIGTERM
 #endif
 
-#include "timespec.h"
+#if ! HAVE_SIGINTERRUPT
+# define siginterrupt(sig, flag) /* empty */
+#endif
 
 static sig_atomic_t volatile suspended;
 
@@ -66,7 +70,7 @@ my_usleep (const struct timespec *ts_del
       tv_delay.tv_sec++;
       tv_delay.tv_usec = 0;
     }
-  select (0, (void *) 0, (void *) 0, (void *) 0, &tv_delay);
+  select (0, NULL, NULL, NULL, &tv_delay);
 }
 
 /* FIXME: comment */
@@ -77,16 +81,11 @@ rpl_nanosleep (const struct timespec *re
 {
   static bool initialized;
 
-#ifdef SA_NOCLDSTOP
-  struct sigaction oldact, newact;
-#endif
-
-  suspended = 0;
-
   /* set up sig handler */
   if (! initialized)
     {
 #ifdef SA_NOCLDSTOP
+      struct sigaction oldact, newact;
       newact.sa_handler = sighandler;
       sigemptyset (&newact.sa_mask);
       newact.sa_flags = 0;
@@ -96,11 +95,16 @@ rpl_nanosleep (const struct timespec *re
        sigaction (SIGCONT, &newact, NULL);
 #else
       if (signal (SIGCONT, SIG_IGN) != SIG_IGN)
-       signal (SIGCONT, sighandler);
+       {
+         signal (SIGCONT, sighandler);
+         siginterrupt (SIGCONT, 1);
+       }
 #endif
       initialized = true;
     }
 
+  suspended = 0;
+
   my_usleep (requested_delay);
 
   if (suspended)
Index: lib/readutmp.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/readutmp.c,v
retrieving revision 1.19
diff -p -u -r1.19 readutmp.c
--- lib/readutmp.c      1 Dec 2004 07:29:45 -0000       1.19
+++ lib/readutmp.c      2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
 /* GNU's read utmp module.
-   Copyright (C) 1992-2001, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1992-2001, 2003, 2004, 2005 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
@@ -26,6 +26,8 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <signal.h>
+#include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -35,6 +37,10 @@
 # include "unlocked-io.h"
 #endif
 
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
 /* Copy UT->ut_name into storage obtained from malloc.  Then remove any
    trailing spaces from the copy, NUL terminate it, and return the copy.  */
 
@@ -56,19 +62,32 @@ extract_trimmed_name (const STRUCT_UTMP 
   return trimmed_name;
 }
 
+/* Is the utmp entry U desired by the user who asked for OPTIONS?  */
+
+static inline bool
+desirable_utmp_entry (STRUCT_UTMP const *u, int options)
+{
+  return ! (options & READ_UTMP_CHECK_PIDS
+           && (UT_PID (u) <= 0
+               || (kill (UT_PID (u), 0) < 0 && errno == ESRCH)));
+}
+
 /* Read the utmp entries corresponding to file FILENAME into freshly-
    malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to
    the number of entries, and return zero.  If there is any error,
-   return -1, setting errno, and don't modify the parameters.  */
+   return -1, setting errno, and don't modify the parameters.
+   If OPTIONS & READ_UTMP_CHECK_PIDS is nonzero, omit entries whose
+   process-IDs do not currently exist.  */
 
 #ifdef UTMP_NAME_FUNCTION
 
 int
-read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf)
+read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf,
+          int options)
 {
-  size_t n_read;
-  size_t n_alloc = 4;
-  STRUCT_UTMP *utmp = xmalloc (n_alloc * sizeof *utmp);
+  size_t n_read = 0;
+  size_t n_alloc = 0;
+  STRUCT_UTMP *utmp = NULL;
   STRUCT_UTMP *u;
 
   /* Ignore the return value for now.
@@ -79,17 +98,14 @@ read_utmp (const char *filename, size_t 
 
   SET_UTMP_ENT ();
 
-  n_read = 0;
   while ((u = GET_UTMP_ENT ()) != NULL)
-    {
-      if (n_read == n_alloc)
-       {
-         utmp = xnrealloc (utmp, n_alloc, 2 * sizeof *utmp);
-         n_alloc *= 2;
-       }
-      ++n_read;
-      utmp[n_read - 1] = *u;
-    }
+    if (desirable_utmp_entry (u, options))
+      {
+       if (n_read == n_alloc)
+         utmp = x2nrealloc (utmp, &n_alloc, sizeof *utmp);
+
+       utmp[n_read++] = *u;
+      }
 
   END_UTMP_ENT ();
 
@@ -102,46 +118,39 @@ read_utmp (const char *filename, size_t 
 #else
 
 int
-read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf)
+read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf,
+          int options)
 {
-  FILE *utmp;
-  struct stat file_stats;
-  size_t n_read;
-  size_t size;
-  STRUCT_UTMP *buf;
+  size_t n_read = 0;
+  size_t n_alloc = 0;
+  STRUCT_UTMP *utmp = NULL;
+  int saved_errno;
+  FILE *f = fopen (filename, "r");
 
-  utmp = fopen (filename, "r");
-  if (utmp == NULL)
+  if (! f)
     return -1;
 
-  if (fstat (fileno (utmp), &file_stats) != 0)
-    {
-      int e = errno;
-      fclose (utmp);
-      errno = e;
-      return -1;
-    }
-  size = file_stats.st_size;
-  buf = xmalloc (size);
-  n_read = fread (buf, sizeof *buf, size / sizeof *buf, utmp);
-  if (ferror (utmp))
+  for (;;)
     {
-      int e = errno;
-      free (buf);
-      fclose (utmp);
-      errno = e;
-      return -1;
+      if (n_read == n_alloc)
+       utmp = x2nrealloc (utmp, &n_alloc, sizeof *utmp);
+      if (fread (&utmp[n_read], sizeof utmp[n_read], 1, f) == 0)
+       break;
+      n_read += desirable_utmp_entry (&utmp[n_read], options);
     }
-  if (fclose (utmp) != 0)
+
+  saved_errno = ferror (f) ? errno : 0;
+  if (fclose (f) != 0)
+    saved_errno = errno;
+  if (saved_errno != 0)
     {
-      int e = errno;
-      free (buf);
-      errno = e;
+      free (utmp);
+      errno = saved_errno;
       return -1;
     }
 
   *n_entries = n_read;
-  *utmp_buf = buf;
+  *utmp_buf = utmp;
 
   return 0;
 }
Index: lib/readutmp.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/readutmp.h,v
retrieving revision 1.16
diff -p -u -r1.16 readutmp.h
--- lib/readutmp.h      1 Dec 2004 07:30:05 -0000       1.16
+++ lib/readutmp.h      2 May 2005 06:58:37 -0000
@@ -1,7 +1,7 @@
 /* Declarations for GNU's read utmp module.
 
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005 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
@@ -167,6 +167,12 @@ enum { UT_USER_SIZE = sizeof UT_USER ((S
 #  define WTMP_FILE "/etc/wtmp"
 # endif
 
+# if HAVE_STRUCT_XTMP_UT_PID
+#  define UT_PID(U) ((U)->ut_pid)
+# else
+#  define UT_PID(U) 0
+# endif
+
 # if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
 #  define UT_TYPE_EQ(U, V) ((U)->ut_type == (V))
 #  define UT_TYPE_NOT_DEFINED 0
@@ -192,7 +198,14 @@ enum { UT_USER_SIZE = sizeof UT_USER ((S
     && (UT_TYPE_USER_PROCESS (U)                               \
         || (UT_TYPE_NOT_DEFINED && UT_TIME_MEMBER (U) != 0)))
 
+/* Options for read_utmp.  */
+enum
+  {
+    READ_UTMP_CHECK_PIDS = 1
+  };
+
 char *extract_trimmed_name (const STRUCT_UTMP *ut);
-int read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP 
**utmp_buf);
+int read_utmp (const char *filename, size_t *n_entries, STRUCT_UTMP **utmp_buf,
+              int options);
 
 #endif /* __READUTMP_H__ */
Index: lib/save-cwd.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/save-cwd.c,v
retrieving revision 1.20
diff -p -u -r1.20 save-cwd.c
--- lib/save-cwd.c      9 Mar 2005 23:22:08 -0000       1.20
+++ lib/save-cwd.c      2 May 2005 06:58:37 -0000
@@ -42,6 +42,7 @@
 #include <errno.h>
 
 #include "chdir-long.h"
+#include "unistd-safer.h"
 #include "xgetcwd.h"
 
 /* On systems without the fchdir function (WOE), pretend that open
@@ -49,7 +50,7 @@
    Since chdir_long requires fchdir, use chdir instead.  */
 #if !HAVE_FCHDIR
 # undef open
-# define open(File, Flags) -1
+# define open(File, Flags) (-1)
 # undef fchdir
 # define fchdir(Fd) (abort (), -1)
 # undef chdir_long
@@ -81,10 +82,10 @@ save_cwd (struct saved_cwd *cwd)
 {
   cwd->name = NULL;
 
-  cwd->desc = open (".", O_RDONLY);
+  cwd->desc = fd_safer (open (".", O_RDONLY));
   if (cwd->desc < 0)
     {
-      cwd->desc = open (".", O_WRONLY);
+      cwd->desc = fd_safer (open (".", O_WRONLY));
       if (cwd->desc < 0)
        {
          cwd->name = xgetcwd ();
Index: lib/tempname.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/tempname.c,v
retrieving revision 1.11
diff -p -u -r1.11 tempname.c
--- lib/tempname.c      12 Sep 2003 18:24:51 -0000      1.11
+++ lib/tempname.c      2 May 2005 06:58:37 -0000
@@ -1,7 +1,7 @@
 /* tempname.c - generate the name of a temporary file.
 
    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2005 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
@@ -67,34 +67,11 @@
 #endif
 
 #include <sys/stat.h>
-#if STAT_MACROS_BROKEN
-# undef S_ISDIR
-#endif
-#if !defined S_ISDIR && defined S_IFDIR
-# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-#if !S_IRUSR && S_IREAD
-# define S_IRUSR S_IREAD
-#endif
-#if !S_IRUSR
-# define S_IRUSR 00400
-#endif
-#if !S_IWUSR && S_IWRITE
-# define S_IWUSR S_IWRITE
-#endif
-#if !S_IWUSR
-# define S_IWUSR 00200
-#endif
-#if !S_IXUSR && S_IEXEC
-# define S_IXUSR S_IEXEC
-#endif
-#if !S_IXUSR
-# define S_IXUSR 00100
-#endif
 
 #if _LIBC
 # define struct_stat64 struct stat64
 #else
+# include "stat-macros.h"
 # define struct_stat64 struct stat
 # define __getpid getpid
 # define __gettimeofday gettimeofday
Index: lib/unistd-safer.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/unistd-safer.h,v
retrieving revision 1.2
diff -p -u -r1.2 unistd-safer.h
--- lib/unistd-safer.h  18 Jun 2003 05:52:19 -0000      1.2
+++ lib/unistd-safer.h  2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
-/* Invoke unistd functions, but avoid some glitches.
+/* Invoke unistd-like functions, but avoid some glitches.
 
-   Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2005 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
@@ -19,3 +19,4 @@
 /* Written by Paul Eggert.  */
 
 int dup_safer (int);
+int fd_safer (int);
Index: m4/ChangeLog
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/ChangeLog,v
retrieving revision 1.641
diff -p -u -r1.641 ChangeLog
--- m4/ChangeLog        1 May 2005 14:13:01 -0000       1.641
+++ m4/ChangeLog        2 May 2005 06:58:37 -0000
@@ -1,3 +1,41 @@
+2005-05-01  Paul Eggert  <address@hidden>
+
+       * euidaccess.m4 (gl_PREREQ_EUIDACCESS): Don't require AC_HEADER_STAT.
+       * lchown.m4 (gl_FUNC_CHOWN): Likewise.
+       (gl_PREREQ_CHOWN): Remove.
+       * lstat.m4 (gl_FUNC_LSTAT): Require AC_FUNC_LSTAT instead of calling
+       it.  Don't require AC_HEADER_STAT.
+       (gl_PREREQ_LSTAT): Remove.
+       * mkstemp.m4 (gl_PREREQ_TEMPNAME): Check stdint.h only once.
+       Don't require AC_HEADER_STAT.
+       * rmdir.m4 (gl_FUNC_RMDIR): Don't require AC_HEADER_STAT.
+       (gl_PREREQ_RMDIR): Remove.
+       * canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME): Don't
+       mention stat-macros.h or AC_HEADER_STAT, since we'll make
+       the stat-macros module a prerequisite.
+       * file-type.m4 (gl_FILE_TYPE): Likewise.
+       * filemode.m4 (gl_FILEMODE): Likewise.
+       * makepath.m4 (gl_MAKEPATH): Likewise.
+       * modechange.m4 (gl_MODECHANGE): Likewise.
+       * clock_time.m4 (gl_CLOCK_TIME): Use gl_ rather than fetish_ for
+       variable names.
+       * rmdir-errno.m4 (gl_FUNC_RMDIR_NOTEMPTY): Renamed from
+       fetish_FUNC_RMDIR_NOTEMPTY.  All uses changed.  Use gl_ for
+       variable prefixes.
+       * fcntl-safer.m4: Remove.
+       * stdio-safer.m4 (gl_STDIO_SAFER): Use AC_LIBSOURCES and AC_LIBOBJ.
+       * unistd-safer.m4 (gl_UNISTD_SAFER): Likewise.
+       Invoke gl_PREREQ_FD_SAFER.
+       (gl_PREREQ_FD_SAFER): New macro.
+       * nanosleep.m4 (gl_PREREQ_NANOSLEEP): Check for siginterrupt.
+       * readutmp.m4 (gl_READUTMP): Require AC_C_INLINE.
+       Use AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE when possible.
+       Remove duplicate call to AC_LIBOBJ(readutmp).
+       (gl_PREREQ_READUTMP): Remove.  All uses inlined.
+
+       * mmap-anon.m4 (gl_FUNC_MMAP_ANON): Check for message, not for
+       MAP_ANON.  Problem reported by Moriyoshi Koizumi to bug-cvs.
+
 2005-05-01  Oskar Liljeblad  <address@hidden>
 
        * byteswap.m4: New file.
Index: m4/canonicalize.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/canonicalize.m4,v
retrieving revision 1.3
diff -p -u -r1.3 canonicalize.m4
--- m4/canonicalize.m4  21 Mar 2005 22:06:27 -0000      1.3
+++ m4/canonicalize.m4  2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-#serial 6
+#serial 7
 
 # Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -9,11 +9,10 @@
 
 AC_DEFUN([AC_FUNC_CANONICALIZE_FILE_NAME],
   [
-    AC_LIBSOURCES([canonicalize.c, canonicalize.h, stat-macros.h])
+    AC_LIBSOURCES([canonicalize.c, canonicalize.h])
     AC_LIBOBJ([canonicalize])
 
     AC_REQUIRE([AC_HEADER_STDC])
     AC_CHECK_HEADERS(string.h sys/param.h stddef.h)
     AC_CHECK_FUNCS(resolvepath canonicalize_file_name)
-    AC_REQUIRE([AC_HEADER_STAT])
   ])
Index: m4/clock_time.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/clock_time.m4,v
retrieving revision 1.5
diff -p -u -r1.5 clock_time.m4
--- m4/clock_time.m4    23 Jan 2005 08:06:57 -0000      1.5
+++ m4/clock_time.m4    2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
-# clock_time.m4 serial 5
-dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# clock_time.m4 serial 6
+dnl Copyright (C) 2002, 2003, 2004, 2005 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.
@@ -16,11 +16,11 @@ AC_DEFUN([gl_CLOCK_TIME],
   # Save and restore LIBS so e.g., -lrt, isn't added to it.  Otherwise, *all*
   # programs in the package would end up linked with that potentially-shared
   # library, inducing unnecessary run-time overhead.
-  fetish_saved_libs=$LIBS
+  gl_saved_libs=$LIBS
     AC_SEARCH_LIBS(clock_gettime, [rt posix4],
                    [test "$ac_cv_search_clock_gettime" = "none required" ||
                     LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
     AC_SUBST(LIB_CLOCK_GETTIME)
     AC_CHECK_FUNCS(clock_gettime clock_settime)
-  LIBS=$fetish_saved_libs
+  LIBS=$gl_saved_libs
 ])
Index: m4/euidaccess.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/euidaccess.m4,v
retrieving revision 1.4
diff -p -u -r1.4 euidaccess.m4
--- m4/euidaccess.m4    23 Jan 2005 08:06:57 -0000      1.4
+++ m4/euidaccess.m4    2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
-# euidaccess.m4 serial 5
-dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# euidaccess.m4 serial 6
+dnl Copyright (C) 2002, 2003, 2004, 2005 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.
@@ -32,7 +32,6 @@ AC_DEFUN([gl_PREREQ_EUIDACCESS], [
   AC_CHECK_HEADERS_ONCE(libgen.h)
   AC_CHECK_DECLS_ONCE(setregid)
   AC_REQUIRE([AC_FUNC_GETGROUPS])
-  AC_REQUIRE([AC_HEADER_STAT])
 
   # Solaris 9 needs -lgen to get the eaccess function.
   # Save and restore LIBS so -lgen isn't added to it.  Otherwise, *all*
Index: m4/file-type.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/file-type.m4,v
retrieving revision 1.3
diff -p -u -r1.3 file-type.m4
--- m4/file-type.m4     21 Mar 2005 22:06:27 -0000      1.3
+++ m4/file-type.m4     2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-# file-type.m4 serial 4
+# file-type.m4 serial 5
 dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,9 +6,6 @@ dnl with or without modifications, as lo
 
 AC_DEFUN([gl_FILE_TYPE],
 [
-  AC_LIBSOURCES([file-type.c, file-type.h, stat-macros.h])
+  AC_LIBSOURCES([file-type.c, file-type.h])
   AC_LIBOBJ([file-type])
-
-  dnl Prerequisites of lib/file-type.h.
-  AC_REQUIRE([AC_HEADER_STAT])
 ])
Index: m4/filemode.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/filemode.m4,v
retrieving revision 1.3
diff -p -u -r1.3 filemode.m4
--- m4/filemode.m4      21 Mar 2005 22:06:27 -0000      1.3
+++ m4/filemode.m4      2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-# filemode.m4 serial 4
+# filemode.m4 serial 5
 dnl Copyright (C) 2002, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,9 +6,6 @@ dnl with or without modifications, as lo
 
 AC_DEFUN([gl_FILEMODE],
 [
-  AC_LIBSOURCES([filemode.c, filemode.h, stat-macros.h])
+  AC_LIBSOURCES([filemode.c, filemode.h])
   AC_LIBOBJ([filemode])
-
-  dnl Prerequisites of lib/filemode.c.
-  AC_REQUIRE([AC_HEADER_STAT])
 ])
Index: m4/lchown.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/lchown.m4,v
retrieving revision 1.6
diff -p -u -r1.6 lchown.m4
--- m4/lchown.m4        18 Jan 2005 23:42:19 -0000      1.6
+++ m4/lchown.m4        2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
-#serial 6
+#serial 7
 
-dnl Copyright (C) 1998, 2001, 2003, 2004 Free Software Foundation, Inc.
+dnl Copyright (C) 1998, 2001, 2003, 2004, 2005 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.
@@ -13,14 +13,4 @@ AC_DEFUN([gl_FUNC_LCHOWN],
   AC_LIBSOURCES([lchown.c, lchown.h])
   AC_REQUIRE([AC_TYPE_UID_T])
   AC_REPLACE_FUNCS(lchown)
-  if test $ac_cv_func_lchown = no; then
-    gl_PREREQ_LCHOWN
-  fi
-])
-
-# Prerequisites of lib/lchown.c.
-AC_DEFUN([gl_PREREQ_LCHOWN],
-[
-  AC_REQUIRE([AC_HEADER_STAT])
-  :
 ])
Index: m4/lstat.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/lstat.m4,v
retrieving revision 1.19
diff -p -u -r1.19 lstat.m4
--- m4/lstat.m4 23 Jan 2005 08:06:57 -0000      1.19
+++ m4/lstat.m4 2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
-#serial 12
+#serial 13
 
-# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software
+# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 Free Software
 # Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
@@ -18,16 +18,7 @@ dnl
 
 AC_DEFUN([gl_FUNC_LSTAT],
 [
-  AC_FUNC_LSTAT
+  AC_REQUIRE([AC_FUNC_LSTAT])
   dnl Note: AC_FUNC_LSTAT does AC_LIBOBJ(lstat).
-  if test $ac_cv_func_lstat_empty_string_bug = yes; then
-    gl_PREREQ_LSTAT
-  fi
-])
-
-# Prerequisites of lib/lstat.c.
-AC_DEFUN([gl_PREREQ_LSTAT],
-[
-  AC_REQUIRE([AC_HEADER_STAT])
   :
 ])
Index: m4/makepath.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/makepath.m4,v
retrieving revision 1.6
diff -p -u -r1.6 makepath.m4
--- m4/makepath.m4      21 Mar 2005 22:06:27 -0000      1.6
+++ m4/makepath.m4      2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-# makepath.m4 serial 6
+# makepath.m4 serial 7
 dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,12 +6,11 @@ dnl with or without modifications, as lo
 
 AC_DEFUN([gl_MAKEPATH],
 [
-  AC_LIBSOURCES([makepath.c, makepath.h, stat-macros.h])
+  AC_LIBSOURCES([makepath.c, makepath.h])
   AC_LIBOBJ([makepath])
 
   dnl Prerequisites of lib/makepath.c.
   AC_REQUIRE([AC_FUNC_ALLOCA])
   AC_CHECK_HEADERS_ONCE(unistd.h)
-  AC_REQUIRE([AC_HEADER_STAT])
   AC_REQUIRE([gl_AFS])
 ])
Index: m4/mkstemp.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/mkstemp.m4,v
retrieving revision 1.13
diff -p -u -r1.13 mkstemp.m4
--- m4/mkstemp.m4       23 Jan 2005 08:06:57 -0000      1.13
+++ m4/mkstemp.m4       2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-#serial 9
+#serial 10
 
 # Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -65,9 +65,7 @@ AC_DEFUN([gl_PREREQ_MKSTEMP],
 # Prerequisites of lib/tempname.c.
 AC_DEFUN([gl_PREREQ_TEMPNAME],
 [
-  AC_REQUIRE([AC_HEADER_STAT])
-  AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h unistd.h)
-  AC_CHECK_HEADERS(stdint.h)
+  AC_CHECK_HEADERS_ONCE(fcntl.h sys/time.h stdint.h unistd.h)
   AC_CHECK_FUNCS(__secure_getenv gettimeofday)
   AC_CHECK_DECLS_ONCE(getenv)
   AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])
Index: m4/modechange.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/modechange.m4,v
retrieving revision 1.4
diff -p -u -r1.4 modechange.m4
--- m4/modechange.m4    21 Mar 2005 22:06:27 -0000      1.4
+++ m4/modechange.m4    2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-# modechange.m4 serial 4
+# modechange.m4 serial 5
 dnl Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,4 @@ AC_DEFUN([gl_MODECHANGE],
 [
   AC_LIBSOURCES([modechange.c, modechange.h])
   AC_LIBOBJ([modechange])
-
-  AC_REQUIRE([AC_HEADER_STAT])
 ])
Index: m4/nanosleep.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/nanosleep.m4,v
retrieving revision 1.19
diff -p -u -r1.19 nanosleep.m4
--- m4/nanosleep.m4     21 Mar 2005 22:06:27 -0000      1.19
+++ m4/nanosleep.m4     2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-#serial 12
+#serial 13
 
 dnl From Jim Meyering.
 dnl Check for the nanosleep function.
@@ -68,4 +68,5 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
 AC_DEFUN([gl_PREREQ_NANOSLEEP],
 [
   AC_CHECK_HEADERS_ONCE(unistd.h)
+  AC_CHECK_FUNCS_ONCE(siginterrupt)
 ])
Index: m4/readutmp.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/readutmp.m4,v
retrieving revision 1.8
diff -p -u -r1.8 readutmp.m4
--- m4/readutmp.m4      21 Mar 2005 22:06:27 -0000      1.8
+++ m4/readutmp.m4      2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-# readutmp.m4 serial 7
+# readutmp.m4 serial 9
 dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -9,9 +9,11 @@ AC_DEFUN([gl_READUTMP],
   AC_LIBSOURCES([readutmp.c, readutmp.h])
   AC_LIBOBJ([readutmp])
 
-  dnl Prerequisites of lib/readutmp.h.
-  AC_CHECK_HEADERS(utmp.h utmpx.h)
-  AC_CHECK_FUNCS(utmpname utmpxname)
+  dnl Prerequisites of lib/readutmp.h and lib/readutmp.c.
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_FUNC_FREE])
+  AC_CHECK_HEADERS_ONCE(utmp.h utmpx.h)
+  AC_CHECK_FUNCS_ONCE(utmpname utmpxname)
   AC_CHECK_DECLS(getutent,,,[
 #ifdef HAVE_UTMP_H
 # include <utmp.h>
@@ -49,14 +51,5 @@ $ac_includes_default
     AC_CHECK_MEMBERS([struct utmp.ut_exit.ut_termination],,,[$utmp_includes])
     AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_termination],,,[$utmp_includes])
     AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination],,,[$utmp_includes])
-
-    AC_LIBOBJ(readutmp)
-    gl_PREREQ_READUTMP
   fi
 ])
-
-# Prerequisites of lib/readutmp.c.
-AC_DEFUN([gl_PREREQ_READUTMP],
-[
-  AC_REQUIRE([gl_FUNC_FREE])
-])
Index: m4/rmdir-errno.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/rmdir-errno.m4,v
retrieving revision 1.4
diff -p -u -r1.4 rmdir-errno.m4
--- m4/rmdir-errno.m4   23 Jan 2005 08:06:57 -0000      1.4
+++ m4/rmdir-errno.m4   2 May 2005 06:58:37 -0000
@@ -1,6 +1,6 @@
-#serial 4
+#serial 5
 
-# Copyright (C) 2000, 2001, Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -10,10 +10,10 @@
 # ENOTEMPTY is mistakenly defined to be EEXIST.  To work around this, and
 # in general, to avoid depending on the use of any particular symbol, this
 # test runs a test to determine the actual numeric value.
-AC_DEFUN([fetish_FUNC_RMDIR_NOTEMPTY],
+AC_DEFUN([gl_FUNC_RMDIR_NOTEMPTY],
 [dnl
   AC_CACHE_CHECK([for rmdir-not-empty errno value],
-    fetish_cv_func_rmdir_errno_not_empty,
+    gl_cv_func_rmdir_errno_not_empty,
     [
       # Arrange for deletion of the temporary directory this test creates.
       ac_clean_files="$ac_clean_files confdir2"
@@ -35,14 +35,14 @@ extern int errno;
          exit (0);
        }
        ],
-      fetish_cv_func_rmdir_errno_not_empty=`cat confdir2/errno`,
-      fetish_cv_func_rmdir_errno_not_empty='configure error in rmdir-errno.m4',
-      fetish_cv_func_rmdir_errno_not_empty=ENOTEMPTY
+      gl_cv_func_rmdir_errno_not_empty=`cat confdir2/errno`,
+      gl_cv_func_rmdir_errno_not_empty='configure error in rmdir-errno.m4',
+      gl_cv_func_rmdir_errno_not_empty=ENOTEMPTY
       )
     ]
   )
 
   AC_DEFINE_UNQUOTED([RMDIR_ERRNO_NOT_EMPTY],
-    $fetish_cv_func_rmdir_errno_not_empty,
+    $gl_cv_func_rmdir_errno_not_empty,
     [the value to which errno is set when rmdir fails on a nonempty directory])
 ])
Index: m4/rmdir.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/rmdir.m4,v
retrieving revision 1.2
diff -p -u -r1.2 rmdir.m4
--- m4/rmdir.m4 23 Jan 2005 08:06:57 -0000      1.2
+++ m4/rmdir.m4 2 May 2005 06:58:37 -0000
@@ -1,5 +1,5 @@
-# rmdir.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# rmdir.m4 serial 3
+dnl Copyright (C) 2002, 2005 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.
@@ -7,13 +7,4 @@ dnl with or without modifications, as lo
 AC_DEFUN([gl_FUNC_RMDIR],
 [
   AC_REPLACE_FUNCS(rmdir)
-  if test $ac_cv_func_rmdir = no; then
-    gl_PREREQ_RMDIR
-  fi
-])
-
-# Prerequisites of lib/rmdir.c.
-AC_DEFUN([gl_PREREQ_RMDIR], [
-  AC_REQUIRE([AC_HEADER_STAT])
-  :
 ])
Index: m4/stat-macros.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/stat-macros.m4,v
retrieving revision 1.1
diff -p -u -r1.1 stat-macros.m4
--- m4/stat-macros.m4   22 Mar 2005 07:44:41 -0000      1.1
+++ m4/stat-macros.m4   2 May 2005 06:58:37 -0000
@@ -1,4 +1,4 @@
-#serial 1
+#serial 2
 
 # Copyright (C) 2005 Free Software Foundation, Inc.
 #
@@ -9,4 +9,6 @@
 AC_DEFUN([gl_STAT_MACROS],
 [
   AC_LIBSOURCES([stat-macros.h])
+  
+  AC_REQUIRE([AC_HEADER_STAT])
 ])
Index: m4/stdio-safer.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/stdio-safer.m4,v
retrieving revision 1.2
diff -p -u -r1.2 stdio-safer.m4
--- m4/stdio-safer.m4   23 Jan 2005 08:06:57 -0000      1.2
+++ m4/stdio-safer.m4   2 May 2005 06:58:37 -0000
@@ -1,11 +1,14 @@
-# stdio-safer.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# stdio-safer.m4 serial 3
+dnl Copyright (C) 2002, 2005 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.
 
 AC_DEFUN([gl_STDIO_SAFER],
 [
+  AC_LIBSOURCES([fopen-safer.c, stdio-safer.h])
+  AC_LIBOBJ([fopen-safer])
+
   dnl Prerequisites of lib/fopen-safer.c.
   AC_CHECK_HEADERS_ONCE(unistd.h)
 ])
Index: m4/unistd-safer.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/unistd-safer.m4,v
retrieving revision 1.2
diff -p -u -r1.2 unistd-safer.m4
--- m4/unistd-safer.m4  23 Jan 2005 08:06:57 -0000      1.2
+++ m4/unistd-safer.m4  2 May 2005 06:58:37 -0000
@@ -1,15 +1,25 @@
-# unistd-safer.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# unistd-safer.m4 serial 3
+dnl Copyright (C) 2002, 2005 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.
 
 AC_DEFUN([gl_UNISTD_SAFER],
 [
+  AC_LIBSOURCES([dup-safer.c, fd-safer.c, unistd-safer.h])
+  AC_LIBOBJ([dup-safer])
+  AC_LIBOBJ([fd-safer])
+
   gl_PREREQ_DUP_SAFER
+  gl_PREREQ_FD_SAFER
 ])
 
 # Prerequisites of lib/dup-safer.c.
 AC_DEFUN([gl_PREREQ_DUP_SAFER], [
   AC_CHECK_HEADERS_ONCE(fcntl.h unistd.h)
 ])
+
+# Prerequisites of lib/fd-safer.c.
+AC_DEFUN([gl_PREREQ_FD_SAFER], [
+  AC_CHECK_HEADERS_ONCE(unistd.h)
+])
Index: modules/getloadavg
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/getloadavg,v
retrieving revision 1.7
diff -p -u -r1.7 getloadavg
--- modules/getloadavg  9 Mar 2005 19:11:23 -0000       1.7
+++ modules/getloadavg  2 May 2005 06:58:37 -0000
@@ -9,6 +9,7 @@ Depends-on:
 cloexec
 xalloc
 c-strtod
+unistd-safer
 
 configure.ac:
 AC_FUNC_GETLOADAVG
Index: modules/getusershell
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/getusershell,v
retrieving revision 1.5
diff -p -u -r1.5 getusershell
--- modules/getusershell        4 Oct 2004 20:17:39 -0000       1.5
+++ modules/getusershell        2 May 2005 06:58:37 -0000
@@ -6,6 +6,7 @@ lib/getusershell.c
 m4/getusershell.m4
 
 Depends-on:
+stdio-safer
 xalloc
 
 configure.ac:
@@ -20,4 +21,3 @@ GPL
 
 Maintainer:
 Jim Meyering
-
Index: modules/lstat
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/lstat,v
retrieving revision 1.5
diff -p -u -r1.5 lstat
--- modules/lstat       22 Sep 2004 15:11:04 -0000      1.5
+++ modules/lstat       2 May 2005 06:58:37 -0000
@@ -7,7 +7,6 @@ m4/lstat.m4
 
 Depends-on:
 stat
-xalloc
 
 configure.ac:
 gl_FUNC_LSTAT
@@ -22,4 +21,3 @@ GPL
 
 Maintainer:
 Jim Meyering
-
Index: modules/mkstemp
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/mkstemp,v
retrieving revision 1.5
diff -p -u -r1.5 mkstemp
--- modules/mkstemp     22 Sep 2004 15:11:04 -0000      1.5
+++ modules/mkstemp     2 May 2005 06:58:37 -0000
@@ -11,6 +11,7 @@ m4/uintmax_t.m4
 m4/mkstemp.m4
 
 Depends-on:
+stat-macros
 
 configure.ac:
 gl_FUNC_MKSTEMP
Index: modules/modechange
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/modechange,v
retrieving revision 1.5
diff -p -u -r1.5 modechange
--- modules/modechange  21 Mar 2005 22:07:25 -0000      1.5
+++ modules/modechange  2 May 2005 06:58:37 -0000
@@ -8,7 +8,8 @@ lib/modechange.c
 m4/modechange.m4
 
 Depends-on:
-xstrtol
+stat-macros
+xalloc
 
 configure.ac:
 gl_MODECHANGE
Index: modules/save-cwd
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/save-cwd,v
retrieving revision 1.7
diff -p -u -r1.7 save-cwd
--- modules/save-cwd    18 Jan 2005 21:58:11 -0000      1.7
+++ modules/save-cwd    2 May 2005 06:58:37 -0000
@@ -8,6 +8,7 @@ m4/save-cwd.m4
 
 Depends-on:
 chdir-long
+unistd-safer
 xgetcwd
 
 configure.ac:
Index: modules/stdio-safer
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/stdio-safer,v
retrieving revision 1.4
diff -p -u -r1.4 stdio-safer
--- modules/stdio-safer 22 Sep 2004 15:11:04 -0000      1.4
+++ modules/stdio-safer 2 May 2005 06:58:37 -0000
@@ -13,7 +13,6 @@ configure.ac:
 gl_STDIO_SAFER
 
 Makefile.am:
-lib_SOURCES += stdio-safer.h fopen-safer.c
 
 Include:
 "stdio-safer.h"
@@ -23,4 +22,3 @@ GPL
 
 Maintainer:
 Paul Eggert, Jim Meyering
-
Index: modules/unistd-safer
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/unistd-safer,v
retrieving revision 1.4
diff -p -u -r1.4 unistd-safer
--- modules/unistd-safer        22 Sep 2004 15:11:04 -0000      1.4
+++ modules/unistd-safer        2 May 2005 06:58:37 -0000
@@ -4,6 +4,7 @@ File descriptor functions that avoid clo
 Files:
 lib/unistd-safer.h
 lib/dup-safer.c
+lib/fd-safer.c
 m4/unistd-safer.m4
 
 Depends-on:
@@ -12,7 +13,6 @@ configure.ac:
 gl_UNISTD_SAFER
 
 Makefile.am:
-lib_SOURCES += unistd-safer.h dup-safer.c
 
 Include:
 "unistd-safer.h"
@@ -22,4 +22,3 @@ GPL
 
 Maintainer:
 Paul Eggert, Jim Meyering
-
--- /dev/null   2003-03-18 13:55:57 -0800
+++ lib/fd-safer.c      2005-05-01 21:32:07 -0700
@@ -0,0 +1,61 @@
+/* Return a safer copy of a file descriptor.
+
+   Copyright (C) 2005 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Paul Eggert.  */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "unistd-safer.h"
+
+#include <errno.h>
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Return FD, unless FD would be a copy of standard input, output, or
+   error; in that case, return a duplicate of FD, closing FD.  On
+   failure to duplicate, close FD, set errno, and return -1.  Preserve
+   errno if FD is negative, so that the caller can always inspect
+   errno when the returned value is negative.
+
+   This function is usefully wrapped around functions that return file
+   descriptors, e.g., fd_safer (open ("file", O_RDONLY)).  */
+
+int
+fd_safer (int fd)
+{
+  if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
+    {
+      int f = dup_safer (fd);
+      int e = errno;
+      close (fd);
+      errno = e;
+      fd = f;
+    }
+
+  return fd;
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]