dup2

Richard M. Mathews richard at locus.com
Thu Feb 14 09:37:35 AEST 1991


rbj at uunet.UU.NET (Root Boy Jim) writes:
>richard at locus.com (Richard M. Mathews) writes:
>>I have not yet seen a correct version of code for dup2() posted.  The
>>versions posted by Paul Falsted, Doug Gwyn, and Root Boy Jim all fail
>>the following test case because they close "fd2" too soon:

>I suppose it depend on your interpretation.

Well, since we are trying to simulate a V7 system call, I would think
that the V7 code would be the best place to go to see what we should
emulate.  I went to the oldest code I could find without bothering
our tape librarian.  The was a version of the Locus Operating System,
circa 1983, based on BSD4.1.  I doubt that Locus made changes to dup2
way back then.  I don't know if Berkeley might have changed dup2 from
V7.  All references to code and documentation below refer to this
system.

>If you try dup2(-1,fileno(stdout))
>and end up with nowhere to print to, have you not made a copy of your
>input file descriptor? What does the shell do with "cmd >&- 2>&1"?

The above mentioned code returns without touching fd2 if the getf()
fails on fd1.  It certainly makes sense that if you return -1 you should
leave the state of the process unchanged.  By your argument, dup2(-1,fd)
should be equivalent to close(fd) and should return success if the close
succeeds.  This clearly is not the way dup2 is documented (it says, "-1
is returned if the given file descriptor is invalid").

>And what is the "meaning" of dup2(1,1)? Anyone who trys to do this
>probably has a logic error somewhere, regardless of the definition.
>In any case, I am willing to add "if (new == old) return(new);" to my code.

The above mentioned code has a special case to make sure it treats this
as a no-op (though it does validate fd1).

>I also claim that I handled errno properly. It is not necessary
>to preserve the old value of errno if dup2 returns true.

The above mentioned code uses EBADF.  Fcntl uses EINVAL.  You definitely
got that errno wrong.  As for preserving errno on success, it certainly
is true that V7 dup2 did do so, but it isn't clear that you need to.
The manual says in intro(2) that, "Errno is not cleared on successful
calls."  It doesn't promise that errno isn't changed.  I think it is a
nice extra feature to add those few lines of code to preserve errno.

Richard M. Mathews			 Freedom for Lithuania
richard at locus.com				Laisve!
lcc!richard at seas.ucla.edu
...!{uunet|ucla-se|turnkey}!lcc!richard



More information about the Comp.unix.internals mailing list