Skip to content

Commit 398caac

Browse files
author
jlh
committed
Import stdbuf(1) and the shared library it relies on.
This tool changes the default buffering behaviour of standard stdio streams. It only works on dynamic binaries. To make it work for static ones it would require cluttering stdio because there no single entry point. PR: 166660 Reviewed by: current@, jhb Approved by: kib (mentor) MFC after: 1 week git-svn-id: svn+ssh://svn.freebsd.org/base/head@234772 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
1 parent 0926e2c commit 398caac

File tree

9 files changed

+463
-0
lines changed

9 files changed

+463
-0
lines changed

lib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
104104
${_libsmdb} \
105105
${_libsmutil} \
106106
libstand \
107+
libstdbuf \
107108
libstdthreads \
108109
${_libtelnet} \
109110
${_libthr} \

lib/libc/stdio/setbuf.3

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ normally does) it is line buffered.
8383
The standard error stream
8484
.Dv stderr
8585
is always unbuffered.
86+
Note that these defaults maybe be altered using the
87+
.Xr stdbuf 1
88+
utility.
8689
.Pp
8790
The
8891
.Fn setvbuf
@@ -177,6 +180,7 @@ function returns what the equivalent
177180
.Fn setvbuf
178181
would have returned.
179182
.Sh SEE ALSO
183+
.Xr stdbuf 1 ,
180184
.Xr fclose 3 ,
181185
.Xr fopen 3 ,
182186
.Xr fread 3 ,

lib/libstdbuf/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# $FreeBSD$
2+
3+
.include <bsd.own.mk>
4+
5+
LIB= stdbuf
6+
SRCS= stdbuf.c
7+
SHLIB_MAJOR= 1
8+
MAN= libstdbuf.3
9+
10+
WARNS?= 6
11+
12+
.include <bsd.lib.mk>

lib/libstdbuf/libstdbuf.3

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
.\" Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
2+
.\" All rights reserved.
3+
.\"
4+
.\" Redistribution and use in source and binary forms, with or without
5+
.\" modification, are permitted provided that the following conditions
6+
.\" are met:
7+
.\" 1. Redistributions of source code and documentation must retain the above
8+
.\" copyright notice, this list of conditions and the following disclaimer.
9+
.\" 2. Redistributions in binary form must reproduce the above copyright
10+
.\" notice, this list of conditions and the following disclaimer in the
11+
.\" documentation and/or other materials provided with the distribution.
12+
.\"
13+
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14+
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16+
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17+
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18+
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19+
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20+
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21+
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22+
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23+
.\" SUCH DAMAGE.
24+
.\"
25+
.\" $FreeBSD$
26+
.\"
27+
.Dd April 28, 2012
28+
.Dt LIBSTDBUF 3
29+
.Os
30+
.Sh NAME
31+
.Nm libstdbuf
32+
.Nd preloaded library to change standard streams initial buffering
33+
.Sh DESCRIPTION
34+
The
35+
.Nm
36+
library is meant to be preloaded with the
37+
.Ev LD_PRELOAD
38+
environment variable to as to change the initial buffering
39+
of standard input, standard output and standard error streams.
40+
.Pp
41+
Although you may load and configure this library manually,
42+
an utility,
43+
.Xr stdbuf 1 ,
44+
can be used to run a command with the appropriate environment variables.
45+
.Sh ENVIRONMENT
46+
Each stream can be configured indepentently through the following
47+
environment variables (values are defined below):
48+
.Bl -tag -width size -offset indent
49+
.It Ev _STDBUF_I
50+
Initial buffering definition for the standard input stream
51+
.It Ev _STDBUF_O
52+
Initial buffering definition for the standard output stream
53+
.It Ev _STDBUF_E
54+
Initial buffering definition for the standard error stream
55+
.El
56+
.Pp
57+
Each variable may take one of the following values:
58+
.Bl -tag -width size -offset indent
59+
.It Qq 0
60+
unbuffered
61+
.It Qq L
62+
line buffered
63+
.It Qq B
64+
fully buffered with the default buffer size
65+
.It Ar size
66+
fully buffered with a buffer of
67+
.Ar size
68+
bytes (suffixes 'k', 'M' and 'G' are accepted)
69+
.El
70+
.Sh EXAMPLE
71+
In the following example, the stdout stream of the
72+
.Xr awk 1
73+
command
74+
will be fully buffered by default because it does not refer
75+
to a terminal.
76+
.Nm
77+
is used to force it to be line-buffered so
78+
.Xr vmstat 8 Ns 's
79+
output will not stall until the full buffer fills.
80+
.Bd -literal -offset indent
81+
# vmstat 1 | LD_PRELOAD=/usr/lib/libstdbuf.so \\
82+
STDBUF_1=L awk '$2 > 1 || $3 > 1' | cat -n
83+
.Ed
84+
.Pp
85+
See also the manpage of
86+
.Xr stdbuf 1
87+
for a simpler way to do this.
88+
.Sh HISTORY
89+
The
90+
.Nm
91+
library first appeared in
92+
.Fx 8.4 .
93+
.Sh AUTHORS
94+
.An -nosplit
95+
The original idea of the
96+
.Nm
97+
command comes from
98+
.An Padraig Brady
99+
who implemented it in the GNU coreutils.
100+
.An Jeremie Le Hen
101+
implemented it on
102+
.Fx .

lib/libstdbuf/stdbuf.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*-
2+
* Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24+
* SUCH DAMAGE.
25+
*
26+
* $FreeBSD$
27+
*/
28+
29+
#include <err.h>
30+
#include <errno.h>
31+
#include <limits.h>
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
#include <string.h>
35+
36+
static const char *
37+
stream_name(FILE *s)
38+
{
39+
40+
if (s == stdin)
41+
return "stdin";
42+
if (s == stdout)
43+
return "stdout";
44+
if (s == stderr)
45+
return "stderr";
46+
/* This should not happen. */
47+
abort();
48+
}
49+
50+
static void
51+
change_buf(FILE *s, const char *bufmode)
52+
{
53+
char *unit;
54+
size_t bufsize;
55+
int mode;
56+
57+
bufsize = 0;
58+
if (bufmode[0] == '0' && bufmode[1] == '\0')
59+
mode = _IONBF;
60+
else if (bufmode[0] == 'L' && bufmode[1] == '\0')
61+
mode = _IOLBF;
62+
else if (bufmode[0] == 'B' && bufmode[1] == '\0') {
63+
mode = _IOFBF;
64+
bufsize = 0;
65+
} else {
66+
/*
67+
* This library being preloaded, depending on libutil
68+
* would lead to excessive namespace pollution.
69+
* Thus we do not use expand_number().
70+
*/
71+
errno = 0;
72+
bufsize = strtol(bufmode, &unit, 0);
73+
if (errno == EINVAL || errno == ERANGE || unit == bufmode)
74+
warn("Wrong buffer mode '%s' for %s", bufmode,
75+
stream_name(s));
76+
switch (*unit) {
77+
case 'G':
78+
bufsize *= 1024 * 1024 * 1024;
79+
break;
80+
case 'M':
81+
bufsize *= 1024 * 1024;
82+
break;
83+
case 'k':
84+
bufsize *= 1024;
85+
break;
86+
case '\0':
87+
break;
88+
default:
89+
warnx("Unknown suffix '%c' for %s", *unit,
90+
stream_name(s));
91+
return;
92+
}
93+
mode = _IOFBF;
94+
}
95+
if (setvbuf(s, NULL, mode, bufsize) != 0)
96+
warn("Cannot set buffer mode '%s' for %s", bufmode,
97+
stream_name(s));
98+
}
99+
100+
__attribute__ ((constructor)) static void
101+
stdbuf(void)
102+
{
103+
char *i_mode, *o_mode, *e_mode;
104+
105+
i_mode = getenv("_STDBUF_I");
106+
o_mode = getenv("_STDBUF_O");
107+
e_mode = getenv("_STDBUF_E");
108+
109+
if (e_mode != NULL)
110+
change_buf(stderr, e_mode);
111+
if (i_mode != NULL)
112+
change_buf(stdin, i_mode);
113+
if (o_mode != NULL)
114+
change_buf(stdout, o_mode);
115+
}

usr.bin/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ SUBDIR= alias \
143143
sockstat \
144144
split \
145145
stat \
146+
stdbuf \
146147
su \
147148
systat \
148149
tabs \

usr.bin/stdbuf/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# $FreeBSD$
2+
3+
PROG= stdbuf
4+
SRCS= stdbuf.c
5+
6+
WARNS?= 6
7+
8+
.include <bsd.prog.mk>

usr.bin/stdbuf/stdbuf.1

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
.\" Copyright (c) 2012 Jeremie Le Hen <jlh@FreeBSD.org>
2+
.\" All rights reserved.
3+
.\"
4+
.\" Redistribution and use in source and binary forms, with or without
5+
.\" modification, are permitted provided that the following conditions
6+
.\" are met:
7+
.\" 1. Redistributions of source code and documentation must retain the above
8+
.\" copyright notice, this list of conditions and the following disclaimer.
9+
.\" 2. Redistributions in binary form must reproduce the above copyright
10+
.\" notice, this list of conditions and the following disclaimer in the
11+
.\" documentation and/or other materials provided with the distribution.
12+
.\"
13+
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14+
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16+
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17+
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18+
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19+
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20+
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21+
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22+
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23+
.\" SUCH DAMAGE.
24+
.\"
25+
.\" $FreeBSD$
26+
.\"
27+
.Dd April 28, 2012
28+
.Dt STDBUF 1
29+
.Os
30+
.Sh NAME
31+
.Nm stdbuf
32+
.Nd change standard streams initial buffering
33+
.Sh SYNOPSIS
34+
.Nm
35+
.Op Fl e Ar bufdef
36+
.Op Fl i Ar bufdef
37+
.Op Fl o Ar bufdef
38+
.Op Ar command Op ...
39+
.Sh DESCRIPTION
40+
.Nm
41+
is used to change the initial buffering of standard input,
42+
standard output and/or standard error streams for
43+
.Ar command .
44+
It relies on
45+
.Xr libstdbuf 3
46+
which is loaded and configured by
47+
.Nm
48+
through environment variables.
49+
.Pp
50+
The options are as follows:
51+
.Bl -tag -width Ds
52+
.It Fl e Ar bufdef
53+
Set initial buffering of the standard error stream for
54+
.Ar command
55+
as defined by
56+
.Ar bufdef
57+
.Pq see Sx BUFFER DEFINITION .
58+
.It Fl i Ar bufdef
59+
Set initial buffering of the standard input stream for
60+
.Ar command
61+
as defined by
62+
.Ar bufdef
63+
.Pq see Sx BUFFER DEFINITION .
64+
.It Fl o Ar bufdef
65+
Set initial buffering of the standard output stream for
66+
.Ar command
67+
as defined by
68+
.Ar bufdef
69+
.Pq see Sx BUFFER DEFINITION .
70+
.El
71+
.Sh BUFFER DEFINITION
72+
Buffer definition is the same as in
73+
.Xr libstdbuf 3 :
74+
.Bl -tag -width size -offset indent
75+
.It Qq 0
76+
unbuffered
77+
.It Qq L
78+
line buffered
79+
.It Qq B
80+
fully buffered with the default buffer size
81+
.It Ar size
82+
fully buffered with a buffer of
83+
.Ar size
84+
bytes (suffixes 'k', 'M' and 'G' are accepted)
85+
.El
86+
.Sh EXAMPLES
87+
In the following example, the stdout stream of the
88+
.Xr awk 1
89+
command
90+
will be fully buffered by default because it does not refer
91+
to a terminal.
92+
.Nm
93+
is used to force it to be line-buffered so
94+
.Xr vmstat 8 Ns 's
95+
output will not stall until the full buffer fills.
96+
.Bd -literal -offset indent
97+
# vmstat 1 | stdbuf -o L awk '$2 > 1 || $3 > 1' | cat -n
98+
.Ed
99+
.Sh SEE ALSO
100+
.Xr libstdbuf 3 ,
101+
.Xr setvbuf 3
102+
.Sh HISTORY
103+
The
104+
.Nm
105+
utility first appeared in
106+
.Fx 8.4 .
107+
.Sh AUTHORS
108+
.An -nosplit
109+
The original idea of the
110+
.Nm
111+
command comes from
112+
.An Padraig Brady
113+
who implemented it in the GNU coreutils.
114+
.An Jeremie Le Hen
115+
implemented it on
116+
.Fx .

0 commit comments

Comments
 (0)