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 * dup202.c
23 *
24 * DESCRIPTION
25 * Is the access mode the same for both file descriptors?
26 * 0: read only ? "0444"
27 * 1: write only ? "0222"
28 * 2: read/write ? "0666"
29 *
30 * ALGORITHM
31 * Creat a file with each access mode; dup each file descriptor;
32 * stat each file descriptor and compare modes of each pair
33 *
34 * USAGE: <for command-line>
35 * dup202 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
36 * where, -c n : Run n copies concurrently.
37 * -f : Turn off functionality Testing.
38 * -i n : Execute test n times.
39 * -I x : Execute test for x seconds.
40 * -P x : Pause for x seconds between iterations.
41 * -t : Turn on syscall timing.
42 *
43 * HISTORY
44 * 07/2001 Ported by Wayne Boyer
45 *
46 * RESTRICTIONS
47 * None
48 */
49
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <stdio.h>
55 #include "test.h"
56
57 char *TCID = "dup202";
58 int TST_TOTAL = 3;
59
60 void setup(void);
61 void cleanup(void);
62
63 char testfile[40];
64 int fail;
65 int newfd;
66
67 /* set these to a known index into our local file descriptor table */
68 int duprdo = 10, dupwro = 20, duprdwr = 30;
69
70 struct test_case_t {
71 int *nfd;
72 mode_t mode;
73 } TC[] = {
74 /* The first test creat(es) a file with mode 0444 */
75 {
76 &duprdo, (S_IRUSR | S_IRGRP | S_IROTH)},
77 /* The second test creat(es) a file with mode 0222 */
78 {
79 &dupwro, (S_IWUSR | S_IWGRP | S_IWOTH)},
80 /* The third test creat(es) a file with mode 0666 */
81 {
82 &duprdwr,
83 (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH)}
84 };
85
main(int ac,char ** av)86 int main(int ac, char **av)
87 {
88 int lc;
89 int i, ofd;
90 struct stat oldbuf, newbuf;
91
92 tst_parse_opts(ac, av, NULL, NULL);
93
94 setup();
95
96 for (lc = 0; TEST_LOOPING(lc); lc++) {
97
98 tst_count = 0;
99
100 /* loop through the test cases */
101 for (i = 0; i < TST_TOTAL; i++) {
102
103 if ((ofd = creat(testfile, TC[i].mode)) == -1)
104 tst_brkm(TBROK | TERRNO, cleanup,
105 "creat failed");
106
107 TEST(dup2(ofd, *TC[i].nfd));
108
109 if (TEST_RETURN == -1) {
110 tst_resm(TFAIL | TERRNO,
111 "call failed unexpectedly");
112 continue;
113 }
114
115 /* stat the original file */
116 if (fstat(ofd, &oldbuf) == -1)
117 tst_brkm(TBROK | TERRNO, cleanup,
118 "fstat #1 failed");
119
120 /* stat the duped file */
121 if (fstat(*TC[i].nfd, &newbuf) == -1)
122 tst_brkm(TBROK | TERRNO, cleanup,
123 "fstat #2 failed");
124
125 if (oldbuf.st_mode != newbuf.st_mode)
126 tst_resm(TFAIL, "original and dup "
127 "modes do not match");
128 else
129 tst_resm(TPASS, "fstat shows new and "
130 "old modes are the same");
131
132 /* remove the file so that we can use it again */
133 if (close(*TC[i].nfd) == -1)
134 perror("close failed");
135 if (close(ofd) == -1)
136 perror("close failed");
137 if (unlink(testfile) == -1)
138 perror("unlink failed");
139 }
140 }
141
142 cleanup();
143 tst_exit();
144 }
145
146 /*
147 * setup() - performs all ONE TIME setup for this test.
148 */
setup(void)149 void setup(void)
150 {
151
152 tst_sig(NOFORK, DEF_HANDLER, cleanup);
153
154 TEST_PAUSE;
155
156 tst_tmpdir();
157
158 (void)umask(0);
159
160 sprintf(testfile, "dup202.%d", getpid());
161 }
162
163 /*
164 * cleanup() - performs all ONE TIME cleanup for this test at
165 * completion or premature exit.
166 */
cleanup(void)167 void cleanup(void)
168 {
169 tst_rmdir();
170 }
171