1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * dup203.c
23 *
24 * DESCRIPTION
25 * Testcase to check the basic functionality of dup2().
26 *
27 * ALGORITHM
28 * 1. Attempt to dup2() on an open file descriptor.
29 * 2. Attempt to dup2() on a close file descriptor.
30 *
31 * USAGE: <for command-line>
32 * dup203 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
33 * where, -c n : Run n copies concurrently.
34 * -f : Turn off functionality Testing.
35 * -i n : Execute test n times.
36 * -I x : Execute test for x seconds.
37 * -P x : Pause for x seconds between iterations.
38 * -t : Turn on syscall timing.
39 *
40 * HISTORY
41 * 07/2001 Ported by Wayne Boyer
42 *
43 * RESTRICTIONS
44 * NONE
45 */
46
47 #include <fcntl.h>
48 #include <sys/param.h>
49 #include <errno.h>
50 #include <string.h>
51 #include "test.h"
52
53 void setup(void);
54 void cleanup(void);
55
56 char *TCID = "dup203";
57 int TST_TOTAL = 1;
58
main(int ac,char ** av)59 int main(int ac, char **av)
60 {
61 int fd0, fd1, fd2, rval;
62 char filename0[40], filename1[40];
63 char buf[40];
64
65 int lc;
66
67 tst_parse_opts(ac, av, NULL, NULL);
68
69 setup();
70
71 for (lc = 0; TEST_LOOPING(lc); lc++) {
72
73 tst_count = 0;
74 //block1:
75 tst_resm(TINFO, "Enter block 1");
76 tst_resm(TINFO, "Test duping over an open fd");
77
78 sprintf(filename0, "dup202.file0.%d\n", getpid());
79 sprintf(filename1, "dup202.file1.%d\n", getpid());
80 unlink(filename0);
81 unlink(filename1);
82
83 if ((fd0 = creat(filename0, 0666)) == -1)
84 tst_brkm(TBROK, cleanup, "cannot create first file");
85 if (write(fd0, filename0, strlen(filename0)) == -1)
86 tst_brkm(TBROK, cleanup, "filename0: write(2) failed");
87
88 if ((fd1 = creat(filename1, 0666)) == -1)
89 tst_brkm(TBROK, cleanup, "Cannot create second file");
90 if (write(fd1, filename1, strlen(filename1)) == -1)
91 tst_brkm(TBROK, cleanup, "filename1: write(2) failed");
92
93 if (close(fd0) == -1)
94 tst_brkm(TBROK, cleanup, "close(2) fd0 failed");
95 if ((fd0 = open(filename0, O_RDONLY)) == -1)
96 tst_brkm(TBROK, cleanup, "open(2) on filename0 failed");
97
98 if (close(fd1) == -1)
99 tst_brkm(TBROK, cleanup, "close(2) fd1 failed");
100 if ((fd1 = open(filename1, O_RDONLY)) == -1)
101 tst_brkm(TBROK, cleanup, "open(2) on filename1 failed");
102
103 TEST(dup2(fd0, fd1));
104
105 if ((fd2 = TEST_RETURN) == -1) {
106 tst_resm(TFAIL, "call failed unexpectedly");
107 } else {
108 if (fd1 != fd2) {
109 tst_resm(TFAIL, "file descriptors don't match");
110 break;
111 }
112
113 memset(buf, 0, sizeof(buf));
114 if (read(fd2, buf, sizeof(buf)) == -1)
115 tst_brkm(TBROK, cleanup, "read(2) failed");
116 if (strcmp(buf, filename0) != 0)
117 tst_resm(TFAIL, "read from file got bad data");
118 tst_resm(TPASS, "dup2 test 1 functionality is correct");
119 }
120
121 close(fd0);
122 close(fd1);
123 close(fd2);
124 unlink(filename0);
125 unlink(filename1);
126
127 tst_resm(TINFO, "Exit block 1");
128
129 //block2:
130 tst_resm(TINFO, "Enter block 2");
131 tst_resm(TINFO, "Test close on exec flag");
132
133 sprintf(filename0, "dup02.%d\n", getpid());
134 unlink(filename0);
135
136 if ((fd0 = creat(filename0, 0666)) == -1) {
137 tst_brkm(TBROK, cleanup, "Cannot create first file");
138 }
139 if (fcntl(fd0, F_SETFD, 1) == -1) {
140 tst_brkm(TBROK, cleanup, "setting close on exec flag "
141 "on fd0 failed");
142 }
143
144 if ((fd2 = creat(filename1, 0666)) == -1) {
145 tst_brkm(TBROK, cleanup, "Cannot create second file");
146 }
147
148 if (close(fd2) == -1) {
149 tst_brkm(TBROK, cleanup, "close(2) fd_closed failed");
150 }
151
152 TEST(dup2(fd0, fd2));
153
154 if ((fd1 = TEST_RETURN) == -1) {
155 tst_resm(TFAIL, "call failed unexpectedly");
156 } else {
157 if (fd1 != fd2) {
158 tst_resm(TFAIL, "bad dup2 descriptor %d", fd1);
159 break;
160 }
161
162 if ((rval = fcntl(fd1, F_GETFD, 0)) != 0) {
163 tst_resm(TBROK | TERRNO,
164 "fcntl F_GETFD on fd1 failed; expected a "
165 "return value of 0x0, got %#x", rval);
166 break;
167 }
168 if ((rval = (fcntl(fd0, F_GETFL, 0) & O_ACCMODE)) !=
169 O_WRONLY) {
170 tst_resm(TFAIL, "fctnl F_GETFL bad rval on fd0 "
171 "Expected %#x got %#x", O_WRONLY,
172 rval);
173 }
174 tst_resm(TPASS, "dup2 test 2 functionality is correct");
175 }
176
177 close(fd0);
178 close(fd1);
179
180 unlink(filename0);
181 unlink(filename1);
182 tst_resm(TINFO, "Exit block 2");
183 }
184
185 cleanup();
186 tst_exit();
187 }
188
189 /*
190 * setup() - performs all ONE TIME setup for this test.
191 */
setup(void)192 void setup(void)
193 {
194
195 tst_sig(NOFORK, DEF_HANDLER, cleanup);
196
197 TEST_PAUSE;
198
199 tst_tmpdir();
200 }
201
202 /*
203 * cleanup() - performs all ONE TIME cleanup for this test at
204 * completion or premature exit.
205 */
cleanup(void)206 void cleanup(void)
207 {
208 tst_rmdir();
209 }
210