Date: Fri, 17 Feb 2012 18:00:31 GMT From: Jeremie Le Hen <jeremie@le-hen.org> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/154915: [libc] [patch] Force stdio output streams to line-buffered mode Message-ID: <201202171800.q1HI0VrW090362@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/154915; it has been noted by GNATS. From: Jeremie Le Hen <jeremie@le-hen.org> To: Oliver Fromme <olli@lurza.secnetix.de> Cc: bug-followup@FreeBSD.org, jeremie@le-hen.org Subject: Re: kern/154915: [libc] [patch] Force stdio output streams to line-buffered mode Date: Fri, 17 Feb 2012 18:53:06 +0100 --n8g4imXOkfNTN/H1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Oliver, On Thu, Feb 16, 2012 at 02:49:50PM +0100, Oliver Fromme wrote: > I think introducing an environment variable for this purpose > is a bad hack. I would advise against this. > > Many tools already have options for unbuffered or line-buffered > output (for example cat -u), and there are also other ways to > circumvent such problems. > > For example, the problem quoted in the PR can be solved like this, > using the -u option of cat: > > $ iostat -x 1 | cat -un | grep ad1 This doesn't help if you enclose a command that doesn't have such an option between pipes. For instance: $ iostat -x 1 | cat -u | tr MG mg | cat -u | grep -n ad1 > or avoiding cat completely (also might be more efficient, > saving one process and one pipe, though I haven't benchmarked > this): > > $ iostat -x 1 | awk '{n+=1} /ad1/{print n, $0}' Right we can almost always replace a pipeline of commands with an awk (or whatever) script. But besides being sometimes inconvenient, saving a process or pipe does not always leads to performance benefits. The very example you took is a good illustration of my point: I sometimes have to dig into big log files and awk is naturally very powerful. Yet I noticed a *huge* performance gap between (gnu) grep and awk: $ time grep -n 'include.*stdio' 'FreeNode/##c.log' > /dev/null 1.10 real 0.97 user 0.12 sys $ time awk '{n+=1} /include.*stdio/{print n, $0}' 'FreeNode/##c.log' > /dev/null 3.74 real 3.63 user 0.08 sys > For certain other cases, I have the following alias in my ~/.zshrc > that simulates a TTY environment for a tool so it is forced to > use line-buffered output: > > alias intty='script -qt0 /dev/null' > > So I can write: > > $ intty sometool -args | grep ... > > However, the intty alias only works when it is the first command > in a pipeline (this is a limitation of the "script" command). I wasn't aware of that. Out of curiosity, I tried the following command in order to test this: $ vmstat 1 | script -qt 0 /dev/null grep . | cat And each line in output is printed twice. I didn't have time to investigate though. > In the above example, the cat command is not the first, but a > subshell can be used to work around this: > > $ intty sh -c 'iostat -x 1 | cat -n' | grep ad1 > > (It should work with any shell that supports aliases, not just > zsh, of course.) > > I suggest closing this PR. Well, an evil hack VS an even eviler workaround which is not as powerful IMHO ;). In fact, I made a far more better of version of my patch which doesn't modify libc. Instead it introduces a new shared library (libstdbuf.so) which is still controlled by environment variables, and an helper command (stdbuf(1)) is provided to do the environment-fu (including LD_PRELOAD) in your stead. Unfortuntately I forgot to update it in the PR database. You will find it attached to this email, I think the bug tracker will show it in the PR afterward. Can you tell me if it better fits your expectations in matter of "low-hackiness"? The standard code path is not modified at all. I would be glad if we could proceed with this, this is a feature I often miss. Thanks a lot for taking time to answer. Regards, -- Jeremie Le Hen Men are born free and equal. Later on, they're on their own. Jean Yanne --n8g4imXOkfNTN/H1 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="stdbuf.diff" diff -urNp src.HEAD_20111506/lib/libc/stdio/setbuf.3 src/lib/libc/stdio/setbuf.3 --- src.HEAD_20111506/lib/libc/stdio/setbuf.3 2007-01-09 01:28:07.000000000 +0100 +++ src/lib/libc/stdio/setbuf.3 2011-08-04 19:00:49.000000000 +0200 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.17 2007/01/09 00:28:07 imp Exp $ +.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.17.10.1 2009/08/03 08:13:06 kensmith Exp $ .\" .Dd June 4, 1993 .Dt 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 -urNp src.HEAD_20111506/lib/libstdbuf/Makefile src/lib/libstdbuf/Makefile --- src.HEAD_20111506/lib/libstdbuf/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ src/lib/libstdbuf/Makefile 2011-08-04 18:49:59.000000000 +0200 @@ -0,0 +1,15 @@ +# $FreeBSD: src/lib/libftpio/Makefile,v 1.17.2.1 2009/08/03 08:13:06 kensmith Exp $ + +.include <bsd.own.mk> + +LIB= stdbuf +SRCS= stdbuf.c +SHLIB_MAJOR= 1 +MAN= libstdbuf.3 + +CFLAGS+= -I${.CURDIR} +LDADD= -lutil + +WARNS?= 6 + +.include <bsd.lib.mk> diff -urNp src.HEAD_20111506/lib/libstdbuf/libstdbuf.3 src/lib/libstdbuf/libstdbuf.3 --- src.HEAD_20111506/lib/libstdbuf/libstdbuf.3 1970-01-01 01:00:00.000000000 +0100 +++ src/lib/libstdbuf/libstdbuf.3 2011-08-04 18:47:04.000000000 +0200 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2011 Jeremie Le Hen +.\" 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$ +.\" +.Dd August 4, 2011 +.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_0 +Initial buffering definition for the standard input stream +.It Ev STDBUF_1 +Initial buffering definition for the standard output stream +.It Ev STDBUF_2 +Initial buffering definition for the standard error stream +.It Ev _STDBUF_I +GNU-compatible variable for +.Ev STDBUF_0 +.It Ev _STDBUF_O +GNU-compatible variable equivalent to +.Ev STDBUF_1 +.It Ev _STDBUF_E +GNU-compatible variable equivalent to +.Ev STDBUF_2 +.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 +.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 9.0 . +.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 -urNp src.HEAD_20111506/lib/libstdbuf/stdbuf.c src/lib/libstdbuf/stdbuf.c --- src.HEAD_20111506/lib/libstdbuf/stdbuf.c 1970-01-01 01:00:00.000000000 +0100 +++ src/lib/libstdbuf/stdbuf.c 2011-08-04 18:17:07.000000000 +0200 @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2011 Jeremie Le Hen + * 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> +#include <libutil.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) +{ + size_t bufsiz; + uint64_t sizearg; + int mode; + + bufsiz = 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; + bufsiz = 0; + } else { + errno = 0; + if (expand_number(bufmode, &sizearg) == -1) { + warn("Wrong buffer mode '%s' for %s", bufmode, + stream_name(s)); + return; + } + if (sizearg > SIZE_T_MAX) { + warn("Buffer size too big for %s", stream_name(s)); + return; + } + mode = _IOFBF; + bufsiz = (size_t)sizearg; + } + if (setvbuf(s, NULL, mode, bufsiz) != 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_0"); + if (i_mode == NULL) + i_mode = getenv("_STDBUF_I"); + o_mode = getenv("STDBUF_1"); + if (o_mode == NULL) + o_mode = getenv("_STDBUF_O"); + e_mode = getenv("STDBUF_2"); + if (e_mode == NULL) + e_mode = getenv("_STDBUF_E"); + + if (e_mode) + change_buf(stderr, e_mode); + if (i_mode) + change_buf(stdin, i_mode); + if (o_mode) + change_buf(stdout, o_mode); +} diff -urNp src.HEAD_20111506/usr.bin/stdbuf/Makefile src/usr.bin/stdbuf/Makefile --- src.HEAD_20111506/usr.bin/stdbuf/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ src/usr.bin/stdbuf/Makefile 2011-08-02 19:16:30.000000000 +0200 @@ -0,0 +1,8 @@ +# $Id$ + +PROG= stdbuf +SRCS= stdbuf.c + +WARNS?= 6 + +.include <bsd.prog.mk> Files src.HEAD_20111506/usr.bin/stdbuf/sh.core and src/usr.bin/stdbuf/sh.core differ diff -urNp src.HEAD_20111506/usr.bin/stdbuf/stdbuf.1 src/usr.bin/stdbuf/stdbuf.1 --- src.HEAD_20111506/usr.bin/stdbuf/stdbuf.1 1970-01-01 01:00:00.000000000 +0100 +++ src/usr.bin/stdbuf/stdbuf.1 2011-08-04 18:46:35.000000000 +0200 @@ -0,0 +1,124 @@ +.\" Copyright (C) 2011 Jeremie Le Hen +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" 4. Neither the name of Caldera International, Inc. nor the names of other +.\" contributors may be used to endorse or promote products derived from +.\" this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. 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 CALDERA INTERNATIONAL, INC. 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: src/usr.bin/dc/dc.1,v 1.2 2010/01/22 23:50:46 delphij Exp $ +.\" +.Dd August 4, 2011 +.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 +.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 9.0 . +.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 -urNp src.HEAD_20111506/usr.bin/stdbuf/stdbuf.c src/usr.bin/stdbuf/stdbuf.c --- src.HEAD_20111506/usr.bin/stdbuf/stdbuf.c 1970-01-01 01:00:00.000000000 +0100 +++ src/usr.bin/stdbuf/stdbuf.c 2011-08-04 18:17:50.000000000 +0200 @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2011 Jeremie Le Hen + * 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); + +static void +usage(int s) +{ + + fprintf(stderr, "Usage: %s [-e bufdef] [-i bufdef] [-o bufdef] " + "<command> [args ...]\n", __progname); + fprintf(stderr, " ``bufdef'' being:\n"); + fprintf(stderr, " - \"0\" to disable buffering;\n"); + fprintf(stderr, " - \"L\" to set line-buffering;\n"); + fprintf(stderr, " - <size> to set full-buffering.\n"); + exit(s); +} + +int +main(int argc, char *argv[]) +{ + int i; + char *ibuf = NULL, *obuf = NULL, *ebuf = NULL; + char *preload0, *preload1; + + 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 (ibuf != NULL && setenv("STDBUF_0", ibuf, 1) == -1) + warn("Failed to set environment variable: %s=%s", + "STDBUF_0", ibuf); + if (obuf != NULL && setenv("STDBUF_1", obuf, 1) == -1) + warn("Failed to set environment variable: %s=%s", + "STDBUF_1", obuf); + if (ebuf != NULL && setenv("STDBUF_2", ebuf, 1) == -1) + warn("Failed to set environment variable: %s=%s", + "STDBUF_2", 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]); +} --n8g4imXOkfNTN/H1--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202171800.q1HI0VrW090362>