With the -c flag, read copies exactly nbytes of characters
          instead of lines. It is mutually exclusive with -n and -m
          flag.

-sl
diff -r c6943e63621b read/read.1
--- a/read/read.1       Thu Apr 19 18:17:26 2012 +0100
+++ b/read/read.1       Mon Jul 02 13:41:08 2012 -0500
@@ -9,6 +9,9 @@
 .br
 .B read
 [
+.B -c
+] [
+[
 .B -m
 ] [
 .B -n
@@ -62,6 +65,18 @@
 .I nline
 lines.
 .PP
+With the
+.B -c
+flag,
+.I read
+copies exactly
+.I nbytes
+of characters instead of lines. It is mutually exclusive with
+.B -n
+and
+.B -m
+flag.
+.PP
 .I Read
 always executes a single
 .B write
diff -r c6943e63621b read/read.c
--- a/read/read.c       Thu Apr 19 18:17:26 2012 +0100
+++ b/read/read.c       Mon Jul 02 13:41:08 2012 -0500
@@ -3,6 +3,7 @@
 
 int    multi;
 int    nlines;
+vlong  nchars;
 char   *status = nil;
 
 int
@@ -53,29 +54,60 @@
 }
 
 void
+chars(int fd, char *file)
+{
+       char buf[8*1024];
+       vlong m;
+       int n;
+
+       for(m = 0; m < nchars; m += n){
+               n = sizeof(buf);
+               if(n > (nchars - m))
+                       n = nchars - m;
+               if((n = read(fd, buf, n)) < 0){
+                       fprint(2, "read: error reading %s: %r\n", file);
+                       exits("read error");
+               }
+               if(n == 0){
+                       if(m == 0)
+                               status = "eof";
+                       break;
+               }
+               write(1, buf, n);
+       }
+}
+
+void
+usage(void)
+{
+       fprint(2, "usage: read [-m] [-n nlines] [-c nbytes] [files...]\n");
+       exits("usage");
+}
+
+void
 main(int argc, char *argv[])
 {
+       void (*proc)(int, char*);
        int i, fd;
-       char *s;
 
+       proc = lines;
        ARGBEGIN{
+       case 'c':
+               nchars = atoll(EARGF(usage()));
+               proc = chars;
+               break;
+       case 'n':
+               nlines = atoi(EARGF(usage()));
+               break;
        case 'm':
                multi = 1;
                break;
-       case 'n':
-               s = ARGF();
-               if(s){
-                       nlines = atoi(s);
-                       break;
-               }
-               /* fall through */
        default:
-               fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
-               exits("usage");
+               usage();
        }ARGEND
 
        if(argc == 0)
-               lines(0, "<stdin>");
+               (*proc)(0, "<stdin>");
        else
                for(i=0; i<argc; i++){
                        fd = open(argv[i], OREAD);
@@ -83,7 +115,7 @@
                                fprint(2, "read: can't open %s: %r\n", argv[i]);
                                exits("open");
                        }
-                       lines(fd, argv[i]);
+                       (*proc)(fd, argv[i]);
                        close(fd);
                }
 

Reply via email to