bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: address@hidden: Re: CVS commit: pkgsrc/devel/m4]


From: Eric Blake
Subject: Re: address@hidden: Re: CVS commit: pkgsrc/devel/m4]
Date: Thu, 26 Jul 2007 07:25:23 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.5) Gecko/20070716 Thunderbird/2.0.0.5 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Joerg Sonnenberger on 7/25/2007 7:59 AM:
> OK, I'm still not fully sure I understand all parts of the problem. The
> flushing happens in debug_flush_files, right? When the called programs
> reads from stdin itself, is m4 supposed to see such changes?

Yes, according to the rules of POSIX.

> This would
> mandate an explicit after the program is executed as well.

Not on a compliant system, since m4 follows the rules spelled out by POSIX:

http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_05.html

Section 2.5.1 deals with the interaction of file descriptors and stdio
streams.  The fact that m4 is creating a child that inherits m4's stdin is
an example of two handles to a given fd, with two changes to the active
handle.  For the first change, m4 wants to hand control of the active
handle to the child; it follows the last bullet of the list of
requirements for the owner of the first handle:

"If the stream is open with a mode that allows reading and the underlying
open file description refers to a device that is capable of seeking, the
application shall either perform an fflush(), or the stream shall be
closed.  Then the child process need do nothing special to start reading
at the correct offset." [and this paragraph is yet more proof that POSIX
2001 requires fflush(stdin) to work]

The second transfer of active handle occurs when the child exits and
returns control to m4.  Here, the child falls under the same bullet, and
the act of exiting the child (or if the child does an explicit fflush)
will set the offset of the fd to the next byte unread by the child.  At
which point m4 needs do nothing to become the active handle, and should
pick up where the child left off, with no extra stdio calls required on
m4's part (that is, if stdio is POSIX compliant).

> What happens
> if the program modifies the regular file opened for stdin?

m4 has no control over a child process, and whether it will correctly
position the offset of the fd if it did a partial read of a seekable
stdin.  But having m4 comply with POSIX when it invokes a non-POSIX child
process is not a requirement (in other words, if the child fails to
restore the offset of fd 0 back to the next unread byte, m4 will not see
those bytes, but it is not m4's fault).  However, in the case where the
child process also follows rules about correctly positioning seekable
stdin to the next unread byte, then the approach I took in m4 is the only
way I know for m4 to also follow POSIX rules about its treatment of stdin;
ie. m4 will pick up reading where the child process left off (yes, this is
one of the places in Unix where the actions of a child process are
observable in the environment of the parent).

On a system where m4 and sed both follow POSIX rules, this is an example
of the above rules (and I use this example in the testsuite for CVS head
of m4
http://cvs.savannah.gnu.org/viewvc/m4/tests/others.at?revision=1.35&root=m4&view=markup;
it is conditionally run after first checking whether sed also obeys POSIX
rules for seekable stdin):

$ cat <<\EOF >in.m4
define(`foo', `FOO')m4 foo
syscmd(`sed -e "s/foo/bar/;q"')sed foo
m4 foo
EOF
$ m4 in.m4
m4 FOO
sed bar
m4 FOO
$

> If I
> understand the implications correctly, the only correct approach would
> be to disable buffering before calling the program and reenable that
> afterwards. That should be portable as well.

Nope.  It may work on some systems, but the POSIX specification of setvbuf
states that it may only safely be used prior to any I/O on the stream.  It
is not portable to go switching m4's copy of the stream between buffered
and unbuffered, once m4 has started reading from it, and I am not about to
make m4 use stdin unbuffered from the getgo.  So that rules out your idea
of setvbuf.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGqKDD84KuGfSFAYARAuJiAJ9NVdqK9Fblr6NfiT3AXE2ppE5rsQCgkIbl
NjdMI1BMj7Hgxl7Z+MFAbG8=
=mI40
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]