[Midnightbsd-cvs] src [6823] trunk/bin/cat: Introduce the l flag
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Fri Oct 3 00:10:33 EDT 2014
Revision: 6823
http://svnweb.midnightbsd.org/src/?rev=6823
Author: laffer1
Date: 2014-10-03 00:10:32 -0400 (Fri, 03 Oct 2014)
Log Message:
-----------
Introduce the l flag
Set an exclusive advisory lock on the standard output file descriptor.
Modified Paths:
--------------
trunk/bin/cat/cat.1
trunk/bin/cat/cat.c
Modified: trunk/bin/cat/cat.1
===================================================================
--- trunk/bin/cat/cat.1 2014-10-03 03:59:08 UTC (rev 6822)
+++ trunk/bin/cat/cat.1 2014-10-03 04:10:32 UTC (rev 6823)
@@ -33,7 +33,7 @@
.\" $FreeBSD: src/bin/cat/cat.1,v 1.25 2005/01/16 16:41:55 ru Exp $
.\" $MidnightBSD: src/bin/cat/cat.1,v 1.4 2006/09/09 13:48:40 laffer1 Exp $
.\"
-.Dd September 9, 2006
+.Dd January 29, 2013
.Dt CAT 1
.Os
.Sh NAME
@@ -41,7 +41,7 @@
.Nd concatenate and print files
.Sh SYNOPSIS
.Nm
-.Op Fl benstuv
+.Op Fl belnstuv
.Op Fl D Ar date_fmt
.Op Ar
.Sh DESCRIPTION
@@ -54,7 +54,7 @@
If
.Ar file
is a single dash
-.Pq Sq \&-
+.Pq Sq Fl
or absent,
.Nm
reads from the standard input.
@@ -81,6 +81,16 @@
option), and display a dollar sign
.Pq Ql \&$
at the end of each line.
+.It Fl l
+Set an exclusive advisory lock on the standard output file descriptor.
+This lock is set using
+.Xr fcntl 2
+with the
+.Dv F_SETLKW
+command.
+If the output file is already locked,
+.Nm
+will block until the lock is acquired.
.It Fl n
Number the output lines, starting at 1.
.It Fl s
@@ -120,7 +130,7 @@
.Dl "cat file1"
.Pp
will print the contents of
-.Ar file1
+.Pa file1
to the standard output.
.Pp
The command:
@@ -128,15 +138,15 @@
.Dl "cat file1 file2 > file3"
.Pp
will sequentially print the contents of
-.Ar file1
+.Pa file1
and
-.Ar file2
+.Pa file2
to the file
-.Ar file3 ,
+.Pa file3 ,
truncating
-.Ar file3
+.Pa file3
if it already exists.
-See the manual page for your shell (i.e.,
+See the manual page for your shell (e.g.,
.Xr sh 1 )
for more information on redirection.
.Pp
@@ -145,21 +155,21 @@
.Dl "cat file1 - file2 - file3"
.Pp
will print the contents of
-.Ar file1 ,
+.Pa file1 ,
print data it receives from the standard input until it receives an
.Dv EOF
.Pq Sq ^D
character, print the contents of
-.Ar file2 ,
+.Pa file2 ,
read and output contents of the standard input again, then finally output
the contents of
-.Ar file3 .
+.Pa file3 .
Note that if the standard input referred to a file, the second dash
on the command-line would have no effect, since the entire contents of the file
would have already been read and printed by
.Nm
when it encountered the first
-.Ql \&-
+.Sq Fl
operand.
.Pp
The command:
@@ -193,7 +203,7 @@
specification.
.Pp
The flags
-.Op Fl benstvD
+.Op Fl belnstvD
are extensions to the specification.
.Sh HISTORY
A
@@ -208,7 +218,9 @@
Because of the shell language mechanism used to perform output
redirection, the command
.Dq Li cat file1 file2 > file1
-will cause the original data in file1 to be destroyed!
+will cause the original data in
+.Pa file1
+to be destroyed!
.Pp
The
.Nm
Modified: trunk/bin/cat/cat.c
===================================================================
--- trunk/bin/cat/cat.c 2014-10-03 03:59:08 UTC (rev 6822)
+++ trunk/bin/cat/cat.c 2014-10-03 04:10:32 UTC (rev 6823)
@@ -68,8 +68,8 @@
#define DATEPFX_MAXLEN 1024
-int bflag, eflag, nflag, sflag, tflag, vflag;
-int rval;
+static int bflag, eflag, lflag, nflag, sflag, tflag, vflag;
+static int rval;
static time_t prev_time;
static const char *datefmt;
static char *datepfx;
@@ -85,14 +85,30 @@
static int udom_open(const char *path, int flags);
#endif
+/*
+ * Memory strategy threshold, in pages: if physmem is larger than this,
+ * use a large buffer.
+ */
+#define PHYSPAGES_THRESHOLD (32 * 1024)
+
+/* Maximum buffer size in bytes - do not allow it to grow larger than this. */
+#define BUFSIZE_MAX (2 * 1024 * 1024)
+
+/*
+ * Small (default) buffer size in bytes. It's inefficient for this to be
+ * smaller than MAXPHYS.
+ */
+#define BUFSIZE_SMALL (MAXPHYS)
+
int
main(int argc, char *argv[])
{
int ch;
+ struct flock stdout_lock;
setlocale(LC_CTYPE, "");
- while ((ch = getopt(argc, argv, "bD:enstuv")) != -1)
+ while ((ch = getopt(argc, argv, "bD:elnstuv")) != -1)
switch (ch) {
case 'b':
bflag = nflag = 1; /* -b implies -n */
@@ -100,6 +116,9 @@
case 'e':
eflag = vflag = 1; /* -e implies -v */
break;
+ case 'l':
+ lflag = 1;
+ break;
case 'n':
nflag = 1;
break;
@@ -123,6 +142,15 @@
}
argv += optind;
+ if (lflag) {
+ stdout_lock.l_len = 0;
+ stdout_lock.l_start = 0;
+ stdout_lock.l_type = F_WRLCK;
+ stdout_lock.l_whence = SEEK_SET;
+ if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
+ err(EXIT_FAILURE, "stdout");
+ }
+
/*
* Test date format so the user will get an error sooner
* rather than later
@@ -144,7 +172,7 @@
static void
usage(void)
{
- fprintf(stderr, "usage: cat [-benstuv] [-D datefmt] [file ...]\n");
+ fprintf(stderr, "usage: cat [-belnstuv] [-D datefmt] [file ...]\n");
exit(1);
/* NOTREACHED */
}
@@ -152,18 +180,17 @@
static void
scanfiles(char *argv[], int cooked)
{
- int i = 0;
+ int fd, i;
char *path;
FILE *fp;
+ i = 0;
while ((path = argv[i]) != NULL || i == 0) {
- int fd;
-
if (path == NULL || strcmp(path, "-") == 0) {
filename = "stdin";
fd = STDIN_FILENO;
} else {
- filename = path;
+ filename = path;
fd = open(path, O_RDONLY);
#ifndef NO_UDOM_SUPPORT
if (fd < 0 && errno == EOPNOTSUPP)
@@ -272,9 +299,17 @@
if (buf == NULL) {
if (fstat(wfd, &sbuf))
err(1, "stdout");
- bsize = MAX(sbuf.st_blksize, 1024);
+ if (S_ISREG(sbuf.st_mode)) {
+ /* If there's plenty of RAM, use a large copy buffer */
+ if (sysconf(_SC_PHYS_PAGES) > PHYSPAGES_THRESHOLD)
+ bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8);
+ else
+ bsize = BUFSIZE_SMALL;
+ } else
+ bsize = MAX(sbuf.st_blksize,
+ (blksize_t)sysconf(_SC_PAGESIZE));
if ((buf = malloc(bsize)) == NULL)
- err(1, "buffer");
+ err(1, "malloc() failure of IO buffer");
}
while ((nr = read(rfd, buf, bsize)) > 0)
for (off = 0; nr; nr -= nw, off += nw)
@@ -358,7 +393,7 @@
break;
}
}
- return(fd);
+ return (fd);
}
#endif
More information about the Midnightbsd-cvs
mailing list