Grep: Reintroducing local modification: --only-files option
authorJohn Marino <draco@marino.st>
Sun, 24 Apr 2011 15:50:32 +0000 (17:50 +0200)
committerJohn Marino <draco@marino.st>
Tue, 26 Apr 2011 18:13:30 +0000 (20:13 +0200)
The previous version of grep was enhanced with a DragonFly-only custom
option --only-files.  This modification adds this customization to
grep 2.7 as well.

contrib/grep/doc/grep.1
contrib/grep/doc/grep.texi
contrib/grep/src/main.c

index 1e61431..a14a671 100644 (file)
@@ -534,6 +534,10 @@ this is equivalent to the
 option.
 .SS "Other Options"
 .TP
+.BR \-O ", " \-\^\-only-files
+Ignore all special files, except for symlinks. Yet, when recursing
+into directories, ignore symlinked directories as well.
+.TP
 .BR \-\^\-line\-buffered
 Use line buffering on output.
 This can cause a performance penalty.
index da103c4..dca952b 100644 (file)
@@ -651,6 +651,15 @@ For each directory mentioned on the command line,
 read and process all files in that directory, recursively.
 This is the same as the @samp{--directories=recurse} option.
 
+@item -O
+@itemx --only-files
+@opindex -O
+@opindex --only-files
+@cindex ignoring special files
+@cindex ignoring symlinked directories
+Ignore all special files, except for symlinks.
+When recursing into directories, ignore symlinked directories as well.
+
 @end table
 
 @node Other Options
index 04a4220..6cdf66d 100644 (file)
@@ -272,7 +272,7 @@ static struct exclude *included_patterns;
 static struct exclude *excluded_directory_patterns;
 /* Short options.  */
 static char const short_options[] =
-"0123456789A:B:C:D:EFGHIPTUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
+"0123456789A:B:C:D:EFGHIOPTUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
 
 /* Non-boolean long options that have no corresponding short equivalents.  */
 enum
@@ -331,6 +331,7 @@ static struct option const long_options[] =
   {"no-messages", no_argument, NULL, 's'},
   {"null", no_argument, NULL, 'Z'},
   {"null-data", no_argument, NULL, 'z'},
+  {"only-files", no_argument, NULL, 'O'},
   {"only-matching", no_argument, NULL, 'o'},
   {"quiet", no_argument, NULL, 'q'},
   {"recursive", no_argument, NULL, 'r'},
@@ -378,6 +379,9 @@ ARGMATCH_VERIFY (directories_args, directories_types);
 
 static enum directories_type directories = READ_DIRECTORIES;
 
+/* How to handle dir/device/links */
+static int only_files;
+
 /* How to handle devices. */
 static enum
   {
@@ -1208,6 +1212,20 @@ grepfile (char const *file, struct stats *stats)
           suppressible_error (file, errno);
           return 1;
         }
+      if (only_files)
+        {
+          if (S_ISDIR (stats->stat.st_mode))
+            {
+              if (directories != RECURSE_DIRECTORIES)
+                return 1;
+              if (lstat(file, &stats->stat) != 0)
+                return 1;
+              if (!S_ISDIR (stats->stat.st_mode))
+                return 1;
+            }
+          else if (!S_ISREG (stats->stat.st_mode))
+            return 1;
+        }
       if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
         return 1;
       if (devices == SKIP_DEVICES && (S_ISCHR (stats->stat.st_mode)
@@ -1224,11 +1242,13 @@ grepfile (char const *file, struct stats *stats)
 
           if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
             {
+#if 0  /* DISABLED by only-files local modification option */
               if (stat (file, &stats->stat) != 0)
                 {
                   error (0, errno, "%s", file);
                   return 1;
                 }
+#endif
 
               return grepdir (file, stats);
             }
@@ -1445,15 +1465,18 @@ Output control:\n\
       printf (_("\
       --include=FILE_PATTERN  search only files that match FILE_PATTERN\n\
       --exclude=FILE_PATTERN  skip files and directories matching FILE_PATTERN\n\
-      --exclude-from=FILE   skip files matching any file pattern from FILE\n\
-      --exclude-dir=PATTERN  directories that match PATTERN will be skipped.\n\
+      --exclude-from=FILE     skip files matching any file pattern from FILE\n\
+      --exclude-dir=PATTERN   directories that match PATTERN will be skipped.\n\
 "));
       printf (_("\
+  -O, --only-files           Ignore special files, except symlinks.\n\
+                             When recursing directories, ignore symlinked\n\
+                             directories as well.\n\
   -L, --files-without-match  print only names of FILEs containing no match\n\
-  -l, --files-with-matches  print only names of FILEs containing matches\n\
-  -c, --count               print only a count of matching lines per FILE\n\
-  -T, --initial-tab         make tabs line up (if needed)\n\
-  -Z, --null                print 0 byte after FILE name\n"));
+  -l, --files-with-matches   print only names of FILEs containing matches\n\
+  -c, --count                print only a count of matching lines per FILE\n\
+  -T, --initial-tab          make tabs line up (if needed)\n\
+  -Z, --null                 print 0 byte after FILE name\n"));
       printf (_("\
 \n\
 Context control:\n\
@@ -1852,6 +1875,10 @@ main (int argc, char **argv)
         binary_files = WITHOUT_MATCH_BINARY_FILES;
         break;
 
+      case 'O':
+        only_files = 1;
+        break;
+
       case 'T':
         align_tabs = 1;
         break;