Posts Tagged ‘Solaris’
Difference between dup(0) and open(“/dev/fd/0″,…);
By chys on January 14th, 2009I believe APUE (2nd ed.; Sec. 3.16) is not correct.
APUE says fd = open("/dev/fd/0", mode); is equivalent to fd = dup (0);, and mode is completely ignored. It seems this is the case in Solaris, but wrong in Linux. (I don’t have access to other Unices at this moment.)
A test program:
01 #include <unistd.h>
02 #include <fcntl.h>
03
04 int main ()
05 {
06 close (0);
07 printf ("%dn", open ("a.txt", O_RDONLY)); // Should be 0
08 //int f2 = open ("/dev/fd/0", O_WRONLY);
09 int f2 = dup(0);
10 printf ("%dn", f2);
11 write (f2, "Hello worldn", 12);
12 return 0;
13 }
Let’s run the program with an empty a.txt. Certainly the write function in Line 11 is going to fail.
Now, let’s comment out Line 9 and uncomment line 8 and try it again.
First I ran it in Solaris, the write call still failed. The behavior is like what APUE tells us.
Try it again in Linux – It was successful!
It seems that in Linux, /dev/fd/0 is considered by open as nothing but a normal symlink to a.txt. So it returns a completely new descriptor instead of a duplicate of the old.
Let’s try it again with a shell script:
rm -f a.txt touch a.txt exec 0<a.txt exec 3>/dev/fd/0 echo 'Hello world' >&3 cat a.txt
Run it in Linux (with DASH or BASH): Both outputed ‘Hello world’.
Run it in Solaris (with Bourne shell and BASH): Both failed, outputting nothing (Bourne shell) or failing with ‘Bad file number’ (BASH).
Conclusion:
(1) Solaris handles /dev/fd/.. specially, as APUE tells us;
(2) Linux simply consider /dev/fd/0 a symlink to the actual file.
(I’ll try later how Linux handles open("/dev/fd/0",mode) if the descriptor is an anonymous pipe or socket or something else that a normal symlink is unable to link to.
Kernels used in the above tests:
Linux: Linux desktop 2.6.28-gentoo #4 SMP Mon Jan 12 17:39:23 CST 2009 x86_64 Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz GenuineIntel GNU/Linux
Solaris: SunOS caesar 5.8 Generic_117350-51 sun4u sparc SUNW,Ultra-80 Solaris

