Re: [repost] Patch to make cpdup's stdout unbuffered

看板DFBSD_submit作者時間21年前 (2004/06/09 19:32), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串8/9 (看更多)
This is a multi-part message in MIME format. --Multipart=_Tue__8_Jun_2004_20_11_26_-0700_=EwjN+qSCNn=dBcH Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Whoops, attached the wrong patch. The right one should be attached this time. -Chris On Tue, 8 Jun 2004 20:07:35 -0700 Chris Pressey <cpressey@catseye.mine.nu> wrote: > On Tue, 8 Jun 2004 16:23:05 -0700 (PDT) > Matthew Dillon <dillon@apollo.backplane.com> wrote: > > > :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? > > : > > :cheers > > : simon > > > > Say what? No, we are not hacking up libc to turn off buffering in > > some magic way. Buffering is what you want for the vast, vast > > majority of programs that are run from the command line. We > > certainly are not going to add yet another environment variable > > that libc has to check every time a program is started up. > > > > Just add an option to cpdup that calls setvbuf() on stdout. > > I'll take that as a green light to commit the previously posted cpdup > patch. > > However, I think I just discovered a potential general solution. I > strongly suspected there would be a way to do it with standard BSD > mechanisms, and lo and behold there is a userland utility already set up > to exploit those mechanisms. On FreeBSD 4.9, try popen()'ing: > > script -q /dev/null your_favourite_program_with_buffered_output > > According to my testing, the result should be unbuffered. This is > thanks to a fairly recent MFC to script(1) which allows its stdin/out > to be something other than a terminal. I've ported the MFC - it's > attached to this e-mail - and I'd like to commit it pending review. > > However, there still seem to be some small issues with combining > script(1) and popen(). Namely, when the pipe is forcefully pclose()'ed, > the script(1) process exits, but the cpdup process doesn't :( So until > that's sorted out, I'll stick with cpdup -u in the installer. > > -Chris > --Multipart=_Tue__8_Jun_2004_20_11_26_-0700_=EwjN+qSCNn=dBcH Content-Type: text/plain; name="script.c.diff" Content-Disposition: attachment; filename="script.c.diff" Content-Transfer-Encoding: 7bit Index: usr.bin/script/script.c =================================================================== RCS file: /home/dcvs/src/usr.bin/script/script.c,v retrieving revision 1.4 diff -u -r1.4 script.c --- usr.bin/script/script.c 28 Mar 2004 01:02:54 -0000 1.4 +++ usr.bin/script/script.c 9 Jun 2004 02:37:00 -0000 @@ -32,7 +32,7 @@ * * @(#) Copyright (c) 1980, 1992, 1993 The Regents of the University of California. All rights reserved. * @(#)script.c 8.1 (Berkeley) 6/6/93 - * $FreeBSD: src/usr.bin/script/script.c,v 1.11.2.1 2000/07/20 10:35:21 kris Exp $ + * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/usr.bin/script/script.c,v 1.11.2.2 2004/03/13 09:21:00 cperciva Exp $ * $DragonFly: src/usr.bin/script/script.c,v 1.4 2004/03/28 01:02:54 cpressey Exp $ */ @@ -58,7 +58,7 @@ int master, slave; int child; char *fname; -int qflg; +int qflg, ttyflg; struct termios tt; @@ -118,10 +118,17 @@ if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) err(1, "%s", fname); - tcgetattr(STDIN_FILENO, &tt); - ioctl(STDIN_FILENO, TIOCGWINSZ, &win); - if (openpty(&master, &slave, NULL, &tt, &win) == -1) - err(1, "openpty"); + if (ttyflg = isatty(STDIN_FILENO)) { + if (tcgetattr(STDIN_FILENO, &tt) == -1) + err(1, "tcgetattr"); + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) + err(1, "ioctl"); + if (openpty(&master, &slave, NULL, &tt, &win) == -1) + err(1, "openpty"); + } else { + if (openpty(&master, &slave, NULL, NULL, NULL) == -1) + err(1, "openpty"); + } if (!qflg) { tvec = time(NULL); @@ -129,10 +136,13 @@ fprintf(fscript, "Script started on %s", ctime(&tvec)); fflush(fscript); } - rtt = tt; - cfmakeraw(&rtt); - rtt.c_lflag &= ~ECHO; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt); + + if (ttyflg) { + rtt = tt; + cfmakeraw(&rtt); + rtt.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt); + } child = fork(); if (child < 0) { @@ -161,8 +171,10 @@ break; if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) { cc = read(STDIN_FILENO, ibuf, sizeof(ibuf)); - if (cc <= 0) + if (cc < 0) break; + if (cc == 0) + write(master, ibuf, 0); if (cc > 0) { write(master, ibuf, cc); if (kflg && tcgetattr(master, &stt) >= 0 && @@ -252,7 +264,8 @@ { time_t tvec; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt); + if (ttyflg) + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt); tvec = time(NULL); if (!qflg) { fprintf(fscript,"\nScript done on %s", ctime(&tvec)); --Multipart=_Tue__8_Jun_2004_20_11_26_-0700_=EwjN+qSCNn=dBcH--
文章代碼(AID): #10nlKu00 (DFBSD_submit)
討論串 (同標題文章)
文章代碼(AID): #10nlKu00 (DFBSD_submit)