The yesno module has a problem on platforms where exit() does not implicitly flush seekable input streams (this behavior of exit() is contrary to POSIX, but glibc behaves this way, and Ulrich was unwilling to fix the glibc bug [1]). Basically, because the yesno module consumes input from stdin, if the application does not restore the offset of the underlying fd to the next unread byte prior to a successful exit, then data is lost from subsequent applications that also read from the file descriptor.
For an example of the bug, try this on Linux (tested with glibc 2.3): $ touch a b $ echo 'n y' > blah $ (export LC_ALL=C; mv -vi a b; mv -vi a b) < blah mv: overwrite `b'? mv: overwrite `b'? $ echo $? 0 $ ls ? a b contrasted to Solaris or cygwin (where exit() already takes care of flushing seekable stdin): $ touch a b $ echo 'n y' > blah $ (export LC_ALL=C; mv -vi a b; mv -vi a b) < blah mv: overwrite `b'? mv: overwrite `b'? `a' -> `b' $ echo $? 0 $ ls ? b Basically, on buggy platforms, the first mv did not reset the file pointer to the unread line "y", so the second mv saw EOF instead of the affirmative response. The end result was a violation of POSIX semantics on Linux. The closein module is capable of resolving this problem. However, rather than fix all of the affected applications one-by-one (the list includes, but is not limited to, coreutils' cp, ln, mv, rm, and remove; and findutils' find), it would be nicer to fix this just once in yesno. OK to apply the patch below? [1] http://sources.redhat.com/bugzilla/show_bug.cgi?id=3746 2007-08-17 Eric Blake <[EMAIL PROTECTED]> Don't consume too much input when stdin is seekable. * lib/yesno.c (yesno): Flush seekable stdin. * modules/yesno (Depends-on): Add fflush. Index: modules/yesno =================================================================== RCS file: /sources/gnulib/gnulib/modules/yesno,v retrieving revision 1.13 diff -u -p -r1.13 yesno --- modules/yesno 13 Oct 2006 12:40:23 -0000 1.13 +++ modules/yesno 17 Aug 2007 19:56:38 -0000 @@ -8,6 +8,7 @@ lib/yesno.h m4/yesno.m4 Depends-on: +fflush getline rpmatch stdbool Index: lib/yesno.c =================================================================== RCS file: /sources/gnulib/gnulib/lib/yesno.c,v retrieving revision 1.17 diff -u -p -r1.17 yesno.c --- lib/yesno.c 14 Dec 2006 18:47:36 -0000 1.17 +++ lib/yesno.c 17 Aug 2007 19:56:38 -0000 @@ -1,6 +1,6 @@ /* yesno.c -- read a yes/no response from stdin - Copyright (C) 1990, 1998, 2001, 2003, 2004, 2005, 2006 Free + Copyright (C) 1990, 1998, 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -23,6 +23,7 @@ #include <stdlib.h> #include <stdio.h> +#include <unistd.h> #if ENABLE_NLS # include "getline.h" @@ -60,5 +61,18 @@ yesno (void) c = getchar (); #endif + /* POSIX requires that if stdin was seekable, that the application + leave the underlying fd positioned at the next unread byte. + glibc is a notorious offender of not doing this automatically at + exit() [glibc bug 3746], even though that is also required by + POSIX. But rather than make applications use the closein module, + we just flush seekable input streams here. gnulib's fflush + module is undefined when doing fflush on non-seekable files, + hence the use of lseek to figure out whether we can do the seek. + The sequence fflush/fseeko is guaranteed by POSIX and by gnulib + to do what we want, even though it is undefined in C99. */ + if (lseek (STDIN_FILENO, 0, SEEK_CUR) >= 0 && fflush (stdin) == 0) + fseeko (stdin, 0, SEEK_CUR); + return yes; } -- View this message in context: http://www.nabble.com/yesno-module-consumes-too-much-input-tf4287835.html#a12206260 Sent from the Gnulib mailing list archive at Nabble.com.