1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * 07/2001 Ported by Wayne Boyer 5 */ 6 7/*\ 8 * [Description] 9 * 10 * Testcase to check the basic functionality of dup2(). 11 * 12 * - Attempt to dup2() on an open file descriptor. 13 * - Attempt to dup2() on a close file descriptor. 14 */ 15 16#include <errno.h> 17#include <stdio.h> 18#include <unistd.h> 19#include "tst_test.h" 20#include "tst_safe_macros.h" 21 22static char filename0[40], filename1[40]; 23static int fd0 = -1, fd1 = -1; 24 25static struct tcase { 26 char *desc; 27 int is_close; 28} tcases[] = { 29 {"Test duping over an open fd", 0}, 30 {"Test duping over a close fd", 1}, 31}; 32 33static void run(unsigned int i) 34{ 35 int fd2, rval; 36 char buf[40]; 37 38 struct tcase *tc = tcases + i; 39 40 tst_res(TINFO, "%s", tc->desc); 41 42 fd0 = SAFE_CREAT(filename0, 0666); 43 SAFE_WRITE(SAFE_WRITE_ALL, fd0, filename0, strlen(filename0)); 44 SAFE_CLOSE(fd0); 45 46 fd1 = SAFE_CREAT(filename1, 0666); 47 SAFE_WRITE(SAFE_WRITE_ALL, fd1, filename1, strlen(filename1)); 48 49 fd0 = SAFE_OPEN(filename0, O_RDONLY); 50 SAFE_FCNTL(fd0, F_SETFD, 1); 51 52 if (tc->is_close) { 53 /* SAFE_CLOSE() sets the fd to -1 avoid it here */ 54 rval = fd1; 55 SAFE_CLOSE(rval); 56 } 57 58 TEST(dup2(fd0, fd1)); 59 fd2 = TST_RET; 60 if (TST_RET == -1) { 61 tst_res(TFAIL, "call failed unexpectedly"); 62 goto free; 63 } 64 if (fd1 != fd2) { 65 tst_res(TFAIL, "file descriptors don't match"); 66 goto free; 67 } 68 69 memset(buf, 0, sizeof(buf)); 70 SAFE_READ(0, fd2, buf, sizeof(buf)); 71 if (strcmp(buf, filename0) != 0) 72 tst_res(TFAIL, "read from file got bad data"); 73 else 74 tst_res(TPASS, "test the content of file is correct"); 75 76 rval = SAFE_FCNTL(fd2, F_GETFD); 77 if (rval != 0) 78 tst_res(TFAIL, "the FD_CLOEXEC flag is %#x, expected 0x0", 79 rval); 80 else 81 tst_res(TPASS, "test the FD_CLOEXEC flag is correct"); 82free: 83 SAFE_CLOSE(fd0); 84 SAFE_CLOSE(fd1); 85 SAFE_UNLINK(filename0); 86 SAFE_UNLINK(filename1); 87} 88 89static void setup(void) 90{ 91 int pid; 92 93 pid = getpid(); 94 sprintf(filename0, "dup203.file0.%d\n", pid); 95 sprintf(filename1, "dup203.file1.%d\n", pid); 96} 97 98static void cleanup(void) 99{ 100 close(fd0); 101 close(fd1); 102} 103 104static struct tst_test test = { 105 .setup = setup, 106 .tcnt = ARRAY_SIZE(tcases), 107 .needs_tmpdir = 1, 108 .test = run, 109 .cleanup = cleanup, 110}; 111