1 /******************************************************************************/ 2 /* */ 3 /* Copyright (c) Ulrich Drepper <drepper (at) redhat.com> */ 4 /* Copyright (c) International Business Machines Corp., 2009 */ 5 /* */ 6 /* This program is free software; you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation; either version 2 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* This program is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 14 /* the GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with this program; if not, write to the Free Software */ 18 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 19 /* */ 20 /******************************************************************************/ 21 /******************************************************************************/ 22 /* */ 23 /* File: pipe2_01.c */ 24 /* */ 25 /* Description: This Program tests the new system call introduced in 2.6.27. */ 26 /* Ulrichs comment as in: */ 27 /* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ed8cae8ba01348bfd83333f4648dd807b04d7f08 */ 28 /* says: */ 29 /* This patch introduces the new syscall pipe2 which is like pipe but it also */ 30 /* takes an additional parameter which takes a flag value. This patch */ 31 /* implements the handling of O_CLOEXEC for the flag. I did not add support */ 32 /* for the new syscall for the architectures which have a special sys_pipe */ 33 /* implementation. I think the maintainers of those archs have the chance to */ 34 /* go with the unified implementation but that's up to them. */ 35 /* */ 36 /* The implementation introduces do_pipe_flags. I did that instead of */ 37 /* changing all callers of do_pipe because some of the callers are written in */ 38 /* assembler. I would probably screw up changing the assembly code. To avoid */ 39 /* breaking code do_pipe is now a small wrapper around do_pipe_flags. Once */ 40 /* all callers are changed over to do_pipe_flags the old do_pipe function can */ 41 /* be removed. */ 42 /* The following test must be adjusted for architectures other than x86 and */ 43 /* x86-64 and in case the syscall numbers changed. */ 44 /* */ 45 /* Usage: <for command-line> */ 46 /* pipe2_01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */ 47 /* where, -c n : Run n copies concurrently. */ 48 /* -e : Turn on errno logging. */ 49 /* -i n : Execute test n times. */ 50 /* -I x : Execute test for x seconds. */ 51 /* -P x : Pause for x seconds between iterations. */ 52 /* -t : Turn on syscall timing. */ 53 /* */ 54 /* Total Tests: 1 */ 55 /* */ 56 /* Test Name: pipe2_01 */ 57 /* */ 58 /* Author: Ulrich Drepper <drepper (at) redhat.com> */ 59 /* */ 60 /* History: Created - Jan 13 2009 - Ulrich Drepper <drepper (at) redhat.com> */ 61 /* Ported to LTP */ 62 /* - Jan 13 2009 - Subrata <subrata (at) linux.vnet.ibm.com> */ 63 /******************************************************************************/ 64 #include <fcntl.h> 65 #include <stdio.h> 66 #include <unistd.h> 67 #include <sys/syscall.h> 68 #include <errno.h> 69 70 #include "test.h" 71 #include "lapi/fcntl.h" 72 #include "lapi/syscalls.h" 73 74 char *TCID = "pipe2_01"; 75 int testno; 76 int TST_TOTAL = 1; 77 78 /* Extern Global Functions */ 79 /******************************************************************************/ 80 /* */ 81 /* Function: cleanup */ 82 /* */ 83 /* Description: Performs all one time clean up for this test on successful */ 84 /* completion, premature exit or failure. Closes all temporary */ 85 /* files, removes all temporary directories exits the test with */ 86 /* appropriate return code by calling tst_exit() function. */ 87 /* */ 88 /* Input: None. */ 89 /* */ 90 /* Output: None. */ 91 /* */ 92 /* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ 93 /* On success - Exits calling tst_exit(). With '0' return code. */ 94 /* */ 95 /******************************************************************************/ 96 void cleanup(void) 97 { 98 99 tst_rmdir(); 100 101 } 102 103 /* Local Functions */ 104 /******************************************************************************/ 105 /* */ 106 /* Function: setup */ 107 /* */ 108 /* Description: Performs all one time setup for this test. This function is */ 109 /* typically used to capture signals, create temporary dirs */ 110 /* and temporary files that may be used in the course of this */ 111 /* test. */ 112 /* */ 113 /* Input: None. */ 114 /* */ 115 /* Output: None. */ 116 /* */ 117 /* Return: On failure - Exits by calling cleanup(). */ 118 /* On success - returns 0. */ 119 /* */ 120 /******************************************************************************/ 121 void setup(void) 122 { 123 /* Capture signals if any */ 124 /* Create temporary directories */ 125 TEST_PAUSE; 126 tst_tmpdir(); 127 } 128 129 int main(int argc, char *argv[]) 130 { 131 int fd[2], i, coe; 132 int lc; 133 134 tst_parse_opts(argc, argv, NULL, NULL); 135 if ((tst_kvercmp(2, 6, 27)) < 0) { 136 tst_brkm(TCONF, 137 NULL, 138 "This test can only run on kernels that are 2.6.27 and higher"); 139 } 140 setup(); 141 142 for (lc = 0; TEST_LOOPING(lc); ++lc) { 143 tst_count = 0; 144 for (testno = 0; testno < TST_TOTAL; ++testno) { 145 if (ltp_syscall(__NR_pipe2, fd, 0) != 0) { 146 tst_brkm(TFAIL, cleanup, "pipe2(0) failed"); 147 } 148 for (i = 0; i < 2; ++i) { 149 coe = fcntl(fd[i], F_GETFD); 150 if (coe == -1) { 151 tst_brkm(TBROK, cleanup, 152 "fcntl failed"); 153 } 154 if (coe & FD_CLOEXEC) { 155 tst_brkm(TFAIL, 156 cleanup, "pipe2(0) set close-on-exit for fd[%d]", 157 i); 158 } 159 } 160 close(fd[0]); 161 close(fd[1]); 162 163 if (ltp_syscall(__NR_pipe2, fd, O_CLOEXEC) != 0) { 164 tst_brkm(TFAIL, cleanup, 165 "pipe2(O_CLOEXEC) failed"); 166 } 167 for (i = 0; i < 2; ++i) { 168 coe = fcntl(fd[i], F_GETFD); 169 if (coe == -1) { 170 tst_brkm(TBROK, cleanup, 171 "fcntl failed"); 172 } 173 if ((coe & FD_CLOEXEC) == 0) { 174 tst_brkm(TFAIL, 175 cleanup, "pipe2(O_CLOEXEC) does not set close-on-exit for fd[%d]", 176 i); 177 } 178 } 179 close(fd[0]); 180 close(fd[1]); 181 tst_resm(TPASS, "pipe2(O_CLOEXEC) PASSED"); 182 cleanup(); 183 } 184 } 185 tst_exit(); 186 } 187