scoutos / prex-0.9.0 / usr / test / dup / dup.c @ 03e9c04a
History | View | Annotate | Download (4.57 KB)
1 |
/*
|
---|---|
2 |
* $OpenBSD: dup2test.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
|
3 |
* $OpenBSD: dup2_self.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
|
4 |
* $OpenBSD: fcntl_dup.c,v 1.2 2003/07/31 21:48:08 deraadt Exp $
|
5 |
*
|
6 |
* Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain.
|
7 |
*
|
8 |
* $FreeBSD: src/tools/regression/file/dup/dup.c,v 1.2.2.1.2.1 2008/11/25 02:59:29 kensmith Exp $
|
9 |
*/
|
10 |
|
11 |
/* Modified for Prex by Kohsuke Ohtani */
|
12 |
|
13 |
/*
|
14 |
* Test #1: check if dup(2) works.
|
15 |
* Test #2: check if dup2(2) works.
|
16 |
* Test #3: check if dup2(2) returned a fd we asked for.
|
17 |
* Test #4: check if dup2(2) cleared close-on-exec flag for duped fd.
|
18 |
* Test #5: check if dup2(2) allows to dup fd to itself.
|
19 |
* Test #6: check if dup2(2) returned a fd we asked for.
|
20 |
* Test #7: check if dup2(2) did not clear close-on-exec flag for duped fd.
|
21 |
* Test #8: check if fcntl(F_DUPFD) works.
|
22 |
* Test #9: check if fcntl(F_DUPFD) cleared close-on-exec flag for duped fd.
|
23 |
* Test #10: check if dup2() to a fd > current maximum number of open files
|
24 |
* limit work.
|
25 |
*/
|
26 |
|
27 |
#include <sys/types.h> |
28 |
#include <sys/time.h> |
29 |
#include <sys/resource.h> |
30 |
|
31 |
#include <err.h> |
32 |
#include <fcntl.h> |
33 |
#include <stdio.h> |
34 |
#include <stdlib.h> |
35 |
#include <unistd.h> |
36 |
|
37 |
static int getafile(void); |
38 |
|
39 |
static int |
40 |
getafile(void)
|
41 |
{ |
42 |
int fd;
|
43 |
|
44 |
char temp[] = "/tmp/dup2XXXXXXXXX"; |
45 |
if ((fd = mkstemp(temp)) < 0) |
46 |
err(1, "mkstemp"); |
47 |
remove(temp); |
48 |
if (ftruncate(fd, 1024) != 0) |
49 |
err(1, "ftruncate"); |
50 |
return (fd);
|
51 |
} |
52 |
|
53 |
int
|
54 |
main(int argc, char *argv[]) |
55 |
{ |
56 |
struct rlimit rlp;
|
57 |
int orgfd, fd1, fd2, test = 0; |
58 |
|
59 |
orgfd = getafile(); |
60 |
|
61 |
printf("1..17\n");
|
62 |
|
63 |
/* If dup(2) ever work? */
|
64 |
if ((fd1 = dup(orgfd)) < 0) |
65 |
err(1, "dup"); |
66 |
printf("ok %d - dup(2) works\n", ++test);
|
67 |
|
68 |
/* Set close-on-exec */
|
69 |
if (fcntl(fd1, F_SETFD, 1) != 0) |
70 |
err(1, "fcntl(F_SETFD)"); |
71 |
|
72 |
/* If dup2(2) ever work? */
|
73 |
if ((fd2 = dup2(fd1, fd1 + 1)) < 0) |
74 |
err(1, "dup2"); |
75 |
printf("ok %d - dup2(2) works\n", ++test);
|
76 |
|
77 |
/* Do we get the right fd? */
|
78 |
++test; |
79 |
if (fd2 != fd1 + 1) |
80 |
printf("no ok %d - dup2(2) didn't give us the right fd\n",
|
81 |
test); |
82 |
else
|
83 |
printf("ok %d - dup2(2) returned a correct fd\n", test);
|
84 |
|
85 |
#if 0
|
86 |
/* Was close-on-exec cleared? */
|
87 |
++test;
|
88 |
if (fcntl(fd2, F_GETFD) != 0)
|
89 |
printf("not ok %d - dup2(2) didn't clear close-on-exec\n",
|
90 |
test);
|
91 |
else
|
92 |
printf("ok %d - dup2(2) cleared close-on-exec\n", test);
|
93 |
#endif
|
94 |
|
95 |
/*
|
96 |
* Dup to itself.
|
97 |
*
|
98 |
* We're testing a small tweak in dup2 semantics.
|
99 |
* Normally dup and dup2 will clear the close-on-exec
|
100 |
* flag on the new fd (which appears to be an implementation
|
101 |
* mistake from start and not some planned behavior).
|
102 |
* In todays implementations of dup and dup2 we have to make
|
103 |
* an effort to really clear that flag. But all tested
|
104 |
* implementations of dup2 have another tweak. If we
|
105 |
* dup2(old, new) when old == new, the syscall short-circuits
|
106 |
* and returns early (because there is no need to do all the
|
107 |
* work (and there is a risk for serious mistakes)).
|
108 |
* So although the docs say that dup2 should "take 'old',
|
109 |
* close 'new' perform a dup(2) of 'old' into 'new'"
|
110 |
* the docs are not really followed because close-on-exec
|
111 |
* is not cleared on 'new'.
|
112 |
*
|
113 |
* Since everyone has this bug, we pretend that this is
|
114 |
* the way it is supposed to be and test here that it really
|
115 |
* works that way.
|
116 |
*
|
117 |
* This is a fine example on where two separate implementation
|
118 |
* fuckups take out each other and make the end-result the way
|
119 |
* it was meant to be.
|
120 |
*/
|
121 |
if ((fd2 = dup2(fd1, fd1)) < 0) |
122 |
err(1, "dup2"); |
123 |
printf("ok %d - dup2(2) to itself works\n", ++test);
|
124 |
|
125 |
/* Do we get the right fd? */
|
126 |
++test; |
127 |
if (fd2 != fd1)
|
128 |
printf("not ok %d - dup2(2) didn't give us the right fd\n",
|
129 |
test); |
130 |
else
|
131 |
printf("ok %d - dup2(2) to itself returned a correct fd\n",
|
132 |
test); |
133 |
|
134 |
#if 0
|
135 |
/* Was close-on-exec cleared? */
|
136 |
++test;
|
137 |
if (fcntl(fd2, F_GETFD) == 0)
|
138 |
printf("not ok %d - dup2(2) cleared close-on-exec\n", test);
|
139 |
else
|
140 |
printf("ok %d - dup2(2) didn't clear close-on-exec\n", test);
|
141 |
#endif
|
142 |
|
143 |
/* Does fcntl(F_DUPFD) work? */
|
144 |
if ((fd2 = fcntl(fd1, F_DUPFD, 0)) < 0) |
145 |
err(1, "fcntl(F_DUPFD)"); |
146 |
printf("ok %d - fcntl(F_DUPFD) works\n", ++test);
|
147 |
|
148 |
#if 0
|
149 |
/* Was close-on-exec cleared? */
|
150 |
++test;
|
151 |
if (fcntl(fd2, F_GETFD) != 0)
|
152 |
printf(
|
153 |
"not ok %d - fcntl(F_DUPFD) didn't clear close-on-exec\n",
|
154 |
test);
|
155 |
else
|
156 |
printf("ok %d - fcntl(F_DUPFD) cleared close-on-exec\n", test);
|
157 |
|
158 |
#endif
|
159 |
++test; |
160 |
if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) |
161 |
err(1, "getrlimit"); |
162 |
if ((fd2 = dup2(fd1, (int)(rlp.rlim_cur + 1))) >= 0) |
163 |
printf("not ok %d - dup2(2) bypassed NOFILE limit\n", test);
|
164 |
else
|
165 |
printf("ok %d - dup2(2) didn't bypass NOFILE limit\n", test);
|
166 |
|
167 |
return (0); |
168 |
} |