Weird Problem with cat

Alexander Dupuy dupuy at douglass.columbia.edu
Tue Nov 29 09:14:57 AEST 1988


In article <PS72234.88Nov22020044 at naakka.tut.fi>, ps72234 at naakka (Pertti Suomela) writes:
|In article <41 at eplrx7.UUCP> mcneill at eplrx7.UUCP (mcneill) writes:
|
|   eplrx7 {root} % cat ~mcneill/.login
|   cat: write error bad file number
|
|Tcsh (I don't know if you were running it) contains a bug.

The problem is not with cat, in fact, cat is the most helpful program you could
run in the circumstance, because it tells you what the problem is.  Most
commands just execute with no output whatsoever.  This is much worse than a
weird error message.  However, the cat error message is still not helpful
enough - I only figured out the bug using ofiles(1), available from a sun-spots
archive near you.

This bug exists in all versions of the csh which do filename completion on Suns
(or other NFS systems) running yellow pages.

What happens is that when getpwnam(3) is called to find the home directory for
some user (~j-user) in the tilde() function, the yellow pages opens up a UDP
socket or two to talk to the various yellow pages daemons (ypbind, ypserv).  It
closes the first of these, but leaves the second one open.  Since the csh keeps
file descriptors 0-3 unused (it stashes stdin, etc. up around 20), the file
descriptor for this socket is usually 1 (aka stdout).  When the csh fork/execs
a program, it moves stdin, back down to the 0-2 range.  But because the yp
socket is already down there, the stdout (1) file descriptor gets closed when
all is said and done (this may be due to close-on-exec being set for 1, or yp
closing it explicitly, or something else, I never bothered to find out).

The result of this is that your cat was invoked with no file descriptor 1.  As
a result it got a write error (EBADF bad file number).  Most programs which
never checked the result of writes to stdout got errors too, but didn't tell
you about them.  You can duplicate this with 'sh -c "program >&-"'.

The fix, in tilde() is to make a call to the undocumented, but extremely useful
yp_unbind() function after you've gotten the answer back from getpwnam(3).  You
shouls also check that the closem() function invokes yp_unbind(), although that
may not be necessary if you fix tilde() (at any rate, it won't hurt).

@alex
-- 
inet: dupuy at columbia.edu
uucp: ...!rutgers!columbia!dupuy



More information about the Comp.unix.wizards mailing list