]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Portability fix for glob.h building in FreeBSD ports system.
authorPaul Smith <psmith@gnu.org>
Thu, 30 Jan 2003 05:22:52 +0000 (05:22 +0000)
committerPaul Smith <psmith@gnu.org>
Thu, 30 Jan 2003 05:22:52 +0000 (05:22 +0000)
Implement a fix for bug # 2169: too many OSs, even major OSs like Solaris,
don't properly implement SA_RESTART: important system calls like stat() can
still fail when SA_RESTART is set.  So, forget the BROKEN_RESTART config
check and get rid of atomic_stat() and atomic_readdir(), and implement
permanent wrappers for EINTR checking on various system calls (stat(),
fstat(), opendir(), and readdir() so far).

12 files changed:
ChangeLog
arscan.c
commands.c
configure.in
dir.c
glob/ChangeLog
glob/glob.h
make.h
misc.c
read.c
remake.c
vpath.c

index ef5bd87d9e5d7f8ceaebdbfcc8e9569f513489f2..903a64faafddfbfc33a5f703d8cbc2634026a322 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2003-01-29  Paul D. Smith  <psmith@gnu.org>
+
+       Fix bug # 2169, also reported by other people on various systems.
+
+       * make.h: Some systems, such as Solaris and PTX, do not fully
+       implement POSIX-compliant SA_RESTART functionality; important
+       system calls like stat() and readdir() can still fail with EINTR
+       even if SA_RESTART has been set on the signal handler.  So,
+       introduce macros EINTRLOOP() and ENULLLOOP() which can loop on
+       EINTR for system calls which return -1 or 0 (NULL), respectively,
+       on error.
+       Also, remove the old atomic_stat()/atomic_readdir() and
+       HAVE_BROKEN_RESTART handling.
+
+       * configure.in: Remove setting of HAVE_BROKEN_RESTART.
+
+       * arscan.c (ar_member_touch): Use EINTRLOOP() to wrap fstat().
+       * remake.c (touch_file): Ditto.
+
+       * commands.c (delete_target): Use EINTRLOOP() to wrap stat().
+       * read.c (construct_include_path): Ditto.
+       * remake.c (name_mtime): Ditto.
+       * vpath.c (selective_vpath_search): Ditto.
+       * dir.c (find_directory): Ditto.
+       (local_stat): Ditto.
+       (find_directory): Use ENULLLOOP() to wrap opendir().
+       (dir_contents_file_exists_p): Use ENULLLOOP() to wrap readdir().
+
+       * misc.c: Remove HAVE_BROKEN_RESTART, atomic_stat(), and
+       atomic_readdir() handling.
+
 2003-01-22  Paul D. Smith  <psmith@gnu.org>
 
        * function.c (func_call): Fix Bug #1744.  If we're inside a
index 2c679471012288e5677b994930665843dd3f77ec..b1e9971a79823d4afb4c88f814b7ebb516bbaa78 100644 (file)
--- a/arscan.c
+++ b/arscan.c
@@ -781,7 +781,8 @@ ar_member_touch (char *arname, char *memname)
   if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
     goto lose;
   /* The file's mtime is the time we we want.  */
-  if (fstat (fd, &statbuf) < 0)
+  EINTRLOOP (i, fstat (fd, &statbuf));
+  if (i < 0)
     goto lose;
 #if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
   /* Advance member's time to that time */
index 30787a45edc81a25e153e60355ee6029cd1a6b7e..a6964d5566aba451a6dc87846e13f53eea7317e8 100644 (file)
@@ -492,6 +492,7 @@ static void
 delete_target (struct file *file, char *on_behalf_of)
 {
   struct stat st;
+  int e;
 
   if (file->precious || file->phony)
     return;
@@ -515,7 +516,8 @@ delete_target (struct file *file, char *on_behalf_of)
     }
 #endif
 
-  if (stat (file->name, &st) == 0
+  EINTRLOOP (e, stat (file->name, &st));
+  if (e == 0
       && S_ISREG (st.st_mode)
       && FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
     {
index 8df2e272213ce59492ed829370a48608d686b5a8..befba089c725a1aae89e43e5bf74046bf9a60eb7 100644 (file)
@@ -294,21 +294,6 @@ make_cv_sys_gnu_glob=no])])
 # Tell automake about this, so it can build the right .c files.
 AM_CONDITIONAL(USE_LOCAL_GLOB, test "$make_cv_sys_gnu_glob" = no)
 
-# PTX systems have a broken implementation of SA_RESTART.  I know of
-# no way to test for this behavior, so I'll just test for PTX
-
-case "$host" in
-  i386-sequent-sysv4)
-    AC_DEFINE(HAVE_BROKEN_RESTART, 1, [This system has SA_RESTART, but it doesn't work properly.])
-    echo ""
-    echo "WARNING: The SA_RESTART sigaction() flag does not work on PTX."
-    echo "         This causes 'make -j' to fail at random times."
-    echo "         I am installing a workaround, which is mostly but not 100%"
-    echo "         effective.  If you see random failures during 'make -j'"
-    echo "         you should either contact the bug list, or not use -j."
-    echo "" ;;
-esac
-
 # Let the makefile know what our build host is
 
 AC_DEFINE_UNQUOTED(MAKE_HOST,"$host",[Build host information.])
diff --git a/dir.c b/dir.c
index 39f3e2af2df80658300272845e8d3e47a20e7035..7db0697773d32fc81abde9b84513a5b23138f596 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -455,7 +455,7 @@ find_directory (char *name)
 #ifdef VMS
       r = vmsstat_dir (name, &st);
 #else
-      r = stat (name, &st);
+      EINTRLOOP (r, stat (name, &st));
 #endif
 
 #ifdef WINDOWS32
@@ -536,7 +536,7 @@ find_directory (char *name)
 # endif
 #endif /* WINDOWS32 */
              hash_insert_at (&directory_contents, dc, dc_slot);
-             dc->dirstream = opendir (name);
+             ENULLLOOP (dc->dirstream, opendir (name));
              if (dc->dirstream == 0)
                 /* Couldn't open the directory.  Mark this by
                    setting the `files' member to a nil pointer.  */
@@ -645,13 +645,17 @@ dir_contents_file_exists_p (struct directory_contents *dir, char *filename)
        return 0;
     }
 
-  while ((d = readdir (dir->dirstream)) != 0)
+  while (1)
     {
       /* Enter the file in the hash table.  */
       unsigned int len;
       struct dirfile dirfile_key;
       struct dirfile **dirfile_slot;
 
+      ENULLLOOP (d, readdir (dir->dirstream));
+      if (d == 0)
+        break;
+
 #if defined(VMS) && defined(HAVE_DIRENT_H)
       /* In VMS we get file versions too, which have to be stripped off */
       {
@@ -1155,7 +1159,10 @@ extern int stat PARAMS ((const char *path, struct stat *sbuf));
 static int
 local_stat (const char *path, struct stat *buf)
 {
-  return stat (path, buf);
+  int e;
+
+  EINTRLOOP (e, stat (path, buf));
+  return e;
 }
 #endif
 
index 1ebf879bde3e938dfd6eff8c97704eb56fa24d62..75c688816d5436448f9e7211561e6006b88a8b7e 100644 (file)
@@ -1,3 +1,9 @@
+2003-01-30  Paul D. Smith  <psmith@gnu.org>
+
+       * glob.h: Patch for FreeBSD by Mike Barcroft <mike@freebsd.org>
+       Reported by Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>.  On
+       FreeBSD, declare __size_t to simply size_t.
+
 2002-04-22  Paul D. Smith  <psmith@gnu.org>
 
        * Makefile.am: Use automake 1.6.
index 9f735fe8aec56107ec261261d4c749c53c480343..ca523f7a2f85192e69939d52fcaf163cc2358e87 100644 (file)
@@ -47,9 +47,12 @@ extern "C" {
 
 /* We need `size_t' for the following definitions.  */
 #ifndef __size_t
-# if defined __GNUC__ && __GNUC__ >= 2
-typedef __SIZE_TYPE__ __size_t;
+# if defined __FreeBSD__
+#  define __size_t size_t
 # else
+#  if defined __GNUC__ && __GNUC__ >= 2
+typedef __SIZE_TYPE__ __size_t;
+#  else
 /* This is a guess.  */
 /*hb
  *     Conflicts with DECCs aready defined type __size_t.
@@ -57,9 +60,10 @@ typedef __SIZE_TYPE__ __size_t;
  *     Anyway if DECC is used and __SIZE_T is defined then __size_t is
  *     already defined (and I hope it's exactly the one we need here).
  */
-#if !(defined __DECC && defined __SIZE_T)
+#   if !(defined __DECC && defined __SIZE_T)
 typedef unsigned long int __size_t;
-#endif
+#   endif
+#  endif
 # endif
 #else
 /* The GNU CC stddef.h version defines __size_t as empty.  We need a real
diff --git a/make.h b/make.h
index 6648ea0dbac7c74502ea0bce4e371b56c0a2a27a..3ac47d137da2d3f7f7029ea51596e54fdb85c430 100644 (file)
--- a/make.h
+++ b/make.h
@@ -539,24 +539,13 @@ extern int handling_fatal_signal;
 #endif
 
 
-/* If we have broken SA_RESTART support, then wrap stat() and readdir() with
-   versions that handle EINTR.  Note that there are still plenty of system
-   calls that can fail with EINTR but this, reportedly, gets the vast
-   majority of failure cases.  If you still experience failures you'll need
-   to either get a system where SA_RESTART works, or you need to avoid -j.  */
+/* Some systems (like Solaris, PTX, etc.) do not support the SA_RESTART flag
+   properly according to POSIX.  So, we try to wrap common system calls with
+   checks for EINTR.  Note that there are still plenty of system calls that
+   can fail with EINTR but this, reportedly, gets the vast majority of
+   failure cases.  If you still experience failures you'll need to either get
+   a system where SA_RESTART works, or you need to avoid -j.  */
 
-#ifdef HAVE_BROKEN_RESTART
+#define EINTRLOOP(_v,_c)   while (((_v)=_c)==-1 && errno==EINTR)
 
-/* Here we make an assumption that a system with a broken SA_RESTART has
-   dirent.h.  Right now the only system I know of in this category is PTX, and
-   it does have dirent.h.
-*/
-#include <dirent.h>
-
-#define stat(_f,_b)     atomic_stat ((_f), (_b))
-#define readdir(_d)     atomic_readdir (_d)
-
-extern int atomic_stat PARAMS ((const char *file, struct stat *buf));
-extern struct dirent *atomic_readdir PARAMS ((DIR *dir));
-
-#endif
+#define ENULLLOOP(_v,_c)   while (((_v)=_c)==0 && errno==EINTR)
diff --git a/misc.c b/misc.c
index 5305220f9c79e3e2ea485d9517303ae941f96555..ef754e50a51d625dd6d202d2db205dfeed9862f1 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -828,35 +828,3 @@ get_path_max (void)
   return value;
 }
 #endif
-\f
-
-#ifdef HAVE_BROKEN_RESTART
-
-#undef stat
-#undef readdir
-
-int
-atomic_stat (const char *file, struct stat *buf)
-{
-  int r;
-
-  while ((r = stat (file, buf)) < 0)
-    if (errno != EINTR)
-      break;
-
-  return r;
-}
-
-struct dirent *
-atomic_readdir (DIR *dir)
-{
-  struct dirent *r;
-
-  while ((r = readdir (dir)) == NULL)
-    if (errno != EINTR)
-      break;
-
-  return r;
-}
-
-#endif  /* HAVE_BROKEN_RESTART */
diff --git a/read.c b/read.c
index 3e0157202e4fb16fee40e1280fb0b5337a03cab2..a0bf5caa834e340e6c498ef159cd80bf855112f1 100644 (file)
--- a/read.c
+++ b/read.c
@@ -2819,6 +2819,7 @@ construct_include_path (char **arg_dirs)
     while (*arg_dirs != 0)
       {
        char *dir = *arg_dirs++;
+        int e;
 
        if (dir[0] == '~')
          {
@@ -2827,7 +2828,8 @@ construct_include_path (char **arg_dirs)
              dir = expanded;
          }
 
-       if (stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
+        EINTRLOOP (e, stat (dir, &stbuf));
+       if (e == 0 && S_ISDIR (stbuf.st_mode))
          {
            if (idx == max - 1)
              {
@@ -2860,9 +2862,13 @@ construct_include_path (char **arg_dirs)
 #endif
 
   for (i = 0; default_include_directories[i] != 0; ++i)
-    if (stat (default_include_directories[i], &stbuf) == 0
-       && S_ISDIR (stbuf.st_mode))
-      dirs[idx++] = default_include_directories[i];
+    {
+      int e;
+
+      EINTRLOOP (e, stat (default_include_directories[i], &stbuf));
+      if (e == 0 && S_ISDIR (stbuf.st_mode))
+        dirs[idx++] = default_include_directories[i];
+    }
 
   dirs[idx] = 0;
 
index db1dd2c3ba04f34f2926b8b264d741319eac6398..c679d11128e0293511ac4ec16691537ef1843d28 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -961,8 +961,10 @@ touch_file (struct file *file)
        {
          struct stat statbuf;
          char buf;
+          int e;
 
-         if (fstat (fd, &statbuf) < 0)
+          EINTRLOOP (e, fstat (fd, &statbuf));
+         if (e < 0)
            TOUCH_ERROR ("touch: fstat: ");
          /* Rewrite character 0 same as it already is.  */
          if (read (fd, &buf, 1) < 0)
@@ -1257,8 +1259,10 @@ static FILE_TIMESTAMP
 name_mtime (char *name)
 {
   struct stat st;
+  int e;
 
-  if (stat (name, &st) != 0)
+  EINTRLOOP (e, stat (name, &st));
+  if (e != 0)
     {
       if (errno != ENOENT && errno != ENOTDIR)
         perror_with_name ("stat:", name);
diff --git a/vpath.c b/vpath.c
index 18aaaa96b815f5dacb6814d600d2442c1697b97a..5e04d08565e4f20fe715c943475df8c87e88a8a3 100644 (file)
--- a/vpath.c
+++ b/vpath.c
@@ -507,27 +507,33 @@ selective_vpath_search (struct vpath *path, char **file,
          *n = '/';
 #endif
 
-         if (!exists_in_cache  /* Makefile-mentioned file need not exist.  */
-             || stat (name, &st) == 0) /* Does it really exist?  */
+         if (exists_in_cache)  /* Makefile-mentioned file need not exist.  */
            {
-             /* We have found a file.
-                Store the name we found into *FILE for the caller.  */
-
-             *file = savestring (name, (n + 1 - name) + flen);
-
-             if (mtime_ptr != 0)
-               /* Store the modtime into *MTIME_PTR for the caller.
-                  If we have had no need to stat the file here,
-                  we record UNKNOWN_MTIME to indicate this.  */
-               *mtime_ptr = (exists_in_cache
-                             ? FILE_TIMESTAMP_STAT_MODTIME (name, st)
-                             : UNKNOWN_MTIME);
-
-             free (name);
-             return 1;
-           }
-         else
-           exists = 0;
+              int e;
+
+              EINTRLOOP (e, stat (name, &st)); /* Does it really exist?  */
+              if (e != 0)
+                {
+                  exists = 0;
+                  continue;
+                }
+            }
+
+          /* We have found a file.
+             Store the name we found into *FILE for the caller.  */
+
+          *file = savestring (name, (n + 1 - name) + flen);
+
+          if (mtime_ptr != 0)
+            /* Store the modtime into *MTIME_PTR for the caller.
+               If we have had no need to stat the file here,
+               we record UNKNOWN_MTIME to indicate this.  */
+            *mtime_ptr = (exists_in_cache
+                          ? FILE_TIMESTAMP_STAT_MODTIME (name, st)
+                          : UNKNOWN_MTIME);
+
+          free (name);
+          return 1;
        }
     }