This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC][PATCH] Add envvar IO_BUFMODE to forcibly set buffering mode


On 3/22/2017 1:14 PM, Sunyeop Lee wrote:
   I thought it's too hard and tricky to solve this problem. Some of
the solutions are: to modify the source code, to open a pty to get the
output through it, or to use LD_PRELOAD to hook printf or some
functions.
   Therefore, I propose a new environment variable IO_BUFMODE to
forcibly set the buffering mode in these cases. To force "fully
buffering mode", I can easily set IO_BUFMODE=0. To force "line
buffering mode", I set IO_BUFMODE=1. And to force "no buffered mode",
I set IO_BUFMODE=2. The constants are from _IOFBF, _IOLBF, _IONBF used
in setvbuf().

A few concerns with this: it applies the change to every opened file,
which I doubt is what you want; it will make writes to files be
line-buffered at all times, which is likely not what you want.  Also,
I'm not sure calling getenv() for every file open is good for
performance.  And I'm a bit dubious about your just copying in the
constants _IOFBF and friends.

Here we have a similar issue in one application and found that solving
it with LD_PRELOAD was not that onerous.  We wanted to spawn
subprocesses and force console stdout to be line buffered, even if the
whole process group was having its output passed into a pipe.
Accordingly, the main process does an fstat() on stdout to get its
dev/ino information and puts that into $STDIO_LBF_DEV_INO,
then sets $LD_PRELOAD to point to a trivial program that does this:

static void __attribute((constructor)) set_linebuf(void)
{
  // Get "dev" and "ino" from the environment.
  unsigned long dev, ino;
  const char* env = getenv("STDIO_LBF_DEV_INO");
  if (env == NULL || sscanf(env, "%lu:%lu", &dev, &ino) != 2)
    return;

  // Set line buffering if stdout is pointing to the specified dev/ino.
  struct stat s;
  if (fstat(STDOUT_FILENO, &s) == 0 && s.st_ino == ino && s.st_dev == dev)
    setlinebuf(stdout);
}

--
Chris Metcalf, Mellanox Technologies
http://www.mellanox.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]