safe_read and full_write + join patch
authorJim Meyering <jim@meyering.net>
Sun, 9 Jan 1994 03:47:21 +0000 (03:47 +0000)
committerJim Meyering <jim@meyering.net>
Sun, 9 Jan 1994 03:47:21 +0000 (03:47 +0000)
src/cat.c
src/csplit.c
src/head.c
src/join.c
src/split.c
src/sum.c
src/tac.c
src/tail.c
src/tr.c
src/wc.c

index 702d5c9..63128e0 100644 (file)
--- 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);
index f27290b..54bd498 100644 (file)
@@ -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;
index 0d1d9c8..f17d7c3 100644 (file)
@@ -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;
 }
index 21ed852..d07c0e8 100644 (file)
@@ -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;
 
index 323335e..f65a769 100644 (file)
@@ -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)
index 67527e1..62fd30e 100644 (file)
--- 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;
 
index b35293f..c295de4 100644 (file)
--- 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 ();
index 2eb05c7..c10008c 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <assert.h>
 #include <getopt.h>
 #include <sys/types.h>
 #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)
index cb31ceb..7485fe3 100644 (file)
--- 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)
index 6625b59..3f1dd90 100644 (file)
--- 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;