summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Le Hen <jlh@FreeBSD.org>2012-04-28 20:52:20 +0000
committerJeremie Le Hen <jlh@FreeBSD.org>2012-04-28 20:52:20 +0000
commit6486b015fc84e96725fef22b0e3363351399ae83 (patch)
tree82e8a2c00b0e28749e9fc998b6ae46e1602dfc3d
parent64cc18cc015fc09d2cf9b1fb3d4cd76d3cef1634 (diff)
downloadsrc-test2-6486b015fc84e96725fef22b0e3363351399ae83.tar.gz
src-test2-6486b015fc84e96725fef22b0e3363351399ae83.zip
Notes
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libc/stdio/setbuf.34
-rw-r--r--lib/libstdbuf/Makefile12
-rw-r--r--lib/libstdbuf/libstdbuf.3102
-rw-r--r--lib/libstdbuf/stdbuf.c115
-rw-r--r--usr.bin/Makefile1
-rw-r--r--usr.bin/stdbuf/Makefile8
-rw-r--r--usr.bin/stdbuf/stdbuf.1116
-rw-r--r--usr.bin/stdbuf/stdbuf.c104
9 files changed, 463 insertions, 0 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 876dbb8a00d0..2bff80aa1366 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -104,6 +104,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
${_libsmdb} \
${_libsmutil} \
libstand \
+ libstdbuf \
libstdthreads \
${_libtelnet} \
${_libthr} \
diff --git a/lib/libc/stdio/setbuf.3 b/lib/libc/stdio/setbuf.3
index be8803404b89..d02d7ea579e8 100644
--- a/lib/libc/stdio/setbuf.3
+++ b/lib/libc/stdio/setbuf.3
@@ -83,6 +83,9 @@ normally does) it is line buffered.
The standard error stream
.Dv stderr
is always unbuffered.
+Note that these defaults maybe be altered using the
+.Xr stdbuf 1
+utility.
.Pp
The
.Fn setvbuf
@@ -177,6 +180,7 @@ function returns what the equivalent
.Fn setvbuf
would have returned.
.Sh SEE ALSO
+.Xr stdbuf 1 ,
.Xr fclose 3 ,
.Xr fopen 3 ,
.Xr fread 3 ,
diff --git a/lib/libstdbuf/Makefile b/lib/libstdbuf/Makefile
new file mode 100644
index 000000000000..cf65e4f20ab6
--- /dev/null
+++ b/lib/libstdbuf/Makefile
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+LIB= stdbuf
+SRCS= stdbuf.c
+SHLIB_MAJOR= 1
+MAN= libstdbuf.3
+
+WARNS?= 6
+
+.include <bsd.lib.mk>
diff --git a/lib/libstdbuf/libstdbuf.3 b/lib/libstdbuf/libstdbuf.3
new file mode 100644
index 000000000000..c60ffd7eb850
--- /dev/null
+++ b/lib/libstdbuf/libstdbuf.3
@@ -0,0 +1,102 @@
+.\" Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code and documentation must retain the above
+.\" copyright notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 28, 2012
+.Dt LIBSTDBUF 3
+.Os
+.Sh NAME
+.Nm libstdbuf
+.Nd preloaded library to change standard streams initial buffering
+.Sh DESCRIPTION
+The
+.Nm
+library is meant to be preloaded with the
+.Ev LD_PRELOAD
+environment variable to as to change the initial buffering
+of standard input, standard output and standard error streams.
+.Pp
+Although you may load and configure this library manually,
+an utility,
+.Xr stdbuf 1 ,
+can be used to run a command with the appropriate environment variables.
+.Sh ENVIRONMENT
+Each stream can be configured indepentently through the following
+environment variables (values are defined below):
+.Bl -tag -width size -offset indent
+.It Ev _STDBUF_I
+Initial buffering definition for the standard input stream
+.It Ev _STDBUF_O
+Initial buffering definition for the standard output stream
+.It Ev _STDBUF_E
+Initial buffering definition for the standard error stream
+.El
+.Pp
+Each variable may take one of the following values:
+.Bl -tag -width size -offset indent
+.It Qq 0
+unbuffered
+.It Qq L
+line buffered
+.It Qq B
+fully buffered with the default buffer size
+.It Ar size
+fully buffered with a buffer of
+.Ar size
+bytes (suffixes 'k', 'M' and 'G' are accepted)
+.El
+.Sh EXAMPLE
+In the following example, the stdout stream of the
+.Xr awk 1
+command
+will be fully buffered by default because it does not refer
+to a terminal.
+.Nm
+is used to force it to be line-buffered so
+.Xr vmstat 8 Ns 's
+output will not stall until the full buffer fills.
+.Bd -literal -offset indent
+# vmstat 1 | LD_PRELOAD=/usr/lib/libstdbuf.so \\
+ STDBUF_1=L awk '$2 > 1 || $3 > 1' | cat -n
+.Ed
+.Pp
+See also the manpage of
+.Xr stdbuf 1
+for a simpler way to do this.
+.Sh HISTORY
+The
+.Nm
+library first appeared in
+.Fx 8.4 .
+.Sh AUTHORS
+.An -nosplit
+The original idea of the
+.Nm
+command comes from
+.An Padraig Brady
+who implemented it in the GNU coreutils.
+.An Jeremie Le Hen
+implemented it on
+.Fx .
diff --git a/lib/libstdbuf/stdbuf.c b/lib/libstdbuf/stdbuf.c
new file mode 100644
index 000000000000..1b5d39a63613
--- /dev/null
+++ b/lib/libstdbuf/stdbuf.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *
+stream_name(FILE *s)
+{
+
+ if (s == stdin)
+ return "stdin";
+ if (s == stdout)
+ return "stdout";
+ if (s == stderr)
+ return "stderr";
+ /* This should not happen. */
+ abort();
+}
+
+static void
+change_buf(FILE *s, const char *bufmode)
+{
+ char *unit;
+ size_t bufsize;
+ int mode;
+
+ bufsize = 0;
+ if (bufmode[0] == '0' && bufmode[1] == '\0')
+ mode = _IONBF;
+ else if (bufmode[0] == 'L' && bufmode[1] == '\0')
+ mode = _IOLBF;
+ else if (bufmode[0] == 'B' && bufmode[1] == '\0') {
+ mode = _IOFBF;
+ bufsize = 0;
+ } else {
+ /*
+ * This library being preloaded, depending on libutil
+ * would lead to excessive namespace pollution.
+ * Thus we do not use expand_number().
+ */
+ errno = 0;
+ bufsize = strtol(bufmode, &unit, 0);
+ if (errno == EINVAL || errno == ERANGE || unit == bufmode)
+ warn("Wrong buffer mode '%s' for %s", bufmode,
+ stream_name(s));
+ switch (*unit) {
+ case 'G':
+ bufsize *= 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ bufsize *= 1024 * 1024;
+ break;
+ case 'k':
+ bufsize *= 1024;
+ break;
+ case '\0':
+ break;
+ default:
+ warnx("Unknown suffix '%c' for %s", *unit,
+ stream_name(s));
+ return;
+ }
+ mode = _IOFBF;
+ }
+ if (setvbuf(s, NULL, mode, bufsize) != 0)
+ warn("Cannot set buffer mode '%s' for %s", bufmode,
+ stream_name(s));
+}
+
+__attribute__ ((constructor)) static void
+stdbuf(void)
+{
+ char *i_mode, *o_mode, *e_mode;
+
+ i_mode = getenv("_STDBUF_I");
+ o_mode = getenv("_STDBUF_O");
+ e_mode = getenv("_STDBUF_E");
+
+ if (e_mode != NULL)
+ change_buf(stderr, e_mode);
+ if (i_mode != NULL)
+ change_buf(stdin, i_mode);
+ if (o_mode != NULL)
+ change_buf(stdout, o_mode);
+}
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 85fb6e612399..ce8e48c19927 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -143,6 +143,7 @@ SUBDIR= alias \
sockstat \
split \
stat \
+ stdbuf \
su \
systat \
tabs \
diff --git a/usr.bin/stdbuf/Makefile b/usr.bin/stdbuf/Makefile
new file mode 100644
index 000000000000..ccf139d3e49e
--- /dev/null
+++ b/usr.bin/stdbuf/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= stdbuf
+SRCS= stdbuf.c
+
+WARNS?= 6
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/stdbuf/stdbuf.1 b/usr.bin/stdbuf/stdbuf.1
new file mode 100644
index 000000000000..2e287400c22e
--- /dev/null
+++ b/usr.bin/stdbuf/stdbuf.1
@@ -0,0 +1,116 @@
+.\" Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code and documentation must retain the above
+.\" copyright notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 28, 2012
+.Dt STDBUF 1
+.Os
+.Sh NAME
+.Nm stdbuf
+.Nd change standard streams initial buffering
+.Sh SYNOPSIS
+.Nm
+.Op Fl e Ar bufdef
+.Op Fl i Ar bufdef
+.Op Fl o Ar bufdef
+.Op Ar command Op ...
+.Sh DESCRIPTION
+.Nm
+is used to change the initial buffering of standard input,
+standard output and/or standard error streams for
+.Ar command .
+It relies on
+.Xr libstdbuf 3
+which is loaded and configured by
+.Nm
+through environment variables.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl e Ar bufdef
+Set initial buffering of the standard error stream for
+.Ar command
+as defined by
+.Ar bufdef
+.Pq see Sx BUFFER DEFINITION .
+.It Fl i Ar bufdef
+Set initial buffering of the standard input stream for
+.Ar command
+as defined by
+.Ar bufdef
+.Pq see Sx BUFFER DEFINITION .
+.It Fl o Ar bufdef
+Set initial buffering of the standard output stream for
+.Ar command
+as defined by
+.Ar bufdef
+.Pq see Sx BUFFER DEFINITION .
+.El
+.Sh BUFFER DEFINITION
+Buffer definition is the same as in
+.Xr libstdbuf 3 :
+.Bl -tag -width size -offset indent
+.It Qq 0
+unbuffered
+.It Qq L
+line buffered
+.It Qq B
+fully buffered with the default buffer size
+.It Ar size
+fully buffered with a buffer of
+.Ar size
+bytes (suffixes 'k', 'M' and 'G' are accepted)
+.El
+.Sh EXAMPLES
+In the following example, the stdout stream of the
+.Xr awk 1
+command
+will be fully buffered by default because it does not refer
+to a terminal.
+.Nm
+is used to force it to be line-buffered so
+.Xr vmstat 8 Ns 's
+output will not stall until the full buffer fills.
+.Bd -literal -offset indent
+# vmstat 1 | stdbuf -o L awk '$2 > 1 || $3 > 1' | cat -n
+.Ed
+.Sh SEE ALSO
+.Xr libstdbuf 3 ,
+.Xr setvbuf 3
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 8.4 .
+.Sh AUTHORS
+.An -nosplit
+The original idea of the
+.Nm
+command comes from
+.An Padraig Brady
+who implemented it in the GNU coreutils.
+.An Jeremie Le Hen
+implemented it on
+.Fx .
diff --git a/usr.bin/stdbuf/stdbuf.c b/usr.bin/stdbuf/stdbuf.c
new file mode 100644
index 000000000000..c6951bba72b9
--- /dev/null
+++ b/usr.bin/stdbuf/stdbuf.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define LIBSTDBUF "/usr/lib/libstdbuf.so"
+
+extern char *__progname;
+
+static void
+usage(int s)
+{
+
+ fprintf(stderr, "Usage: %s [-e 0|L|<sz>] [-i 0|L|<sz>] [-o 0|L|<sz>] "
+ "<cmd> [args ...]\n", __progname);
+ exit(s);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *ibuf, *obuf, *ebuf;
+ char *preload0, *preload1;
+ int i;
+
+ ibuf = obuf = ebuf = NULL;
+ while ((i = getopt(argc, argv, ":e:i:o:")) != -1) {
+ switch (i) {
+ case 'e':
+ ebuf = optarg;
+ break;
+ case 'i':
+ ibuf = optarg;
+ break;
+ case 'o':
+ obuf = optarg;
+ break;
+ case ':':
+ warnx("Missing argument for option -%c", optopt);
+ usage(1);
+ break;
+ case '?':
+ default:
+ warnx("Unknown option: %c", optopt);
+ usage(1);
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage(0);
+
+ if (ibuf != NULL && setenv("_STDBUF_I", ibuf, 1) == -1)
+ warn("Failed to set environment variable: %s=%s",
+ "_STDBUF_I", ibuf);
+ if (obuf != NULL && setenv("_STDBUF_O", obuf, 1) == -1)
+ warn("Failed to set environment variable: %s=%s",
+ "_STDBUF_O", obuf);
+ if (ebuf != NULL && setenv("_STDBUF_E", ebuf, 1) == -1)
+ warn("Failed to set environment variable: %s=%s",
+ "_STDBUF_E", ebuf);
+
+ preload0 = getenv("LD_PRELOAD");
+ if (preload0 == NULL)
+ i = asprintf(&preload1, "LD_PRELOAD=" LIBSTDBUF);
+ else
+ i = asprintf(&preload1, "LD_PRELOAD=%s:%s", preload0,
+ LIBSTDBUF);
+
+ if (i < 0 || putenv(preload1) == -1)
+ warn("Failed to set environment variable: %s", preload1);
+
+ execvp(argv[0], argv);
+ err(2, "%s", argv[0]);
+}