看板 DFBSD_submit 關於我們 聯絡資訊
This is a multi-part message in MIME format. --Multipart=_Tue__8_Jun_2004_15_19_33_-0700_j5/IXsqBHHH05cFU Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Tue, 8 Jun 2004 23:34:15 +0200 Simon 'corecode' Schubert <corecode@fs.ei.tum.de> wrote: > On 08.06.2004, at 23:02, Chris Pressey wrote: > > > The installer popen()'s "cpdup -vvv src dest" and it reads from this > > pipe to monitor cpdup's progress. Unfortunately, since cpdup's > > output is fully buffered, cpdup's progress can't be usefully > > measured this way. > > This patch simply gives us a way to make cpdup's output unbuffered, > > so we can get it through the pipe as cpdup generates it. > > As I wrote some months ago: this is a thing a lot of programs could > use (sed, awk, grep etc IIRC) > > Now, we could add a flag for every single program to write unbuffered > (linebuffered) output. Or we could do some (non-POSIX?) magic in libc > to get most of this just fixed by doing a env > LIBC_STDOUT_BUFFERING=line $program or whatever... > > opinions about this? The man pages make it sound a bit like this is already possible, but I can't figure out how to do it. man 2 execve: "File descriptors open in the calling process image remain open in the new process image, except for those for which the close-on-exec flag is set (see close(2) and fcntl(2)). Descriptors that remain open are unaffected by execve()." man 2 close: "For this reason, the call ``fcntl(d, F_SETFD, 1)'' is provided, which arranges that a descriptor will be closed after a successful execve; the call ``fcntl(d, F_SETFD, 0)'' restores the default, which is to not close the descriptor." So by the sounds of it, the attached program should be able to run another program, forcing that other program's stdout to be unbufferred. But in (a small amount of) testing, I couldn't seem to get that behaviour. It's possible that libc unconditionally sets the output to fully bufferred in the prologue code, in which case it might be a simple matter of making that conditional on something, then using a little hack like the attached program. I'll look at the libc startup code a little later. -Chris --Multipart=_Tue__8_Jun_2004_15_19_33_-0700_j5/IXsqBHHH05cFU Content-Type: text/plain; name="xraw.c" Content-Disposition: attachment; filename="xraw.c" Content-Transfer-Encoding: 7bit #include <fcntl.h> #include <stdio.h> #include <unistd.h> extern char **environ; int main(int argc, char **argv) { setvbuf(stdout, NULL, _IONBF, 0); fcntl(STDOUT_FILENO, F_SETFD, 0); execve(argv[1], &argv[1], environ); } --Multipart=_Tue__8_Jun_2004_15_19_33_-0700_j5/IXsqBHHH05cFU--