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 53void setup(void); 54void cleanup(void); 55 56char *TCID = "dup203"; 57int TST_TOTAL = 1; 58 59int 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 */ 192void 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 */ 206void cleanup(void) 207{ 208 tst_rmdir(); 209} 210