mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-02-04 13:55:45 +00:00
Portability fix for glob.h building in FreeBSD ports system.
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).
This commit is contained in:
parent
d15a484098
commit
d33ff30145
12 changed files with 108 additions and 99 deletions
31
ChangeLog
31
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
|
||||
|
|
3
arscan.c
3
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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
15
configure.in
15
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.])
|
||||
|
|
15
dir.c
15
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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
12
glob/glob.h
12
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
|
||||
|
|
27
make.h
27
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)
|
||||
|
|
32
misc.c
32
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 */
|
||||
|
|
14
read.c
14
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;
|
||||
|
||||
|
|
8
remake.c
8
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);
|
||||
|
|
40
vpath.c
40
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. */
|
||||
int e;
|
||||
|
||||
*file = savestring (name, (n + 1 - name) + flen);
|
||||
EINTRLOOP (e, stat (name, &st)); /* Does it really exist? */
|
||||
if (e != 0)
|
||||
{
|
||||
exists = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
/* We have found a file.
|
||||
Store the name we found into *FILE for the caller. */
|
||||
|
||||
free (name);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
exists = 0;
|
||||
*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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue