From 07cd9a8d1563ddc8627f762e67fffae95fd6ab30 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 9 Jan 1994 03:47:21 +0000 Subject: safe_read and full_write + join patch --- src/cat.c | 12 +++++++----- src/csplit.c | 3 ++- src/head.c | 29 ++++++++++++----------------- src/join.c | 47 +++++++++++++++++++++++++++++++++++++++++------ src/split.c | 6 ++++-- src/sum.c | 3 ++- src/tac.c | 12 +++++++----- src/tail.c | 60 ++++++++++++++++++++++++++++++++++-------------------------- src/tr.c | 7 ++++--- src/wc.c | 3 ++- 10 files changed, 115 insertions(+), 67 deletions(-) diff --git a/src/cat.c b/src/cat.c index 702d5c984..63128e053 100644 --- a/src/cat.c +++ b/src/cat.c @@ -47,6 +47,8 @@ char *stpcpy (); char *xmalloc (); void error (); +int full_write (); +int safe_read (); static void cat (); static void next_line_num (); @@ -417,7 +419,7 @@ simple_cat (buf, bufsize) { /* Read a block of input. */ - n_read = read (input_desc, buf, bufsize); + n_read = safe_read (input_desc, buf, bufsize); if (n_read < 0) { error (0, errno, "%s", infile); @@ -432,7 +434,7 @@ simple_cat (buf, bufsize) /* Write this block out. */ - if (write (output_desc, buf, n_read) != n_read) + if (full_write (output_desc, buf, n_read) < 0) error (1, errno, "write error"); } } @@ -516,7 +518,7 @@ cat (inbuf, insize, outbuf, outsize, quote, unsigned char *wp = outbuf; do { - if (write (output_desc, wp, outsize) != outsize) + if (full_write (output_desc, wp, outsize) < 0) error (1, errno, "write error"); wp += outsize; } @@ -564,14 +566,14 @@ cat (inbuf, insize, outbuf, outsize, quote, { int n_write = bpout - outbuf; - if (write (output_desc, outbuf, n_write) != n_write) + if (full_write (output_desc, outbuf, n_write) < 0) error (1, errno, "write error"); bpout = outbuf; } /* Read more input into INBUF. */ - n_read = read (input_desc, inbuf, insize); + n_read = safe_read (input_desc, inbuf, insize); if (n_read < 0) { error (0, errno, "%s", infile); diff --git a/src/csplit.c b/src/csplit.c index f27290b77..54bd498d7 100644 --- a/src/csplit.c +++ b/src/csplit.c @@ -56,6 +56,7 @@ char *realloc (); #endif /* INT_MAX */ void error (); +int safe_read (); static char *xrealloc (); @@ -314,7 +315,7 @@ read_input (dest, max) if (max == 0) return 0; - bytes_read = read (input_desc, dest, max); + bytes_read = safe_read (input_desc, dest, max); if (bytes_read == 0) have_read_eof = TRUE; diff --git a/src/head.c b/src/head.c index 0d1d9c8ea..f17d7c362 100644 --- a/src/head.c +++ b/src/head.c @@ -70,7 +70,7 @@ enum header_mode }; void error (); -void xwrite (); +int safe_read (); static int head (); static int head_bytes (); @@ -231,7 +231,7 @@ main (argc, argv) if (have_read_stdin && close (0) < 0) error (1, errno, "-"); - if (close (1) < 0) + if (fclose (stdout) == EOF) error (1, errno, "write error"); exit (exit_status); @@ -276,15 +276,8 @@ write_header (filename) { static int first_file = 1; - if (first_file) - { - xwrite (1, "==> ", 4); - first_file = 0; - } - else - xwrite (1, "\n==> ", 5); - xwrite (1, filename, strlen (filename)); - xwrite (1, " <==\n", 5); + printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename); + first_file = 0; } static int @@ -310,8 +303,8 @@ head_bytes (filename, fd, bytes_to_write) while (bytes_to_write) { - bytes_read = read (fd, buffer, BUFSIZE); - if (bytes_read == -1) + bytes_read = safe_read (fd, buffer, BUFSIZE); + if (bytes_read < 0) { error (0, errno, "%s", filename); return 1; @@ -320,7 +313,8 @@ head_bytes (filename, fd, bytes_to_write) break; if (bytes_read > bytes_to_write) bytes_read = bytes_to_write; - xwrite (1, buffer, bytes_read); + if (fwrite (buffer, 1, bytes_read, stdout) == 0) + error (1, errno, "write error"); bytes_to_write -= bytes_read; } return 0; @@ -338,8 +332,8 @@ head_lines (filename, fd, lines_to_write) while (lines_to_write) { - bytes_read = read (fd, buffer, BUFSIZE); - if (bytes_read == -1) + bytes_read = safe_read (fd, buffer, BUFSIZE); + if (bytes_read < 0) { error (0, errno, "%s", filename); return 1; @@ -350,7 +344,8 @@ head_lines (filename, fd, lines_to_write) while (bytes_to_write < bytes_read) if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0) break; - xwrite (1, buffer, bytes_to_write); + if (fwrite (buffer, 1, bytes_to_write, stdout) == 0) + error (1, errno, "write error"); } return 0; } diff --git a/src/join.c b/src/join.c index 21ed852a6..d07c0e820 100644 --- a/src/join.c +++ b/src/join.c @@ -44,6 +44,7 @@ void error (); static void usage (); #define min(A, B) ((A) < (B) ? (A) : (B)) +#define max(A, B) ((A) > (B) ? (A) : (B)) /* An element of the list describing the format of each output line. */ @@ -115,6 +116,10 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; +/* Used to print non-joining lines */ +static struct line blank1; +static struct line blank2; + /* Fill in the `fields' structure in LINE. */ static void @@ -404,7 +409,7 @@ join (fp1, fp2) if (diff < 0) { if (print_unpairables_1) - prline (&seq1.lines[0]); + prjoin (&seq1.lines[0], &blank2); freeline (&seq1.lines[0]); seq1.count = 0; getseq (fp1, &seq1); @@ -413,7 +418,7 @@ join (fp1, fp2) if (diff > 0) { if (print_unpairables_2) - prline (&seq2.lines[0]); + prjoin (&blank1, &seq2.lines[0]); freeline (&seq2.lines[0]); seq2.count = 0; getseq (fp2, &seq2); @@ -474,22 +479,22 @@ join (fp1, fp2) if (print_unpairables_1 && seq1.count) { - prline (&seq1.lines[0]); + prjoin(&seq1.lines[0], &blank2); freeline (&seq1.lines[0]); while (get_line (fp1, &line)) { - prline (&line); + prjoin(&line, &blank2); freeline (&line); } } if (print_unpairables_2 && seq2.count) { - prline (&seq2.lines[0]); + prjoin(&blank1, &seq2.lines[0]); freeline (&seq2.lines[0]); while (get_line (fp2, &line)) { - prline (&line); + prjoin(&blank1, &line); freeline (&line); } } @@ -541,6 +546,10 @@ add_field_list (str) if (*str == ',' || ISBLANK (*str)) { added += add_field (file, field); + switch (file) { + case 1: blank1.nfields = max(blank1.nfields, field); break; + case 2: blank2.nfields = max(blank2.nfields, field); break; + } file = field = -1; dot_found = 0; } @@ -569,6 +578,24 @@ add_field_list (str) return added; } +/* Create a blank line with COUNT fields separated by tabs. */ + +void +make_blank (blank, count) + struct line *blank; + int count; +{ + int i; + blank->beg = xmalloc(blank->nfields + 1); + blank->fields = (struct field *)xmalloc(sizeof(struct field) * count); + for (i = 0; i < blank->nfields; i++) { + blank->beg[i] = '\t'; + blank->fields[i].lim = blank->fields[i].beg = &blank->beg[i]; + } + blank->beg[i] = '\0'; + blank->lim = &blank->beg[i]; +} + void main (argc, argv) int argc; @@ -578,10 +605,18 @@ main (argc, argv) FILE *fp1, *fp2; int optc, prev_optc = 0, nfiles, val; + blank1.nfields = 1; + blank2.nfields = 1; + program_name = argv[0]; parse_long_options (argc, argv, usage); + /* Now that we've seen the options, we can construct the blank line + structures. */ + make_blank(&blank1, blank1.nfields); + make_blank(&blank2, blank2.nfields); + nfiles = 0; print_pairables = 1; diff --git a/src/split.c b/src/split.c index 323335ee1..f65a769be 100644 --- a/src/split.c +++ b/src/split.c @@ -40,6 +40,8 @@ char *xmalloc (); void error (); +int full_write (); +int safe_read (); static int convint (); static int isdigits (); @@ -524,7 +526,7 @@ cwrite (new_file_flag, bp, bytes) if (output_desc < 0) error (1, errno, "%s", outfile); } - if (write (output_desc, bp, bytes) < 0) + if (full_write (output_desc, bp, bytes) < 0) error (1, errno, "%s", outfile); } @@ -542,7 +544,7 @@ stdread (buf, nchars) while (to_be_read) { - n_read = read (input_desc, buf, to_be_read); + n_read = safe_read (input_desc, buf, to_be_read); if (n_read < 0) return -1; if (n_read == 0) diff --git a/src/sum.c b/src/sum.c index 67527e142..62fd30e92 100644 --- a/src/sum.c +++ b/src/sum.c @@ -40,6 +40,7 @@ static int bsd_sum_file (); static int sysv_sum_file (); void error (); +int safe_read (); /* The name this program was run with. */ char *program_name; @@ -242,7 +243,7 @@ sysv_sum_file (file, print_name) } } - while ((bytes_read = read (fd, buf, sizeof buf)) > 0) + while ((bytes_read = safe_read (fd, buf, sizeof buf)) > 0) { register int i; diff --git a/src/tac.c b/src/tac.c index b35293f50..c295de444 100644 --- a/src/tac.c +++ b/src/tac.c @@ -78,6 +78,8 @@ static void save_stdin (); static void xwrite (); void error (); +int full_write (); +int safe_read (); /* The name this program was run with. */ char *program_name; @@ -382,8 +384,8 @@ save_stdin () error (0, errno, "%s", tempfile); cleanup (); } - while ((bytes_read = read (0, buffer, read_size)) > 0) - if (write (fd, buffer, bytes_read) != bytes_read) + while ((bytes_read = safe_read (0, buffer, read_size)) > 0) + if (full_write (fd, buffer, bytes_read) < 0) { error (0, errno, "%s", tempfile); cleanup (); @@ -466,7 +468,7 @@ tac (fd, file) in the input file. */ lseek (fd, file_pos, SEEK_SET); - if (read (fd, buffer, saved_record_size) != saved_record_size) + if (safe_read (fd, buffer, saved_record_size) != saved_record_size) { error (0, 1, "%s", file); return 1; @@ -562,7 +564,7 @@ tac (fd, file) else match_start = past_end; - if (read (fd, buffer, read_size) != read_size) + if (safe_read (fd, buffer, read_size) != read_size) { error (0, errno, "%s", file); return 1; @@ -640,7 +642,7 @@ xwrite (desc, buffer, size) char *buffer; int size; { - if (write (desc, buffer, size) != size) + if (full_write (desc, buffer, size) < 0) { error (0, errno, "write error"); cleanup (); diff --git a/src/tail.c b/src/tail.c index 2eb05c7da..c10008cac 100644 --- a/src/tail.c +++ b/src/tail.c @@ -57,14 +57,29 @@ #endif #include +#include #include #include #include "system.h" #include "version.h" +/* FIXME: uncomment before release. */ +/* #define NDEBUG 1 */ + +#define XWRITE(fd, buffer, n_bytes) \ + do \ + { \ + assert ((fd) == 1); \ + assert ((n_bytes) > 0); \ + if (fwrite ((buffer), 1, (n_bytes), stdout) == 0) \ + error (1, errno, "write error"); \ + } \ + while (0) + /* Number of items to tail. */ #define DEFAULT_NUMBER 10 +/* FIXME: use definition from stdio.h. */ /* Size of atomic reads. */ #define BUFSIZE (512 * 8) @@ -97,8 +112,8 @@ enum header_mode }; char *xmalloc (); -void xwrite (); void error (); +int safe_read (); static int file_lines (); static int pipe_bytes (); @@ -315,7 +330,7 @@ main (argc, argv) if (have_read_stdin && close (0) < 0) error (1, errno, "-"); - if (close (1) < 0) + if (fclose (stdout) == EOF) error (1, errno, "write error"); exit (exit_status); } @@ -422,15 +437,8 @@ write_header (filename) { static int first_file = 1; - if (first_file) - { - xwrite (1, "==> ", 4); - first_file = 0; - } - else - xwrite (1, "\n==> ", 5); - xwrite (1, filename, strlen (filename)); - xwrite (1, " <==\n", 5); + printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename); + first_file = 0; } /* Display the last NUMBER units of file FILENAME, open for reading @@ -568,7 +576,7 @@ file_lines (filename, fd, number, pos) reads will be on block boundaries, which might increase efficiency. */ pos -= bytes_read; lseek (fd, pos, SEEK_SET); - bytes_read = read (fd, buffer, bytes_read); + bytes_read = safe_read (fd, buffer, bytes_read); if (bytes_read == -1) { error (0, errno, "%s", filename); @@ -590,7 +598,7 @@ file_lines (filename, fd, number, pos) /* If this newline wasn't the last character in the buffer, print the text after it. */ if (i != bytes_read - 1) - xwrite (1, &buffer[i + 1], bytes_read - (i + 1)); + XWRITE (1, &buffer[i + 1], bytes_read - (i + 1)); return 0; } } @@ -604,7 +612,7 @@ file_lines (filename, fd, number, pos) pos -= BUFSIZE; lseek (fd, pos, SEEK_SET); } - while ((bytes_read = read (fd, buffer, BUFSIZE)) > 0); + while ((bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0); if (bytes_read == -1) { error (0, errno, "%s", filename); @@ -642,7 +650,7 @@ pipe_lines (filename, fd, number) tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER)); /* Input is always read into a fresh buffer. */ - while ((tmp->nbytes = read (fd, tmp->buffer, BUFSIZE)) > 0) + while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZE)) > 0) { tmp->nlines = 0; tmp->next = NULL; @@ -721,10 +729,10 @@ pipe_lines (filename, fd, number) } else i = 0; - xwrite (1, &tmp->buffer[i], tmp->nbytes - i); + XWRITE (1, &tmp->buffer[i], tmp->nbytes - i); for (tmp = tmp->next; tmp; tmp = tmp->next) - xwrite (1, tmp->buffer, tmp->nbytes); + XWRITE (1, tmp->buffer, tmp->nbytes); free_lbuffers: while (first) @@ -764,7 +772,7 @@ pipe_bytes (filename, fd, number) tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER)); /* Input is always read into a fresh buffer. */ - while ((tmp->nbytes = read (fd, tmp->buffer, BUFSIZE)) > 0) + while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZE)) > 0) { tmp->next = NULL; @@ -818,10 +826,10 @@ pipe_bytes (filename, fd, number) i = total_bytes - number; else i = 0; - xwrite (1, &tmp->buffer[i], tmp->nbytes - i); + XWRITE (1, &tmp->buffer[i], tmp->nbytes - i); for (tmp = tmp->next; tmp; tmp = tmp->next) - xwrite (1, tmp->buffer, tmp->nbytes); + XWRITE (1, tmp->buffer, tmp->nbytes); free_cbuffers: while (first) @@ -846,7 +854,7 @@ start_bytes (filename, fd, number) char buffer[BUFSIZE]; int bytes_read = 0; - while (number > 0 && (bytes_read = read (fd, buffer, BUFSIZE)) > 0) + while (number > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0) number -= bytes_read; if (bytes_read == -1) { @@ -854,7 +862,7 @@ start_bytes (filename, fd, number) return 1; } else if (number < 0) - xwrite (1, &buffer[bytes_read + number], -number); + XWRITE (1, &buffer[bytes_read + number], -number); return 0; } @@ -872,7 +880,7 @@ start_lines (filename, fd, number) int bytes_read = 0; int bytes_to_skip = 0; - while (number && (bytes_read = read (fd, buffer, BUFSIZE)) > 0) + while (number && (bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0) { bytes_to_skip = 0; while (bytes_to_skip < bytes_read) @@ -885,7 +893,7 @@ start_lines (filename, fd, number) return 1; } else if (bytes_to_skip < bytes_read) - xwrite (1, &buffer[bytes_to_skip], bytes_read - bytes_to_skip); + XWRITE (1, &buffer[bytes_to_skip], bytes_read - bytes_to_skip); return 0; } @@ -904,9 +912,9 @@ dump_remainder (filename, fd) total = 0; output: - while ((bytes_read = read (fd, buffer, BUFSIZE)) > 0) + while ((bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0) { - xwrite (1, buffer, bytes_read); + XWRITE (1, buffer, bytes_read); total += bytes_read; } if (bytes_read == -1) diff --git a/src/tr.c b/src/tr.c index cb31ceba3..7485fe375 100644 --- a/src/tr.c +++ b/src/tr.c @@ -201,6 +201,7 @@ struct Spec_list char *xmalloc (); char *stpcpy (); void error (); +int safe_read (); /* The name by which this program was run. */ char *program_name; @@ -1514,7 +1515,7 @@ squeeze_filter (buf, size, reader) if (i >= nr) { if (reader == NULL) - nr = read (0, (char *) buf, size); + nr = safe_read (0, (char *) buf, size); else nr = (*reader) (buf, size, NULL); @@ -1616,7 +1617,7 @@ read_and_delete (buf, size, not_used) do { int i; - int nr = read (0, (char *) buf, size); + int nr = safe_read (0, (char *) buf, size); if (nr < 0) error (1, errno, "read error"); @@ -1664,7 +1665,7 @@ read_and_xlate (buf, size, not_used) if (hit_eof) return 0; - chars_read = read (0, (char *) buf, size); + chars_read = safe_read (0, (char *) buf, size); if (chars_read < 0) error (1, errno, "read error"); if (chars_read == 0) diff --git a/src/wc.c b/src/wc.c index 6625b59f0..3f1dd90ae 100644 --- a/src/wc.c +++ b/src/wc.c @@ -39,6 +39,7 @@ #define BUFFER_SIZE (16 * 1024) void error (); +int safe_read (); static void wc (); static void wc_file (); @@ -220,7 +221,7 @@ wc (fd, file) } else { - while ((bytes_read = read (fd, buf, BUFFER_SIZE)) > 0) + while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0) { register char *p = buf; -- cgit v1.2.3-54-g00ecf