~ubuntu-branches/ubuntu/utopic/coreutils/utopic-proposed

« back to all changes in this revision

Viewing changes to src/tail.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-11-28 03:03:42 UTC
  • mfrom: (8.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20121128030342-21zanj8354gas5gr
Tags: 8.20-3ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Make 'uname -i -p' return the real processor/hardware, instead of
    unknown.
  - Build-depend on gettext:any instead of on gettext, so that apt-get can
    properly resolve build-dependencies on the tool when cross-building.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* tail -- output the last part of file(s)
2
 
   Copyright (C) 1989-1991, 1995-2006, 2008-2011 Free Software Foundation, Inc.
 
2
   Copyright (C) 1989-2012 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software: you can redistribute it and/or modify
5
5
   it under the terms of the GNU General Public License as published by
49
49
#if HAVE_INOTIFY
50
50
# include "hash.h"
51
51
# include <sys/inotify.h>
52
 
/* `select' is used by tail_forever_inotify.  */
 
52
/* 'select' is used by tail_forever_inotify.  */
53
53
# include <sys/select.h>
54
54
 
55
55
/* inotify needs to know if a file is local.  */
56
56
# include "fs.h"
 
57
# include "fs-is-local.h"
57
58
# if HAVE_SYS_STATFS_H
58
59
#  include <sys/statfs.h>
59
60
# elif HAVE_SYS_VFS_H
61
62
# endif
62
63
#endif
63
64
 
64
 
/* The official name of this program (e.g., no `g' prefix).  */
 
65
/* The official name of this program (e.g., no 'g' prefix).  */
65
66
#define PROGRAM_NAME "tail"
66
67
 
67
68
#define AUTHORS \
251
252
usage (int status)
252
253
{
253
254
  if (status != EXIT_SUCCESS)
254
 
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
255
 
             program_name);
 
255
    emit_try_help ();
256
256
  else
257
257
    {
258
258
      printf (_("\
310
310
     fputs (VERSION_OPTION_DESCRIPTION, stdout);
311
311
     fputs (_("\
312
312
\n\
313
 
If the first character of K (the number of bytes or lines) is a `+',\n\
 
313
If the first character of K (the number of bytes or lines) is a '+',\n\
314
314
print beginning with the Kth item from the start of each file, otherwise,\n\
315
315
print the last K items in the file.  K may have a multiplier suffix:\n\
316
316
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
466
466
}
467
467
 
468
468
/* Print the last N_LINES lines from the end of file FD.
469
 
   Go backward through the file, reading `BUFSIZ' bytes at a time (except
 
469
   Go backward through the file, reading 'BUFSIZ' bytes at a time (except
470
470
   probably the first), until we hit the start of the file or have
471
471
   read NUMBER newlines.
472
472
   START_POS is the starting position of the read pointer for the file
485
485
  if (n_lines == 0)
486
486
    return true;
487
487
 
488
 
  /* Set `bytes_read' to the size of the last, probably partial, buffer;
489
 
     0 < `bytes_read' <= `BUFSIZ'.  */
 
488
  /* Set 'bytes_read' to the size of the last, probably partial, buffer;
 
489
     0 < 'bytes_read' <= 'BUFSIZ'.  */
490
490
  bytes_read = (pos - start_pos) % BUFSIZ;
491
491
  if (bytes_read == 0)
492
492
    bytes_read = BUFSIZ;
493
 
  /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
 
493
  /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all
494
494
     reads will be on block boundaries, which might increase efficiency.  */
495
495
  pos -= bytes_read;
496
496
  xlseek (fd, pos, SEEK_SET, pretty_filename);
608
608
      total_lines += tmp->nlines;
609
609
 
610
610
      /* If there is enough room in the last buffer read, just append the new
611
 
         one to it.  This is because when reading from a pipe, `n_read' can
 
611
         one to it.  This is because when reading from a pipe, 'n_read' can
612
612
         often be very small.  */
613
613
      if (tmp->nbytes + last->nbytes < BUFSIZ)
614
614
        {
670
670
    char const *buffer_end = tmp->buffer + tmp->nbytes;
671
671
    if (total_lines > n_lines)
672
672
      {
673
 
        /* Skip `total_lines' - `n_lines' newlines.  We made sure that
674
 
           `total_lines' - `n_lines' <= `tmp->nlines'.  */
 
673
        /* Skip 'total_lines' - 'n_lines' newlines.  We made sure that
 
674
           'total_lines' - 'n_lines' <= 'tmp->nlines'.  */
675
675
        size_t j;
676
676
        for (j = total_lines - n_lines; j; --j)
677
677
          {
735
735
 
736
736
      total_bytes += tmp->nbytes;
737
737
      /* If there is enough room in the last buffer read, just append the new
738
 
         one to it.  This is because when reading from a pipe, `nbytes' can
 
738
         one to it.  This is because when reading from a pipe, 'nbytes' can
739
739
         often be very small.  */
740
740
      if (tmp->nbytes + last->nbytes < BUFSIZ)
741
741
        {
778
778
    total_bytes -= tmp->nbytes;
779
779
 
780
780
  /* Find the correct beginning, then print the rest of the file.
781
 
     We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'.  */
 
781
     We made sure that 'total_bytes' - 'n_bytes' <= 'tmp->nbytes'.  */
782
782
  if (total_bytes > n_bytes)
783
783
    i = total_bytes - n_bytes;
784
784
  else
847
847
  while (1)
848
848
    {
849
849
      char buffer[BUFSIZ];
850
 
      char *p = buffer;
851
850
      size_t bytes_read = safe_read (fd, buffer, BUFSIZ);
852
 
      char *buffer_end = buffer + bytes_read;
853
851
      if (bytes_read == 0) /* EOF */
854
852
        return -1;
855
853
      if (bytes_read == SAFE_READ_ERROR) /* error */
858
856
          return 1;
859
857
        }
860
858
 
 
859
      char *buffer_end = buffer + bytes_read;
 
860
 
861
861
      *read_pos += bytes_read;
862
862
 
 
863
      char *p = buffer;
863
864
      while ((p = memchr (p, '\n', buffer_end - p)))
864
865
        {
865
866
          ++p;
896
897
    }
897
898
  else
898
899
    {
899
 
      switch (buf.f_type)
 
900
      switch (is_local_fs_type (buf.f_type))
900
901
        {
901
 
        case S_MAGIC_AFS:
902
 
        case S_MAGIC_CIFS:
903
 
        case S_MAGIC_CODA:
904
 
        case S_MAGIC_FUSEBLK:
905
 
        case S_MAGIC_FUSECTL:
906
 
        case S_MAGIC_GFS:
907
 
        case S_MAGIC_KAFS:
908
 
        case S_MAGIC_LUSTRE:
909
 
        case S_MAGIC_NCP:
910
 
        case S_MAGIC_NFS:
911
 
        case S_MAGIC_NFSD:
912
 
        case S_MAGIC_OCFS2:
913
 
        case S_MAGIC_SMB:
914
 
          break;
915
 
        default:
 
902
        case 0:
 
903
          break;
 
904
        case -1:
 
905
          {
 
906
            unsigned long int fs_type = buf.f_type;
 
907
            error (0, 0, _("unrecognized file system type 0x%08lx for %s. "
 
908
                           "please report this to %s. reverting to polling"),
 
909
                   fs_type, quote (name), PACKAGE_BUGREPORT);
 
910
            /* Treat as "remote", so caller polls.  */
 
911
          }
 
912
          break;
 
913
        case 1:
916
914
          remote = false;
 
915
          break;
 
916
        default:
 
917
          assert (!"unexpected return value from is_local_fs_type");
917
918
        }
918
919
    }
919
920
# endif
1140
1141
                  f[i].fd = -1;
1141
1142
                  f[i].errnum = errno;
1142
1143
                  error (0, errno, "%s", name);
 
1144
                  close (fd); /* ignore failure */
1143
1145
                  continue;
1144
1146
                }
1145
1147
 
1266
1268
  return spec1->wd == spec2->wd;
1267
1269
}
1268
1270
 
1269
 
/* Helper function used by `tail_forever_inotify'.  */
 
1271
/* Helper function used by 'tail_forever_inotify'.  */
1270
1272
static void
1271
1273
check_fspec (struct File_spec *fspec, int wd, int *prev_wd)
1272
1274
{
1275
1277
 
1276
1278
  if (fstat (fspec->fd, &stats) != 0)
1277
1279
    {
 
1280
      fspec->errnum = errno;
1278
1281
      close_fd (fspec->fd, name);
1279
1282
      fspec->fd = -1;
1280
 
      fspec->errnum = errno;
1281
1283
      return;
1282
1284
    }
1283
1285
 
1425
1427
 
1426
1428
  /* Wait for inotify events and handle them.  Events on directories
1427
1429
     ensure that watched files can be re-added when following by name.
1428
 
     This loop blocks on the `safe_read' call until a new event is notified.
 
1430
     This loop blocks on the 'safe_read' call until a new event is notified.
1429
1431
     But when --pid=P is specified, tail usually waits via the select.  */
1430
1432
  while (1)
1431
1433
    {
1521
1523
 
1522
1524
          fspec = &(f[j]);
1523
1525
 
1524
 
          /* Remove `fspec' and re-add it using `new_fd' as its key.  */
 
1526
          /* Remove 'fspec' and re-add it using 'new_fd' as its key.  */
1525
1527
          hash_delete (wd_to_name, fspec);
1526
1528
          fspec->wd = new_wd;
1527
1529
 
1687
1689
        {
1688
1690
          /* Under very unlikely circumstances, it is possible to reach
1689
1691
             this point after positioning the file pointer to end of file
1690
 
             via the `lseek (...SEEK_END)' above.  In that case, reposition
 
1692
             via the 'lseek (...SEEK_END)' above.  In that case, reposition
1691
1693
             the file pointer back to start_pos before calling pipe_lines.  */
1692
1694
          if (start_pos != -1)
1693
1695
            xlseek (fd, start_pos, SEEK_SET, pretty_filename);
1768
1770
          struct stat stats;
1769
1771
 
1770
1772
#if TEST_RACE_BETWEEN_FINAL_READ_AND_INITIAL_FSTAT
1771
 
          /* Before the tail function provided `read_pos', there was
 
1773
          /* Before the tail function provided 'read_pos', there was
1772
1774
             a race condition described in the URL below.  This sleep
1773
1775
             call made the window big enough to exercise the problem.  */
1774
1776
          xnanosleep (1);
2109
2111
  parse_options (argc, argv, &n_units, &header_mode, &sleep_interval);
2110
2112
 
2111
2113
  /* To start printing with item N_UNITS from the start of the file, skip
2112
 
     N_UNITS - 1 items.  `tail -n +0' is actually meaningless, but for Unix
2113
 
     compatibility it's treated the same as `tail -n +1'.  */
 
2114
     N_UNITS - 1 items.  'tail -n +0' is actually meaningless, but for Unix
 
2115
     compatibility it's treated the same as 'tail -n +1'.  */
2114
2116
  if (from_start)
2115
2117
    {
2116
2118
      if (n_units)
2140
2142
    if (found_hyphen && follow_mode == Follow_name)
2141
2143
      error (EXIT_FAILURE, 0, _("cannot follow %s by name"), quote ("-"));
2142
2144
 
2143
 
    /* When following forever, warn if any file is `-'.
 
2145
    /* When following forever, warn if any file is '-'.
2144
2146
       This is only a warning, since tail's output (before a failing seek,
2145
2147
       and that from any non-stdin files) might still be useful.  */
2146
2148
    if (forever && found_hyphen && isatty (STDIN_FILENO))