diff -r 1cf9c28012a7 toys/pending/grep.c
--- a/toys/pending/grep.c	Wed Jul 17 17:27:14 2013 -0500
+++ b/toys/pending/grep.c	Sat Jul 20 08:14:17 2013 -0700
@@ -5,13 +5,13 @@
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/
  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html
 
-USE_GREP(NEWTOY(grep, "EFhinovclqe*f*m#", TOYFLAG_BIN))
+USE_GREP(NEWTOY(grep, "EFhHinosvclqe*f*m#", TOYFLAG_BIN))
 
 config GREP
   bool "grep"
   default n
   help
-    usage: grep [-clq] [-EFhinov] (-e RE | -f REfile | RE) [file...]
+    usage: grep [-clq] [-EFhinosv] (-e RE | -f REfile | RE) [file...]
 
     modes:
       default: print lines from each file what match regular expression RE.
@@ -22,10 +22,12 @@
     flags:
       -E:   extended RE syntax
       -F:   fixed RE syntax, i.e. all characters literal
-      -h:   not print file name
+      -h:   do not print file name
+      -H:   print file name
       -i:   case insensitive
       -n:   print line numbers
       -o:   print only matching part
+      -s:   do not print file read errors
       -v:   invert match
 */
 
@@ -34,9 +36,6 @@
 #include <regex.h>
 #include <err.h>
 
-/* could be in GLOBALS but so need initialization code */
-static int c = 1;
-
 static regex_t re; /* fails in GLOBALS */
 
 GLOBALS(
@@ -60,10 +59,11 @@
 
     while (regexec (&re, y, 1, &match, atBOL ? 0 : REG_NOTBOL) == 0) {
       if (atBOL) nMatch++;
-      c = 0; atBOL = 0;
+      toys.exitval = 0;
+      atBOL = 0;
       switch (TT.mode) {
       case 'q':
-        exit (0);
+        xexit ();
       case 'l':
         if (!(toys.optflags & FLAG_h)) printf ("%s\n", name);
         free (x);
@@ -136,7 +136,7 @@
   }
 
   if (!re_xs) {
-    if (toys.optc < 1) errx (2, "no RE");
+    if (toys.optc < 1) error_exit ("no RE");
     re_xs = toys.optflags & FLAG_F ? regfix (toys.optargs[0]) : toys.optargs[0];
     toys.optc--; toys.optargs++;
   }
@@ -144,7 +144,7 @@
   if (regcomp (&re, re_xs,
                (toys.optflags & (FLAG_E | FLAG_F) ? REG_EXTENDED : 0) |
                (toys.optflags &  FLAG_i           ? REG_ICASE    : 0)) != 0) {
-    errx (2, "bad RE");
+    error_exit("bad RE");
   }
 }
 
@@ -154,9 +154,9 @@
   if (toys.optflags & FLAG_c) TT.mode = 'c';
   if (toys.optflags & FLAG_l) TT.mode = 'l';
   if (toys.optflags & FLAG_q) TT.mode = 'q';
+  if (!(toys.optflags & FLAG_H) && (toys.optc < 2))
+    toys.optflags = toys.optflags | FLAG_h;
 
-  if (toys.optc > 0) loopfiles (toys.optargs, do_grep);
-  else do_grep (0, "-");
-
-  exit (c);
+  loopfiles_rw (toys.optargs, O_RDONLY, 0, (toys.optflags & FLAG_s), do_grep);
+  xexit ();
 }
