+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
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 */
delete_target (struct file *file, char *on_behalf_of)
{
struct stat st;
+ int e;
if (file->precious || file->phony)
return;
}
#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)
{
# 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.])
#ifdef VMS
r = vmsstat_dir (name, &st);
#else
- r = stat (name, &st);
+ EINTRLOOP (r, stat (name, &st));
#endif
#ifdef WINDOWS32
# 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. */
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 */
{
static int
local_stat (const char *path, struct stat *buf)
{
- return stat (path, buf);
+ int e;
+
+ EINTRLOOP (e, stat (path, buf));
+ return e;
}
#endif
+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.
/* 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.
* 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
#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)
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 */
while (*arg_dirs != 0)
{
char *dir = *arg_dirs++;
+ int e;
if (dir[0] == '~')
{
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)
{
#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;
{
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)
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);
*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;
}
}