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