summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog31
-rw-r--r--arscan.c3
-rw-r--r--commands.c4
-rw-r--r--configure.in15
-rw-r--r--dir.c15
-rw-r--r--glob/ChangeLog6
-rw-r--r--glob/glob.h12
-rw-r--r--make.h27
-rw-r--r--misc.c32
-rw-r--r--read.c14
-rw-r--r--remake.c8
-rw-r--r--vpath.c46
12 files changed, 111 insertions, 102 deletions
diff --git a/ChangeLog b/ChangeLog
index ef5bd87..903a64f 100644
--- 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
diff --git a/arscan.c b/arscan.c
index 2c67947..b1e9971 100644
--- 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 */
diff --git a/commands.c b/commands.c
index 30787a4..a6964d5 100644
--- a/commands.c
+++ b/commands.c
@@ -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)
{
diff --git a/configure.in b/configure.in
index 8df2e27..befba08 100644
--- a/configure.in
+++ b/configure.in
@@ -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 39f3e2a..7db0697 100644
--- 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
diff --git a/glob/ChangeLog b/glob/ChangeLog
index 1ebf879..75c6888 100644
--- a/glob/ChangeLog
+++ b/glob/ChangeLog
@@ -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.
diff --git a/glob/glob.h b/glob/glob.h
index 9f735fe..ca523f7 100644
--- a/glob/glob.h
+++ b/glob/glob.h
@@ -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 6648ea0..3ac47d1 100644
--- 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 5305220..ef754e5 100644
--- a/misc.c
+++ b/misc.c
@@ -828,35 +828,3 @@ get_path_max (void)
return value;
}
#endif
-
-
-#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 3e01572..a0bf5ca 100644
--- 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;
diff --git a/remake.c b/remake.c
index db1dd2c..c679d11 100644
--- 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 18aaaa9..5e04d08 100644
--- 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;
}
}