stevesu@copper.UUCP (04/28/87)
Here's an interesting question: what is the correct behavior of dup2 when both arguments are the same? It appears to be a no-op (on 4.2bsd, at least), but it's hardly a good idea to depend on accidental, undocumented behavior. In fact, a strict interpretation of the man page ("If [the second] descriptor is already in use, the descriptor is first deallocated as if a _c_l_o_s_e(2) call had been done first") would imply that dup2(fd, fd); should close fd before attempting to dup it, resulting in an error and the loss of the file descriptor. The question arises because of some code I have that sets up a socket pair, forks, connects one end of the socket to fd's 0, 1, and 2, and then exec's something. I had (probably in a hurry, since usually I know better) written close(sv[1]); close(0); close(1); close(2); dup(sv[0]); dup(sv[0]); dup(sv[0]); close(sv[0]); (the two fd's returned by socketpair() were in the sv[] array.) This code fails if it is invoked with 0, 1, or 2 already closed, because then the low end of the socket ends up on 0, 1, or 2, and gets closed before it can be dup'ed. I changed the code to if(sv[0] != 0) dup2(sv[0], 0); if(sv[0] != 1) dup2(sv[0], 1); if(sv[0] != 2) dup2(sv[0], 2); if(sv[0] > 2) close(sv[0]); but I wondered if the first three if's were strictly necessary. (I'll definitely leave them in, even though it might work without them. By Murphy's law, since a version of Unix somewhere could implement dup2(fd, fd) as closing fd, one will.) Let me add a word of advice: be very careful when writing code that tries to redefine fd's 0, 1, and/or 2. It's extremely easy to end up with code that fails mysteriously when, for instance, open returns 0. It's my belief that the opens of /dev/null that daemon programs do, which have been discussed on this newsgroup, are there in part to protect programs that have these dependencies. (In fact, the 4.x cpp has this property, and you can break it by using make -f -, which inadvertently closes fd 0.) Steve Summit stevesu@copper.tek.com
mouse@mcgill-vision.UUCP (05/06/87)
In article <1004@copper.TEK.COM>, stevesu@copper.TEK.COM (Steve Summit) writes: > [what does dup2 do with two identical arguments? Question arises > from something like] > close(sv[1]); > close(0); > close(1); > close(2); > dup(sv[0]); > dup(sv[0]); > dup(sv[0]); > close(sv[0]); > This code fails if it is invoked with 0, 1, or 2 already closed, > I changed the code to > if(sv[0] != 0) > dup2(sv[0], 0); > if(sv[0] != 1) > dup2(sv[0], 1); > if(sv[0] != 2) > dup2(sv[0], 2); > if(sv[0] > 2) > close(sv[0]); > but I wondered if the first three if's were strictly necessary. Well, I would suggest you write it as if (sv[0] != fileno(stdin)) { dup2(sv[0],fileno(stdin)); close(sv[0]); } dup2(fileno(stdin),fileno(stdout)); dup2(fileno(stdin),fileno(stderr)); [this line to patch around stupid counterproductive 50% rule] [this line to patch around stupid counterproductive 50% rule] der Mouse (mouse@mcgill-vision.uucp)