Fix SIGINFO botch (PR #8868).
Continue partial write(2) on signals (xwrite()). Partial read(2) at a few places are also continued (xread()). Add {read,write}_with_restart() hooks for porting on systems which don't restart interrupted read()/write() calls. Reviewed and discussed in tech-kern and tech-userlevel lists.
This commit is contained in:
parent
f30d8c9d30
commit
ba0ae447ef
144
bin/pax/ar_io.c
144
bin/pax/ar_io.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $ */
|
||||
/* $NetBSD: ar_io.c,v 1.15 2000/02/17 03:06:12 itohy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $");
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.15 2000/02/17 03:06:12 itohy Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -438,7 +438,7 @@ ar_drain()
|
|||
/*
|
||||
* keep reading until pipe is drained
|
||||
*/
|
||||
while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
|
||||
while ((res = read_with_restart(arfd, drbuf, sizeof(drbuf))) > 0)
|
||||
;
|
||||
lstrval = res;
|
||||
}
|
||||
|
@ -518,6 +518,132 @@ ar_app_ok()
|
|||
return(-1);
|
||||
}
|
||||
|
||||
#ifdef SYS_NO_RESTART
|
||||
/*
|
||||
* read_with_restart()
|
||||
* Equivalent to read() but does retry on signals.
|
||||
* This function is not needed on 4.2BSD and later.
|
||||
* Return:
|
||||
* Number of bytes written. -1 indicates an error.
|
||||
*/
|
||||
|
||||
#if __STDC__
|
||||
int
|
||||
read_with_restart(int fd, void *buf, int bsz)
|
||||
#else
|
||||
int
|
||||
read_with_restart(fd, buf, bsz)
|
||||
int fd;
|
||||
void *buf;
|
||||
int bsz;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
while (((r = read(fd, buf, bsz)) < 0) && errno == EINTR)
|
||||
;
|
||||
|
||||
return(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xread()
|
||||
* Equivalent to read() but does retry on partial read, which may occur
|
||||
* on signals.
|
||||
* Return:
|
||||
* Number of bytes read. 0 for end of file, -1 for an error.
|
||||
*/
|
||||
|
||||
#if __STDC__
|
||||
int
|
||||
xread(int fd, void *buf, int bsz)
|
||||
#else
|
||||
int
|
||||
xread(fd, buf, bsz)
|
||||
int fd;
|
||||
void *buf;
|
||||
int bsz;
|
||||
#endif
|
||||
{
|
||||
char *b = buf;
|
||||
int nread = 0;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if ((r = read_with_restart(fd, b, bsz)) <= 0)
|
||||
break;
|
||||
b += r;
|
||||
bsz -= r;
|
||||
nread += r;
|
||||
} while (bsz > 0);
|
||||
|
||||
return(nread ? nread : r);
|
||||
}
|
||||
|
||||
#ifdef SYS_NO_RESTART
|
||||
/*
|
||||
* write_with_restart()
|
||||
* Equivalent to write() but does retry on signals.
|
||||
* This function is not needed on 4.2BSD and later.
|
||||
* Return:
|
||||
* Number of bytes written. -1 indicates an error.
|
||||
*/
|
||||
|
||||
#if __STDC__
|
||||
int
|
||||
write_with_restart(int fd, void *buf, int bsz)
|
||||
#else
|
||||
int
|
||||
write_with_restart(fd, buf, bsz)
|
||||
int fd;
|
||||
void *buf;
|
||||
int bsz;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
while (((r = write(fd, buf, bsz)) < 0) && errno == EINTR)
|
||||
;
|
||||
|
||||
return(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xwrite()
|
||||
* Equivalent to write() but does retry on partial write, which may occur
|
||||
* on signals.
|
||||
* Return:
|
||||
* Number of bytes written. -1 indicates an error.
|
||||
*/
|
||||
|
||||
#if __STDC__
|
||||
int
|
||||
xwrite(int fd, void *buf, int bsz)
|
||||
#else
|
||||
int
|
||||
xwrite(fd, buf, bsz)
|
||||
int fd;
|
||||
void *buf;
|
||||
int bsz;
|
||||
#endif
|
||||
{
|
||||
char *b = buf;
|
||||
int written = 0;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if ((r = write_with_restart(fd, b, bsz)) <= 0)
|
||||
break;
|
||||
b += r;
|
||||
bsz -= r;
|
||||
written += r;
|
||||
} while (bsz > 0);
|
||||
|
||||
return(written ? written : r);
|
||||
}
|
||||
|
||||
/*
|
||||
* ar_read()
|
||||
* read up to a specified number of bytes from the archive into the
|
||||
|
@ -550,7 +676,7 @@ ar_read(buf, cnt)
|
|||
*/
|
||||
switch (artyp) {
|
||||
case ISTAPE:
|
||||
if ((res = read(arfd, buf, cnt)) > 0) {
|
||||
if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
|
||||
/*
|
||||
* CAUTION: tape systems may not always return the same
|
||||
* sized records so we leave blksz == MAXBLK. The
|
||||
|
@ -588,7 +714,7 @@ ar_read(buf, cnt)
|
|||
* and return. Trying to do anything else with them runs the
|
||||
* risk of failure.
|
||||
*/
|
||||
if ((res = read(arfd, buf, cnt)) > 0) {
|
||||
if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
|
||||
io_ok = 1;
|
||||
return(res);
|
||||
}
|
||||
|
@ -637,7 +763,7 @@ ar_write(buf, bsz)
|
|||
if (lstrval <= 0)
|
||||
return(lstrval);
|
||||
|
||||
if ((res = write(arfd, buf, bsz)) == bsz) {
|
||||
if ((res = xwrite(arfd, buf, bsz)) == bsz) {
|
||||
wr_trail = 1;
|
||||
io_ok = 1;
|
||||
return(bsz);
|
||||
|
@ -1064,7 +1190,7 @@ get_phys()
|
|||
* we know we are at file mark when we get back a 0 from
|
||||
* read()
|
||||
*/
|
||||
while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
while ((res = read_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
padsz += res;
|
||||
if (res < 0) {
|
||||
syswarn(1, errno, "Unable to locate tape filemark.");
|
||||
|
@ -1093,7 +1219,7 @@ get_phys()
|
|||
syswarn(1, errno, "Unable to backspace over last tape block.");
|
||||
return(-1);
|
||||
}
|
||||
if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
|
||||
if ((phyblk = read_with_restart(arfd, scbuf, sizeof(scbuf))) <= 0) {
|
||||
syswarn(1, errno, "Cannot determine archive tape blocksize.");
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1102,7 +1228,7 @@ get_phys()
|
|||
* read foward to the file mark, then back up in front of the filemark
|
||||
* (this is a bit paranoid, but should be safe to do).
|
||||
*/
|
||||
while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
while ((res = read_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
;
|
||||
if (res < 0) {
|
||||
syswarn(1, errno, "Unable to locate tape filemark.");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $ */
|
||||
/* $NetBSD: buf_subs.c,v 1.12 2000/02/17 03:06:13 itohy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)buf_subs.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $");
|
||||
__RCSID("$NetBSD: buf_subs.c,v 1.12 2000/02/17 03:06:13 itohy Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -699,7 +699,7 @@ wr_rdfile(arcn, ifd, left)
|
|||
return(-1);
|
||||
}
|
||||
cnt = MIN(cnt, size);
|
||||
if ((res = read(ifd, bufpt, cnt)) <= 0)
|
||||
if ((res = read_with_restart(ifd, bufpt, cnt)) <= 0)
|
||||
break;
|
||||
size -= res;
|
||||
bufpt += res;
|
||||
|
@ -884,10 +884,10 @@ cp_file(arcn, fd1, fd2)
|
|||
* read the source file and copy to destination file until EOF
|
||||
*/
|
||||
for(;;) {
|
||||
if ((cnt = read(fd1, buf, blksz)) <= 0)
|
||||
if ((cnt = read_with_restart(fd1, buf, blksz)) <= 0)
|
||||
break;
|
||||
if (no_hole)
|
||||
res = write(fd2, buf, cnt);
|
||||
res = xwrite(fd2, buf, cnt);
|
||||
else
|
||||
res = file_write(fd2, buf, cnt, &rem, &isem, sz, fnm);
|
||||
if (res != cnt)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.20 1999/11/01 01:35:58 mrg Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.21 2000/02/17 03:06:13 itohy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -57,6 +57,15 @@ void ar_close __P((void));
|
|||
void ar_drain __P((void));
|
||||
int ar_set_wr __P((void));
|
||||
int ar_app_ok __P((void));
|
||||
#ifdef SYS_NO_RESTART
|
||||
int read_with_restart __P((int, void *, int));
|
||||
int write_with_restart __P((int, void *, int));
|
||||
#else
|
||||
#define read_with_restart read
|
||||
#define write_with_restart write
|
||||
#endif
|
||||
int xread __P((int, void *, int));
|
||||
int xwrite __P((int, void *, int));
|
||||
int ar_read __P((char *, int));
|
||||
int ar_write __P((char *, int));
|
||||
int ar_rdsync __P((void));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: file_subs.c,v 1.15 1999/11/07 15:48:24 mycroft Exp $ */
|
||||
/* $NetBSD: file_subs.c,v 1.16 2000/02/17 03:06:13 itohy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.15 1999/11/07 15:48:24 mycroft Exp $");
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.16 2000/02/17 03:06:13 itohy Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -948,7 +948,7 @@ file_write(fd, str, cnt, rem, isempt, sz, name)
|
|||
}
|
||||
strncpy(gnu_hack_string, st, wcnt);
|
||||
gnu_hack_string[wcnt] = 0;
|
||||
} else if (write(fd, st, wcnt) != wcnt) {
|
||||
} else if (xwrite(fd, st, wcnt) != wcnt) {
|
||||
syswarn(1, errno, "Failed write to file %s", name);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -992,7 +992,7 @@ file_flush(fd, fname, isempt)
|
|||
return;
|
||||
}
|
||||
|
||||
if (write(fd, blnk, 1) < 0)
|
||||
if (write_with_restart(fd, blnk, 1) < 0)
|
||||
syswarn(1, errno, "Failed write to file %s", fname);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tables.c,v 1.10 1999/11/01 01:35:59 mrg Exp $ */
|
||||
/* $NetBSD: tables.c,v 1.11 2000/02/17 03:06:13 itohy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tables.c,v 1.10 1999/11/01 01:35:59 mrg Exp $");
|
||||
__RCSID("$NetBSD: tables.c,v 1.11 2000/02/17 03:06:13 itohy Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -446,7 +446,7 @@ chk_ftime(arcn)
|
|||
"Failed ftime table seek");
|
||||
return(-1);
|
||||
}
|
||||
if (read(ffd, ckname, namelen) != namelen) {
|
||||
if (xread(ffd, ckname, namelen) != namelen) {
|
||||
syswarn(1, errno,
|
||||
"Failed ftime table read");
|
||||
return(-1);
|
||||
|
@ -492,7 +492,7 @@ chk_ftime(arcn)
|
|||
* offset. add the file to the head of the hash chain
|
||||
*/
|
||||
if ((pt->seek = lseek(ffd, (off_t)0, SEEK_END)) >= 0) {
|
||||
if (write(ffd, arcn->name, namelen) == namelen) {
|
||||
if (xwrite(ffd, arcn->name, namelen) == namelen) {
|
||||
pt->mtime = arcn->sb.st_mtime;
|
||||
pt->namelen = namelen;
|
||||
pt->fow = ftab[indx];
|
||||
|
@ -1288,8 +1288,8 @@ add_dir(name, nlen, psb, frc_mode)
|
|||
dblk.atime = psb->st_atime;
|
||||
dblk.fflags = psb->st_flags;
|
||||
dblk.frc_mode = frc_mode;
|
||||
if ((write(dirfd, name, dblk.nlen) == dblk.nlen) &&
|
||||
(write(dirfd, (char *)&dblk, sizeof(dblk)) == sizeof(dblk))) {
|
||||
if ((xwrite(dirfd, name, dblk.nlen) == dblk.nlen) &&
|
||||
(xwrite(dirfd, (char *)&dblk, sizeof(dblk)) == sizeof(dblk))) {
|
||||
++dircnt;
|
||||
return;
|
||||
}
|
||||
|
@ -1329,11 +1329,11 @@ proc_dir()
|
|||
*/
|
||||
if (lseek(dirfd, -((off_t)sizeof(dblk)), SEEK_CUR) < 0)
|
||||
break;
|
||||
if (read(dirfd,(char *)&dblk, sizeof(dblk)) != sizeof(dblk))
|
||||
if (xread(dirfd,(char *)&dblk, sizeof(dblk)) != sizeof(dblk))
|
||||
break;
|
||||
if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
|
||||
break;
|
||||
if (read(dirfd, name, dblk.nlen) != dblk.nlen)
|
||||
if (xread(dirfd, name, dblk.nlen) != dblk.nlen)
|
||||
break;
|
||||
if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue