diff --git a/src/arscan.c b/src/arscan.c index 22c5438f..94879171 100644 --- a/src/arscan.c +++ b/src/arscan.c @@ -425,7 +425,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) { char buf[SARMAG]; int nread; - EINTRLOOP (nread, read (desc, buf, SARMAG)); + nread = readbuf (desc, buf, SARMAG); if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG)) goto invalid; } @@ -433,7 +433,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) #ifdef AIAMAG { int nread; - EINTRLOOP (nread, read (desc, &fl_header, FL_HSZ)); + nread = readbuf (desc, &fl_header, FL_HSZ); if (nread != FL_HSZ) goto invalid; @@ -452,7 +452,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) goto invalid; /* re-read the header into the "big" structure */ - EINTRLOOP (nread, read (desc, &fl_header_big, FL_HSZ_BIG)); + nread = readbuf (desc, &fl_header_big, FL_HSZ_BIG); if (nread != FL_HSZ_BIG) goto invalid; } @@ -470,7 +470,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) unsigned short int buf; #endif int nread; - EINTRLOOP (nread, read (desc, &buf, sizeof (buf))); + nread = readbuf (desc, &buf, sizeof (buf)); if (nread != sizeof (buf) || buf != ARMAG) goto invalid; } @@ -550,8 +550,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) #ifdef AIAMAGBIG if (big_archive) { - EINTRLOOP (nread, read (desc, &member_header_big, - AR_MEMHDR_SZ(member_header_big))); + nread = readbuf (desc, &member_header_big, + AR_MEMHDR_SZ(member_header_big)); if (nread != AR_MEMHDR_SZ(member_header_big)) goto invalid; @@ -560,7 +560,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) if (name_len < 1 || name_len > ARNAME_MAX) goto invalid; - EINTRLOOP (nread, read (desc, name, name_len)); + nread = readbuf (desc, name, name_len); if (nread != name_len) goto invalid; @@ -578,8 +578,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) else #endif { - EINTRLOOP (nread, read (desc, &member_header, - AR_MEMHDR_SZ(member_header))); + nread = readbuf (desc, &member_header, + AR_MEMHDR_SZ(member_header)); if (nread != AR_MEMHDR_SZ(member_header)) goto invalid; @@ -588,7 +588,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) if (name_len < 1 || name_len > ARNAME_MAX) goto invalid; - EINTRLOOP (nread, read (desc, name, name_len)); + nread = readbuf (desc, name, name_len); if (nread != name_len) goto invalid; @@ -612,7 +612,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) eltmode, arg); #else /* Not AIAMAG. */ - EINTRLOOP (nread, read (desc, &member_header, AR_HDR_SIZE)); + nread = readbuf (desc, &member_header, AR_HDR_SIZE); if (nread == 0) /* No data left means end of file; that is OK. */ break; @@ -691,7 +691,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) goto invalid; name = alloca (name_len + 1); - EINTRLOOP (nread, read (desc, name, name_len)); + nread = readbuf (desc, name, name_len); if (nread != name_len) goto invalid; @@ -759,7 +759,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg) if (eltsize > INT_MAX) goto invalid; namemap = alloca (eltsize + 1); - EINTRLOOP (nread, read (desc, namemap, eltsize)); + nread = readbuf (desc, namemap, eltsize); if (nread != eltsize) goto invalid; namemap_size = eltsize; @@ -897,14 +897,7 @@ ar_member_touch (const char *arname, const char *memname) EINTRLOOP (o, lseek (fd, pos, 0)); if (o < 0) goto lose; - EINTRLOOP (r, read (fd, &ar_hdr, AR_HDR_SIZE)); - if (r != AR_HDR_SIZE) - goto lose; - /* Write back the header, thus touching the archive file. */ - EINTRLOOP (o, lseek (fd, pos, 0)); - if (o < 0) - goto lose; - r = output_write (fd, &ar_hdr, AR_HDR_SIZE); + r = readbuf (fd, &ar_hdr, AR_HDR_SIZE); if (r != AR_HDR_SIZE) goto lose; /* The file's mtime is the time we we want. */ @@ -926,7 +919,7 @@ ar_member_touch (const char *arname, const char *memname) EINTRLOOP (o, lseek (fd, pos, 0)); if (o < 0) goto lose; - r = output_write (fd, &ar_hdr, AR_HDR_SIZE); + r = writebuf (fd, &ar_hdr, AR_HDR_SIZE); if (r != AR_HDR_SIZE) goto lose; close (fd); diff --git a/src/makeint.h b/src/makeint.h index 79b286cc..315500fc 100644 --- a/src/makeint.h +++ b/src/makeint.h @@ -529,6 +529,8 @@ void print_spaces (unsigned int); char *find_percent (char *); const char *find_percent_cached (const char **); FILE *get_tmpfile (char **, const char *); +ssize_t writebuf (int, const void*, size_t); +ssize_t readbuf (int, void*, size_t); #ifndef NO_ARCHIVES int ar_name (const char *); diff --git a/src/misc.c b/src/misc.c index f3594ad3..307ff2b0 100644 --- a/src/misc.c +++ b/src/misc.c @@ -335,6 +335,52 @@ find_next_token (const char **ptr, size_t *lengthptr) return (char *)p; } +/* Write a BUFFER of size LEN to file descriptor FD. + Retry short writes from EINTR. Return LEN, or -1 on error. */ +ssize_t +writebuf (int fd, const void *buffer, size_t len) +{ + const char *msg = buffer; + size_t l = len; + while (l) + { + ssize_t r; + + EINTRLOOP (r, write (fd, msg, l)); + if (r < 0) + return r; + + l -= r; + msg += r; + } + + return (ssize_t)len; +} + +/* Read until we get LEN bytes from file descriptor FD, into BUFFER. + Retry short reads on EINTR. If we get an error, return it. + Return 0 at EOF. */ +ssize_t +readbuf (int fd, void *buffer, size_t len) +{ + char *msg = buffer; + while (len) + { + ssize_t r; + + EINTRLOOP (r, read (fd, msg, len)); + if (r < 0) + return r; + if (r == 0) + break; + + len -= r; + msg += r; + } + + return (ssize_t)(msg - (char*)buffer); +} + /* Copy a chain of 'struct dep'. For 2nd expansion deps, dup the name. */ diff --git a/src/output.c b/src/output.c index 8557de27..9a58b9f1 100644 --- a/src/output.c +++ b/src/output.c @@ -53,26 +53,6 @@ unsigned int stdio_traced = 0; # define STREAM_OK(_s) 1 #endif -/* Write a BUFFER of size LEN to file descriptor FD. - Handle EINTR and other short writes. If we get an error, ignore it. */ -int -output_write (int fd, const void *buffer, size_t len) -{ - const char *msg = buffer; - while (1) - { - ssize_t r; - - EINTRLOOP (r, write (fd, msg, len)); - - if (r < 0 || (size_t)r == len) - return r; - - len -= r; - msg += r; - } -} - /* Write a string to the current STDOUT or STDERR. */ static void _outputs (struct output *out, int is_err, const char *msg) @@ -89,7 +69,7 @@ _outputs (struct output *out, int is_err, const char *msg) size_t len = strlen (msg); int r; EINTRLOOP (r, lseek (fd, 0, SEEK_END)); - output_write (fd, msg, len); + writebuf (fd, msg, len); } } @@ -696,7 +676,7 @@ pfatal_with_name (const char *name) void out_of_memory () { - output_write (FD_STDOUT, program, strlen (program)); - output_write (FD_STDOUT, STRING_SIZE_TUPLE (": *** virtual memory exhausted\n")); + writebuf (FD_STDOUT, program, strlen (program)); + writebuf (FD_STDOUT, STRING_SIZE_TUPLE (": *** virtual memory exhausted\n")); exit (MAKE_FAILURE); }