[SV 46261] Add more EINTRLOOP wrappers.

This cannot be a perfect solution because there are always other
possible places EINTR can happen, including external libraries
such as gettext, Guile etc.
This commit is contained in:
Paul Smith 2016-03-05 15:21:59 -05:00
parent e2b39edc22
commit 4f8be4bb28
6 changed files with 80 additions and 56 deletions

View File

@ -420,7 +420,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef SARMAG #ifdef SARMAG
{ {
char buf[SARMAG]; char buf[SARMAG];
register int nread = read (desc, buf, SARMAG); int nread;
EINTRLOOP (nread, read (desc, buf, SARMAG));
if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG)) if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
{ {
(void) close (desc); (void) close (desc);
@ -430,8 +431,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else #else
#ifdef AIAMAG #ifdef AIAMAG
{ {
register int nread = read (desc, &fl_header, FL_HSZ); int nread;
EINTRLOOP (nread, read (desc, &fl_header, FL_HSZ));
if (nread != FL_HSZ) if (nread != FL_HSZ)
{ {
(void) close (desc); (void) close (desc);
@ -442,17 +443,20 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
re-read the header into the "big" structure. */ re-read the header into the "big" structure. */
if (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG)) if (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
{ {
off_t o;
big_archive = 1; big_archive = 1;
/* seek back to beginning of archive */ /* seek back to beginning of archive */
if (lseek (desc, 0, 0) < 0) EINTRLOOP (o, lseek (desc, 0, 0));
if (o < 0)
{ {
(void) close (desc); (void) close (desc);
return -2; return -2;
} }
/* re-read the header into the "big" structure */ /* re-read the header into the "big" structure */
nread = read (desc, &fl_header_big, FL_HSZ_BIG); EINTRLOOP (nread, read (desc, &fl_header_big, FL_HSZ_BIG));
if (nread != FL_HSZ_BIG) if (nread != FL_HSZ_BIG)
{ {
(void) close (desc); (void) close (desc);
@ -475,7 +479,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else #else
unsigned short int buf; unsigned short int buf;
#endif #endif
register int nread = read (desc, &buf, sizeof (buf)); int nread;
EINTRLOOP (nread, read (desc, &buf, sizeof (buf)));
if (nread != sizeof (buf) || buf != ARMAG) if (nread != sizeof (buf) || buf != ARMAG)
{ {
(void) close (desc); (void) close (desc);
@ -544,8 +549,10 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
long int eltsize; long int eltsize;
int eltmode; int eltmode;
long int fnval; long int fnval;
off_t o;
if (lseek (desc, member_offset, 0) < 0) EINTRLOOP (o, lseek (desc, member_offset, 0));
if (o < 0)
{ {
(void) close (desc); (void) close (desc);
return -2; return -2;
@ -557,8 +564,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef AIAMAGBIG #ifdef AIAMAGBIG
if (big_archive) if (big_archive)
{ {
nread = read (desc, &member_header_big, EINTRLOOP (nread, read (desc, &member_header_big,
AR_MEMHDR_SZ(member_header_big) ); AR_MEMHDR_SZ(member_header_big)));
if (nread != AR_MEMHDR_SZ(member_header_big)) if (nread != AR_MEMHDR_SZ(member_header_big))
{ {
@ -567,7 +574,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
} }
sscanf (member_header_big.ar_namlen, "%4d", &name_len); sscanf (member_header_big.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len); EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len) if (nread != name_len)
{ {
@ -589,8 +596,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
else else
#endif #endif
{ {
nread = read (desc, &member_header, EINTRLOOP (nread, read (desc, &member_header,
AR_MEMHDR_SZ(member_header) ); AR_MEMHDR_SZ(member_header)));
if (nread != AR_MEMHDR_SZ(member_header)) if (nread != AR_MEMHDR_SZ(member_header))
{ {
@ -599,7 +606,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
} }
sscanf (member_header.ar_namlen, "%4d", &name_len); sscanf (member_header.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len); EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len) if (nread != name_len)
{ {
@ -627,7 +634,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
eltmode, arg); eltmode, arg);
#else /* Not AIAMAG. */ #else /* Not AIAMAG. */
nread = read (desc, &member_header, AR_HDR_SIZE); EINTRLOOP (nread, read (desc, &member_header, AR_HDR_SIZE));
if (nread == 0) if (nread == 0)
/* No data left means end of file; that is OK. */ /* No data left means end of file; that is OK. */
break; break;
@ -696,7 +703,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
int namesize = atoi (name + 3); int namesize = atoi (name + 3);
name = alloca (namesize + 1); name = alloca (namesize + 1);
nread = read (desc, name, namesize); EINTRLOOP (nread, read (desc, name, namesize));
if (nread != namesize) if (nread != namesize)
{ {
close (desc); close (desc);
@ -767,7 +774,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
char *limit; char *limit;
namemap = alloca (eltsize); namemap = alloca (eltsize);
nread = read (desc, namemap, eltsize); EINTRLOOP (nread, read (desc, namemap, eltsize));
if (nread != eltsize) if (nread != eltsize)
{ {
(void) close (desc); (void) close (desc);
@ -885,7 +892,8 @@ ar_member_touch (const char *arname, const char *memname)
long int pos = ar_scan (arname, ar_member_pos, memname); long int pos = ar_scan (arname, ar_member_pos, memname);
int fd; int fd;
struct ar_hdr ar_hdr; struct ar_hdr ar_hdr;
int i; off_t o;
int r;
unsigned int ui; unsigned int ui;
struct stat statbuf; struct stat statbuf;
@ -894,28 +902,32 @@ ar_member_touch (const char *arname, const char *memname)
if (!pos) if (!pos)
return 1; return 1;
fd = open (arname, O_RDWR, 0666); EINTRLOOP (fd, open (arname, O_RDWR, 0666));
if (fd < 0) if (fd < 0)
return -3; return -3;
/* Read in this member's header */ /* Read in this member's header */
if (lseek (fd, pos, 0) < 0) EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose; goto lose;
if (AR_HDR_SIZE != read (fd, &ar_hdr, AR_HDR_SIZE)) EINTRLOOP (r, read (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose; goto lose;
/* Write back the header, thus touching the archive file. */ /* Write back the header, thus touching the archive file. */
if (lseek (fd, pos, 0) < 0) EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose; goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE)) EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose; goto lose;
/* The file's mtime is the time we we want. */ /* The file's mtime is the time we we want. */
EINTRLOOP (i, fstat (fd, &statbuf)); EINTRLOOP (r, fstat (fd, &statbuf));
if (i < 0) if (r < 0)
goto lose; goto lose;
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32) #if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
/* Advance member's time to that time */ /* Advance member's time to that time */
for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++) for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
ar_hdr.ar_date[ui] = ' '; ar_hdr.ar_date[ui] = ' ';
sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime); sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
#ifdef AIAMAG #ifdef AIAMAG
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' '; ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
#endif #endif
@ -923,17 +935,19 @@ ar_member_touch (const char *arname, const char *memname)
ar_hdr.ar_date = statbuf.st_mtime; ar_hdr.ar_date = statbuf.st_mtime;
#endif #endif
/* Write back this member's header */ /* Write back this member's header */
if (lseek (fd, pos, 0) < 0) EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose; goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE)) EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose; goto lose;
close (fd); close (fd);
return 0; return 0;
lose: lose:
i = errno; r = errno;
close (fd); close (fd);
errno = i; errno = r;
return -3; return -3;
} }
#endif #endif

View File

@ -75,15 +75,10 @@ AC_C_CONST
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_TYPE_UID_T AC_TYPE_UID_T
AC_TYPE_PID_T AC_TYPE_PID_T
AC_TYPE_OFF_T
# Find some definition for uintmax_t AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_CHECK_TYPE([uintmax_t],[], AC_TYPE_UINTMAX_T
[ uintmax_t="unsigned long"
AC_CHECK_TYPE([unsigned long long],[uintmax_t="unsigned long long"])
AC_DEFINE_UNQUOTED([uintmax_t], [$uintmax_t],
[Define uintmax_t if not defined in <stdint.h> or <inttypes.h>.])
])
# Find out whether our struct stat returns nanosecond resolution timestamps. # Find out whether our struct stat returns nanosecond resolution timestamps.

16
job.c
View File

@ -685,7 +685,7 @@ reap_children (int block, int err)
pid = WAIT_NOHANG (&status); pid = WAIT_NOHANG (&status);
else else
#endif #endif
EINTRLOOP(pid, wait (&status)); EINTRLOOP (pid, wait (&status));
#endif /* !VMS */ #endif /* !VMS */
} }
else else
@ -1999,7 +1999,7 @@ new_job (struct file *file)
if (job_rfd < 0) if (job_rfd < 0)
{ {
DB (DB_JOBS, ("Duplicate the job FD\n")); DB (DB_JOBS, ("Duplicate the job FD\n"));
job_rfd = dup (job_fds[0]); EINTRLOOP (job_rfd, dup (job_fds[0]));
} }
#endif #endif
@ -2036,7 +2036,7 @@ new_job (struct file *file)
#else #else
/* Set interruptible system calls, and read() for a job token. */ /* Set interruptible system calls, and read() for a job token. */
set_child_handler_action_flags (1, waiting_jobs != NULL); set_child_handler_action_flags (1, waiting_jobs != NULL);
got_token = read (job_rfd, &token, 1); EINTRLOOP (got_token, read (job_rfd, &token, 1));
saved_errno = errno; saved_errno = errno;
set_child_handler_action_flags (0, waiting_jobs != NULL); set_child_handler_action_flags (0, waiting_jobs != NULL);
#endif #endif
@ -2352,17 +2352,19 @@ void
child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd, child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp) char **argv, char **envp)
{ {
int r;
/* For any redirected FD, dup2() it to the standard FD then close it. */ /* For any redirected FD, dup2() it to the standard FD then close it. */
if (stdin_fd != FD_STDIN) if (stdin_fd != FD_STDIN)
{ {
dup2 (stdin_fd, FD_STDIN); EINTRLOOP (r, dup2 (stdin_fd, FD_STDIN));
close (stdin_fd); close (stdin_fd);
} }
if (stdout_fd != FD_STDOUT) if (stdout_fd != FD_STDOUT)
dup2 (stdout_fd, FD_STDOUT); EINTRLOOP (r, dup2 (stdout_fd, FD_STDOUT));
if (stderr_fd != FD_STDERR) if (stderr_fd != FD_STDERR)
dup2 (stderr_fd, FD_STDERR); EINTRLOOP (r, dup2 (stderr_fd, FD_STDERR));
if (stdout_fd != FD_STDOUT) if (stdout_fd != FD_STDOUT)
close (stdout_fd); close (stdout_fd);
@ -3690,7 +3692,7 @@ dup2 (int old, int new)
int fd; int fd;
(void) close (new); (void) close (new);
fd = dup (old); EINTRLOOP (fd, dup (old));
if (fd != new) if (fd != new)
{ {
(void) close (fd); (void) close (fd);

10
main.c
View File

@ -3488,8 +3488,14 @@ clean_jobserver (int status)
/* Close the write side, so the read() won't hang. */ /* Close the write side, so the read() won't hang. */
close (job_fds[1]); close (job_fds[1]);
while (read (job_fds[0], &token, 1) == 1) while (1)
++tcnt; {
int r;
EINTRLOOP (r, read (job_fds[0], &token, 1));
if (r != 1)
break;
++tcnt;
}
#endif #endif
if (tcnt != master_job_slots) if (tcnt != master_job_slots)

View File

@ -441,7 +441,7 @@ output_tmpfile (char **name, const char *template)
# ifdef HAVE_FDOPEN # ifdef HAVE_FDOPEN
/* Can't use mkstemp(), but guard against a race condition. */ /* Can't use mkstemp(), but guard against a race condition. */
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600); EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
if (fd == -1) if (fd == -1)
return 0; return 0;
return fdopen (fd, "w"); return fdopen (fd, "w");

View File

@ -1158,8 +1158,9 @@ touch_file (struct file *file)
else else
#endif #endif
{ {
int fd = open (file->name, O_RDWR | O_CREAT, 0666); int fd;
EINTRLOOP (fd, open (file->name, O_RDWR | O_CREAT, 0666));
if (fd < 0) if (fd < 0)
TOUCH_ERROR ("touch: open: "); TOUCH_ERROR ("touch: open: ");
else else
@ -1172,18 +1173,24 @@ touch_file (struct file *file)
if (e < 0) if (e < 0)
TOUCH_ERROR ("touch: fstat: "); TOUCH_ERROR ("touch: fstat: ");
/* Rewrite character 0 same as it already is. */ /* Rewrite character 0 same as it already is. */
if (read (fd, &buf, 1) < 0) EINTRLOOP (e, read (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: read: "); TOUCH_ERROR ("touch: read: ");
if (lseek (fd, 0L, 0) < 0L) {
TOUCH_ERROR ("touch: lseek: "); off_t o;
if (write (fd, &buf, 1) < 0) EINTRLOOP (o, lseek (fd, 0L, 0));
if (o < 0L)
TOUCH_ERROR ("touch: lseek: ");
}
EINTRLOOP (e, write (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: write: "); TOUCH_ERROR ("touch: write: ");
/* If file length was 0, we just
changed it, so change it back. */ /* If file length was 0, we just changed it, so change it back. */
if (statbuf.st_size == 0) if (statbuf.st_size == 0)
{ {
(void) close (fd); (void) close (fd);
fd = open (file->name, O_RDWR | O_TRUNC, 0666); EINTRLOOP (fd, open (file->name, O_RDWR | O_TRUNC, 0666));
if (fd < 0) if (fd < 0)
TOUCH_ERROR ("touch: open: "); TOUCH_ERROR ("touch: open: ");
} }