shithub: riscv

Download patch

ref: bdb228e14ac13eeb34601f7f360692cfd467e945
parent: 44f97f0cb1f3fd07c348ae634cb33c3aa74e64db
author: cinap_lenrek <[email protected]>
date: Mon Jul 2 13:46:21 EDT 2012

read: add -c flag to copy bytes instead of lines

--- a/sys/man/1/cat
+++ b/sys/man/1/cat
@@ -12,8 +12,11 @@
 .B -m
 ] [
 .B -n
-.I nline
+.I nlines
 ] [
+.B -c
+.I nbytes
+] [
 .I file ...
 ]
 .SH DESCRIPTION
@@ -54,8 +57,20 @@
 flag causes it to continue reading and writing multiple lines until end of file;
 .B -n
 causes it to read no more than
-.I nline
+.I nlines
 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
--- a/sys/src/cmd/read.c
+++ b/sys/src/cmd/read.c
@@ -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);
 		}