[BACK]Return to reverse.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tail

Diff for /src/usr.bin/tail/reverse.c between version 1.13 and 1.14

version 1.13, 2003/06/03 02:56:17 version 1.14, 2003/07/01 11:12:59
Line 57 
Line 57 
 static void r_buf(FILE *);  static void r_buf(FILE *);
 static int r_reg(FILE *, enum STYLE, long, struct stat *);  static int r_reg(FILE *, enum STYLE, long, struct stat *);
   
   #define COPYCHAR(fp, ch)                                \
           do {                                            \
                   if ((ch = getc(fp)) == EOF) {           \
                           ierr();                         \
                           return (0);                     \
                   }                                       \
                   if (putchar(ch) == EOF) {               \
                           oerr();                         \
                           return (0);                     \
                   }                                       \
           } while (0)
   
 /*  /*
  * reverse -- display input in reverse order by line.   * reverse -- display input in reverse order by line.
  *   *
Line 64 
Line 76 
  * files by bytes, lines or the whole file.   * files by bytes, lines or the whole file.
  *   *
  * BYTES        display N bytes   * BYTES        display N bytes
  *      REG     mmap the file and display the lines   *      REG     reverse scan and display the lines
  *      NOREG   cyclically read characters into a wrap-around buffer   *      NOREG   cyclically read characters into a wrap-around buffer
  *   *
  * LINES        display N lines   * LINES        display N lines
  *      REG     mmap the file and display the lines   *      REG     reverse scan and display the lines
  *      NOREG   cyclically read lines into a wrap-around array of buffers   *      NOREG   cyclically read lines into a wrap-around array of buffers
  *   *
  * FILE         display the entire file   * FILE         display the entire file
  *      REG     mmap the file and display the lines   *      REG     reverse scan and display the lines
  *      NOREG   cyclically read input into a linked list of buffers   *      NOREG   cyclically read input into a linked list of buffers
  */   */
 void  void
Line 105 
Line 117 
  * r_reg -- display a regular file in reverse order by line.   * r_reg -- display a regular file in reverse order by line.
  */   */
 static int  static int
 r_reg(fp, style, off, sbp)  r_reg(FILE *fp, enum STYLE style, long off, struct stat *sbp)
         FILE *fp;  
         enum STYLE style;  
         long off;  
         struct stat *sbp;  
 {  {
         off_t size;          off_t start, pos, end;
         int llen;          int ch;
         char *p;  
         char *start;  
   
         if (!(size = sbp->st_size))          end = sbp->st_size;
           if (end == 0)
                 return (0);                  return (0);
   
         if (size > SIZE_T_MAX)          /* Position before char, ignore last char whether newline or not */
                 return (1);          pos = end-2;
           ch = EOF;
           start = 0;
   
         if ((start = mmap(NULL, (size_t)size, PROT_READ, MAP_PRIVATE,          if (style == RBYTES && off < end)
             fileno(fp), (off_t)0)) == MAP_FAILED)                  start = end - off;
                 return (1);  
         p = start + size - 1;  
   
         if (style == RBYTES && off < size)          for (; pos >= start; pos--) {
                 size = off;                  /* A seek per char isn't a problem with a smart stdio */
                   if (fseeko(fp, pos, SEEK_SET) != 0) {
         /* Last char is special, ignore whether newline or not. */                          ierr();
         for (llen = 1; --size; ++llen)                          return (0);
                 if (*--p == '\n') {                  }
                         WR(p + 1, llen);                  if ((ch = getc(fp)) == '\n') {
                         llen = 0;                          while (--end > pos)
                         if (style == RLINES && !--off) {                                  COPYCHAR(fp, ch);
                                 ++p;                          end++;
                           if (style == RLINES && --off == 0)
                                 break;                                  break;
                         }  
                 }                  }
         if (llen)                  else if (ch == EOF) {
                 WR(p, llen);                          ierr();
         if (munmap(start, (size_t)sbp->st_size))                          return (0);
                 ierr();                  }
           }
           if (pos < start) {
                   if (ch != EOF && ungetc(ch, fp) == EOF) {
                           ierr();
                           return (0);
                   }
                   while (--end >= start)
                           COPYCHAR(fp, ch);
           }
         return (0);          return (0);
 }  }
   

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14