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