On 10/25/06 7:53 AM, "John Jetmore" <jetmore@???> wrote:
> On Wed, 25 Oct 2006, Philip Hazel wrote:
>
>> Looks me as if the dup'ing and then closing the 'other' fd is having the
>> (to me, unexpected) effect of marking the copied fd as "at eof".
>
> What's wierd is that stdin is being marked as "at eof" on Linux and
> Solaris also. It's just that subsequent reads still succeed.
>
>> However, I too am no expert at this level of system call. I do know,
>> however, that on systems I've used (Solaris, Linux), you can usually
>> read "beyond" eof on terminal input without using clearerr(). That is,
>> you can type ^D and the program will see "eof", but if it reads again
>> you can type more. My guess is that this is different on Darwin. I
>
> The read that's actually behaving differently in Darwin is the fgets() in
> exim.c:get_stdinput(). The man pages on Darwin and Linux appear identical
> for fgets(). HOWEVER, I was just looking at the man pages on both systems
> for getc(), which is the call in filtertest.c:read_message_body() that's
> actually setting EOF on stdin. Check this out:
>
> Darwin:
> RETURN VALUES
> <snip>
> global variable errno is set to indicate the error. The end-of-file con-
> dition is remembered, even on a terminal, and all subsequent attempts to
> read will return EOF until the condition is cleared with clearerr(3).
>
> So it looks like Darwin's libs just don't behave the same way. I played
> around with variations of the attached code and it really does seem to be
> that Darwin sets eof on a stream permanently (until clearerr() at least)
> and other systems clear eof themselves on subsequent reads.
>
>> It seems to me that there's no harm in calling clearerr()
>> unconditionally. On the other hand, re-reading the man page for "dup",
>> it may be that I shouldn't have used "close" there. Please can you test
>> by removing that "close" call?
>
> I did test, the close doesn't matter. It seems like an unconditional
> clearerr(stdin) will fix the problem on Darwin (and possibly other
> systems) and do not harm on other systems.
The proposed fix feels right (whether installed conditionally or not as
seems best).
Mac OS X is different in that, instead of terminal programs pretending to be
terminals--which could also be attached the old fashioned way--Mac OS X
knows there won't be terminals attached, but only terminal programs.
It might be interesting--and necessary if the change is unconditional--to
get this tested on Exim under Cygwin (sorry, I don't think I'll install
Cygwin on my XP, which runs under the Parallels virtual machine, to find
out).
--John