1*3cedbec3SEnji Cooper /* 2*3cedbec3SEnji Cooper * $OpenBSD: dup2test.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $ 3*3cedbec3SEnji Cooper * $OpenBSD: dup2_self.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $ 4*3cedbec3SEnji Cooper * $OpenBSD: fcntl_dup.c,v 1.2 2003/07/31 21:48:08 deraadt Exp $ 5*3cedbec3SEnji Cooper * 6*3cedbec3SEnji Cooper * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain. 7*3cedbec3SEnji Cooper * 8*3cedbec3SEnji Cooper * $FreeBSD$ 9*3cedbec3SEnji Cooper */ 10*3cedbec3SEnji Cooper 11*3cedbec3SEnji Cooper /* 12*3cedbec3SEnji Cooper * Test #1: check if dup(2) works. 13*3cedbec3SEnji Cooper * Test #2: check if dup2(2) works. 14*3cedbec3SEnji Cooper * Test #3: check if dup2(2) returned a fd we asked for. 15*3cedbec3SEnji Cooper * Test #4: check if dup2(2) cleared close-on-exec flag for duped fd. 16*3cedbec3SEnji Cooper * Test #5: check if dup2(2) allows to dup fd to itself. 17*3cedbec3SEnji Cooper * Test #6: check if dup2(2) returned a fd we asked for. 18*3cedbec3SEnji Cooper * Test #7: check if dup2(2) did not clear close-on-exec flag for duped fd. 19*3cedbec3SEnji Cooper * Test #8: check if fcntl(F_DUPFD) works. 20*3cedbec3SEnji Cooper * Test #9: check if fcntl(F_DUPFD) cleared close-on-exec flag for duped fd. 21*3cedbec3SEnji Cooper * Test #10: check if dup2() to a fd > current maximum number of open files 22*3cedbec3SEnji Cooper * limit work. 23*3cedbec3SEnji Cooper * Test #11: check if fcntl(F_DUP2FD) works. 24*3cedbec3SEnji Cooper * Test #12: check if fcntl(F_DUP2FD) returned a fd we asked for. 25*3cedbec3SEnji Cooper * Test #13: check if fcntl(F_DUP2FD) cleared close-on-exec flag for duped fd. 26*3cedbec3SEnji Cooper * Test #14: check if fcntl(F_DUP2FD) allows to dup fd to itself. 27*3cedbec3SEnji Cooper * Test #15: check if fcntl(F_DUP2FD) returned a fd we asked for. 28*3cedbec3SEnji Cooper * Test #16: check if fcntl(F_DUP2FD) did not clear close-on-exec flag for 29*3cedbec3SEnji Cooper * duped fd. 30*3cedbec3SEnji Cooper * Test #17: check if fcntl(F_DUP2FD) to a fd > current maximum number of open 31*3cedbec3SEnji Cooper * files limit work. 32*3cedbec3SEnji Cooper * Test #18: check if fcntl(F_DUPFD_CLOEXEC) works. 33*3cedbec3SEnji Cooper * Test #19: check if fcntl(F_DUPFD_CLOEXEC) set close-on-exec flag for duped 34*3cedbec3SEnji Cooper * fd. 35*3cedbec3SEnji Cooper * Test #20: check if fcntl(F_DUP2FD_CLOEXEC) works. 36*3cedbec3SEnji Cooper * Test #21: check if fcntl(F_DUP2FD_CLOEXEC) returned a fd we asked for. 37*3cedbec3SEnji Cooper * Test #22: check if fcntl(F_DUP2FD_CLOEXEC) set close-on-exec flag for duped 38*3cedbec3SEnji Cooper * fd. 39*3cedbec3SEnji Cooper * Test #23: check if fcntl(F_DUP2FD_CLOEXEC) to a fd > current maximum number 40*3cedbec3SEnji Cooper * of open files limit work. 41*3cedbec3SEnji Cooper * Test #24: check if dup3(O_CLOEXEC) works. 42*3cedbec3SEnji Cooper * Test #25: check if dup3(O_CLOEXEC) returned a fd we asked for. 43*3cedbec3SEnji Cooper * Test #26: check if dup3(O_CLOEXEC) set close-on-exec flag for duped fd. 44*3cedbec3SEnji Cooper * Test #27: check if dup3(0) works. 45*3cedbec3SEnji Cooper * Test #28: check if dup3(0) returned a fd we asked for. 46*3cedbec3SEnji Cooper * Test #29: check if dup3(0) cleared close-on-exec flag for duped fd. 47*3cedbec3SEnji Cooper * Test #30: check if dup3(O_CLOEXEC) fails if oldfd == newfd. 48*3cedbec3SEnji Cooper * Test #31: check if dup3(0) fails if oldfd == newfd. 49*3cedbec3SEnji Cooper * Test #32: check if dup3(O_CLOEXEC) to a fd > current maximum number of 50*3cedbec3SEnji Cooper * open files limit work. 51*3cedbec3SEnji Cooper */ 52*3cedbec3SEnji Cooper 53*3cedbec3SEnji Cooper #include <sys/types.h> 54*3cedbec3SEnji Cooper #include <sys/time.h> 55*3cedbec3SEnji Cooper #include <sys/resource.h> 56*3cedbec3SEnji Cooper 57*3cedbec3SEnji Cooper #include <err.h> 58*3cedbec3SEnji Cooper #include <fcntl.h> 59*3cedbec3SEnji Cooper #include <stdio.h> 60*3cedbec3SEnji Cooper #include <stdlib.h> 61*3cedbec3SEnji Cooper #include <unistd.h> 62*3cedbec3SEnji Cooper 63*3cedbec3SEnji Cooper static int getafile(void); 64*3cedbec3SEnji Cooper 65*3cedbec3SEnji Cooper static int 66*3cedbec3SEnji Cooper getafile(void) 67*3cedbec3SEnji Cooper { 68*3cedbec3SEnji Cooper int fd; 69*3cedbec3SEnji Cooper 70*3cedbec3SEnji Cooper char temp[] = "/tmp/dup2XXXXXXXXX"; 71*3cedbec3SEnji Cooper if ((fd = mkstemp(temp)) < 0) 72*3cedbec3SEnji Cooper err(1, "mkstemp"); 73*3cedbec3SEnji Cooper remove(temp); 74*3cedbec3SEnji Cooper if (ftruncate(fd, 1024) != 0) 75*3cedbec3SEnji Cooper err(1, "ftruncate"); 76*3cedbec3SEnji Cooper return (fd); 77*3cedbec3SEnji Cooper } 78*3cedbec3SEnji Cooper 79*3cedbec3SEnji Cooper int 80*3cedbec3SEnji Cooper main(int __unused argc, char __unused *argv[]) 81*3cedbec3SEnji Cooper { 82*3cedbec3SEnji Cooper struct rlimit rlp; 83*3cedbec3SEnji Cooper int orgfd, fd1, fd2, test = 0; 84*3cedbec3SEnji Cooper 85*3cedbec3SEnji Cooper orgfd = getafile(); 86*3cedbec3SEnji Cooper 87*3cedbec3SEnji Cooper printf("1..32\n"); 88*3cedbec3SEnji Cooper 89*3cedbec3SEnji Cooper /* If dup(2) ever work? */ 90*3cedbec3SEnji Cooper if ((fd1 = dup(orgfd)) < 0) 91*3cedbec3SEnji Cooper err(1, "dup"); 92*3cedbec3SEnji Cooper printf("ok %d - dup(2) works\n", ++test); 93*3cedbec3SEnji Cooper 94*3cedbec3SEnji Cooper /* Set close-on-exec */ 95*3cedbec3SEnji Cooper if (fcntl(fd1, F_SETFD, 1) != 0) 96*3cedbec3SEnji Cooper err(1, "fcntl(F_SETFD)"); 97*3cedbec3SEnji Cooper 98*3cedbec3SEnji Cooper /* If dup2(2) ever work? */ 99*3cedbec3SEnji Cooper if ((fd2 = dup2(fd1, fd1 + 1)) < 0) 100*3cedbec3SEnji Cooper err(1, "dup2"); 101*3cedbec3SEnji Cooper printf("ok %d - dup2(2) works\n", ++test); 102*3cedbec3SEnji Cooper 103*3cedbec3SEnji Cooper /* Do we get the right fd? */ 104*3cedbec3SEnji Cooper ++test; 105*3cedbec3SEnji Cooper if (fd2 != fd1 + 1) 106*3cedbec3SEnji Cooper printf("no ok %d - dup2(2) didn't give us the right fd\n", 107*3cedbec3SEnji Cooper test); 108*3cedbec3SEnji Cooper else 109*3cedbec3SEnji Cooper printf("ok %d - dup2(2) returned a correct fd\n", test); 110*3cedbec3SEnji Cooper 111*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 112*3cedbec3SEnji Cooper ++test; 113*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != 0) 114*3cedbec3SEnji Cooper printf("not ok %d - dup2(2) didn't clear close-on-exec\n", 115*3cedbec3SEnji Cooper test); 116*3cedbec3SEnji Cooper else 117*3cedbec3SEnji Cooper printf("ok %d - dup2(2) cleared close-on-exec\n", test); 118*3cedbec3SEnji Cooper 119*3cedbec3SEnji Cooper /* 120*3cedbec3SEnji Cooper * Dup to itself. 121*3cedbec3SEnji Cooper * 122*3cedbec3SEnji Cooper * We're testing a small tweak in dup2 semantics. 123*3cedbec3SEnji Cooper * Normally dup and dup2 will clear the close-on-exec 124*3cedbec3SEnji Cooper * flag on the new fd (which appears to be an implementation 125*3cedbec3SEnji Cooper * mistake from start and not some planned behavior). 126*3cedbec3SEnji Cooper * In today's implementations of dup and dup2 we have to make 127*3cedbec3SEnji Cooper * an effort to really clear that flag. But all tested 128*3cedbec3SEnji Cooper * implementations of dup2 have another tweak. If we 129*3cedbec3SEnji Cooper * dup2(old, new) when old == new, the syscall short-circuits 130*3cedbec3SEnji Cooper * and returns early (because there is no need to do all the 131*3cedbec3SEnji Cooper * work (and there is a risk for serious mistakes)). 132*3cedbec3SEnji Cooper * So although the docs say that dup2 should "take 'old', 133*3cedbec3SEnji Cooper * close 'new' perform a dup(2) of 'old' into 'new'" 134*3cedbec3SEnji Cooper * the docs are not really followed because close-on-exec 135*3cedbec3SEnji Cooper * is not cleared on 'new'. 136*3cedbec3SEnji Cooper * 137*3cedbec3SEnji Cooper * Since everyone has this bug, we pretend that this is 138*3cedbec3SEnji Cooper * the way it is supposed to be and test here that it really 139*3cedbec3SEnji Cooper * works that way. 140*3cedbec3SEnji Cooper * 141*3cedbec3SEnji Cooper * This is a fine example on where two separate implementation 142*3cedbec3SEnji Cooper * fuckups take out each other and make the end-result the way 143*3cedbec3SEnji Cooper * it was meant to be. 144*3cedbec3SEnji Cooper */ 145*3cedbec3SEnji Cooper if ((fd2 = dup2(fd1, fd1)) < 0) 146*3cedbec3SEnji Cooper err(1, "dup2"); 147*3cedbec3SEnji Cooper printf("ok %d - dup2(2) to itself works\n", ++test); 148*3cedbec3SEnji Cooper 149*3cedbec3SEnji Cooper /* Do we get the right fd? */ 150*3cedbec3SEnji Cooper ++test; 151*3cedbec3SEnji Cooper if (fd2 != fd1) 152*3cedbec3SEnji Cooper printf("not ok %d - dup2(2) didn't give us the right fd\n", 153*3cedbec3SEnji Cooper test); 154*3cedbec3SEnji Cooper else 155*3cedbec3SEnji Cooper printf("ok %d - dup2(2) to itself returned a correct fd\n", 156*3cedbec3SEnji Cooper test); 157*3cedbec3SEnji Cooper 158*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 159*3cedbec3SEnji Cooper ++test; 160*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) == 0) 161*3cedbec3SEnji Cooper printf("not ok %d - dup2(2) cleared close-on-exec\n", test); 162*3cedbec3SEnji Cooper else 163*3cedbec3SEnji Cooper printf("ok %d - dup2(2) didn't clear close-on-exec\n", test); 164*3cedbec3SEnji Cooper 165*3cedbec3SEnji Cooper /* Does fcntl(F_DUPFD) work? */ 166*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUPFD, 10)) < 0) 167*3cedbec3SEnji Cooper err(1, "fcntl(F_DUPFD)"); 168*3cedbec3SEnji Cooper if (fd2 < 10) 169*3cedbec3SEnji Cooper printf("not ok %d - fcntl(F_DUPFD) returned wrong fd %d\n", 170*3cedbec3SEnji Cooper ++test, fd2); 171*3cedbec3SEnji Cooper else 172*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUPFD) works\n", ++test); 173*3cedbec3SEnji Cooper 174*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 175*3cedbec3SEnji Cooper ++test; 176*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != 0) 177*3cedbec3SEnji Cooper printf( 178*3cedbec3SEnji Cooper "not ok %d - fcntl(F_DUPFD) didn't clear close-on-exec\n", 179*3cedbec3SEnji Cooper test); 180*3cedbec3SEnji Cooper else 181*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUPFD) cleared close-on-exec\n", test); 182*3cedbec3SEnji Cooper 183*3cedbec3SEnji Cooper ++test; 184*3cedbec3SEnji Cooper if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) 185*3cedbec3SEnji Cooper err(1, "getrlimit"); 186*3cedbec3SEnji Cooper if ((fd2 = dup2(fd1, rlp.rlim_cur + 1)) >= 0) 187*3cedbec3SEnji Cooper printf("not ok %d - dup2(2) bypassed NOFILE limit\n", test); 188*3cedbec3SEnji Cooper else 189*3cedbec3SEnji Cooper printf("ok %d - dup2(2) didn't bypass NOFILE limit\n", test); 190*3cedbec3SEnji Cooper 191*3cedbec3SEnji Cooper /* If fcntl(F_DUP2FD) ever work? */ 192*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUP2FD, fd1 + 1)) < 0) 193*3cedbec3SEnji Cooper err(1, "fcntl(F_DUP2FD)"); 194*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) works\n", ++test); 195*3cedbec3SEnji Cooper 196*3cedbec3SEnji Cooper /* Do we get the right fd? */ 197*3cedbec3SEnji Cooper ++test; 198*3cedbec3SEnji Cooper if (fd2 != fd1 + 1) 199*3cedbec3SEnji Cooper printf( 200*3cedbec3SEnji Cooper "no ok %d - fcntl(F_DUP2FD) didn't give us the right fd\n", 201*3cedbec3SEnji Cooper test); 202*3cedbec3SEnji Cooper else 203*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) returned a correct fd\n", 204*3cedbec3SEnji Cooper test); 205*3cedbec3SEnji Cooper 206*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 207*3cedbec3SEnji Cooper ++test; 208*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != 0) 209*3cedbec3SEnji Cooper printf( 210*3cedbec3SEnji Cooper "not ok %d - fcntl(F_DUP2FD) didn't clear close-on-exec\n", 211*3cedbec3SEnji Cooper test); 212*3cedbec3SEnji Cooper else 213*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) cleared close-on-exec\n", 214*3cedbec3SEnji Cooper test); 215*3cedbec3SEnji Cooper 216*3cedbec3SEnji Cooper /* Dup to itself */ 217*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUP2FD, fd1)) < 0) 218*3cedbec3SEnji Cooper err(1, "fcntl(F_DUP2FD)"); 219*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) to itself works\n", ++test); 220*3cedbec3SEnji Cooper 221*3cedbec3SEnji Cooper /* Do we get the right fd? */ 222*3cedbec3SEnji Cooper ++test; 223*3cedbec3SEnji Cooper if (fd2 != fd1) 224*3cedbec3SEnji Cooper printf( 225*3cedbec3SEnji Cooper "not ok %d - fcntl(F_DUP2FD) didn't give us the right fd\n", 226*3cedbec3SEnji Cooper test); 227*3cedbec3SEnji Cooper else 228*3cedbec3SEnji Cooper printf( 229*3cedbec3SEnji Cooper "ok %d - fcntl(F_DUP2FD) to itself returned a correct fd\n", 230*3cedbec3SEnji Cooper test); 231*3cedbec3SEnji Cooper 232*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 233*3cedbec3SEnji Cooper ++test; 234*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) == 0) 235*3cedbec3SEnji Cooper printf("not ok %d - fcntl(F_DUP2FD) cleared close-on-exec\n", 236*3cedbec3SEnji Cooper test); 237*3cedbec3SEnji Cooper else 238*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) didn't clear close-on-exec\n", 239*3cedbec3SEnji Cooper test); 240*3cedbec3SEnji Cooper 241*3cedbec3SEnji Cooper ++test; 242*3cedbec3SEnji Cooper if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) 243*3cedbec3SEnji Cooper err(1, "getrlimit"); 244*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUP2FD, rlp.rlim_cur + 1)) >= 0) 245*3cedbec3SEnji Cooper printf("not ok %d - fcntl(F_DUP2FD) bypassed NOFILE limit\n", 246*3cedbec3SEnji Cooper test); 247*3cedbec3SEnji Cooper else 248*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD) didn't bypass NOFILE limit\n", 249*3cedbec3SEnji Cooper test); 250*3cedbec3SEnji Cooper 251*3cedbec3SEnji Cooper /* Does fcntl(F_DUPFD_CLOEXEC) work? */ 252*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUPFD_CLOEXEC, 10)) < 0) 253*3cedbec3SEnji Cooper err(1, "fcntl(F_DUPFD_CLOEXEC)"); 254*3cedbec3SEnji Cooper if (fd2 < 10) 255*3cedbec3SEnji Cooper printf("not ok %d - fcntl(F_DUPFD_CLOEXEC) returned wrong fd %d\n", 256*3cedbec3SEnji Cooper ++test, fd2); 257*3cedbec3SEnji Cooper else 258*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUPFD_CLOEXEC) works\n", ++test); 259*3cedbec3SEnji Cooper 260*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 261*3cedbec3SEnji Cooper ++test; 262*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != 1) 263*3cedbec3SEnji Cooper printf( 264*3cedbec3SEnji Cooper "not ok %d - fcntl(F_DUPFD_CLOEXEC) didn't set close-on-exec\n", 265*3cedbec3SEnji Cooper test); 266*3cedbec3SEnji Cooper else 267*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUPFD_CLOEXEC) set close-on-exec\n", 268*3cedbec3SEnji Cooper test); 269*3cedbec3SEnji Cooper 270*3cedbec3SEnji Cooper /* If fcntl(F_DUP2FD_CLOEXEC) ever work? */ 271*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, fd1 + 1)) < 0) 272*3cedbec3SEnji Cooper err(1, "fcntl(F_DUP2FD_CLOEXEC)"); 273*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) works\n", ++test); 274*3cedbec3SEnji Cooper 275*3cedbec3SEnji Cooper /* Do we get the right fd? */ 276*3cedbec3SEnji Cooper ++test; 277*3cedbec3SEnji Cooper if (fd2 != fd1 + 1) 278*3cedbec3SEnji Cooper printf( 279*3cedbec3SEnji Cooper "no ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't give us the right fd\n", 280*3cedbec3SEnji Cooper test); 281*3cedbec3SEnji Cooper else 282*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) returned a correct fd\n", 283*3cedbec3SEnji Cooper test); 284*3cedbec3SEnji Cooper 285*3cedbec3SEnji Cooper /* Was close-on-exec set? */ 286*3cedbec3SEnji Cooper ++test; 287*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != FD_CLOEXEC) 288*3cedbec3SEnji Cooper printf( 289*3cedbec3SEnji Cooper "not ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't set close-on-exec\n", 290*3cedbec3SEnji Cooper test); 291*3cedbec3SEnji Cooper else 292*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) set close-on-exec\n", 293*3cedbec3SEnji Cooper test); 294*3cedbec3SEnji Cooper 295*3cedbec3SEnji Cooper /* 296*3cedbec3SEnji Cooper * It is unclear what F_DUP2FD_CLOEXEC should do when duplicating a 297*3cedbec3SEnji Cooper * file descriptor onto itself. 298*3cedbec3SEnji Cooper */ 299*3cedbec3SEnji Cooper 300*3cedbec3SEnji Cooper ++test; 301*3cedbec3SEnji Cooper if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) 302*3cedbec3SEnji Cooper err(1, "getrlimit"); 303*3cedbec3SEnji Cooper if ((fd2 = fcntl(fd1, F_DUP2FD_CLOEXEC, rlp.rlim_cur + 1)) >= 0) 304*3cedbec3SEnji Cooper printf("not ok %d - fcntl(F_DUP2FD_CLOEXEC) bypassed NOFILE limit\n", 305*3cedbec3SEnji Cooper test); 306*3cedbec3SEnji Cooper else 307*3cedbec3SEnji Cooper printf("ok %d - fcntl(F_DUP2FD_CLOEXEC) didn't bypass NOFILE limit\n", 308*3cedbec3SEnji Cooper test); 309*3cedbec3SEnji Cooper 310*3cedbec3SEnji Cooper /* Does dup3(O_CLOEXEC) ever work? */ 311*3cedbec3SEnji Cooper if ((fd2 = dup3(fd1, fd1 + 1, O_CLOEXEC)) < 0) 312*3cedbec3SEnji Cooper err(1, "dup3(O_CLOEXEC)"); 313*3cedbec3SEnji Cooper printf("ok %d - dup3(O_CLOEXEC) works\n", ++test); 314*3cedbec3SEnji Cooper 315*3cedbec3SEnji Cooper /* Do we get the right fd? */ 316*3cedbec3SEnji Cooper ++test; 317*3cedbec3SEnji Cooper if (fd2 != fd1 + 1) 318*3cedbec3SEnji Cooper printf( 319*3cedbec3SEnji Cooper "no ok %d - dup3(O_CLOEXEC) didn't give us the right fd\n", 320*3cedbec3SEnji Cooper test); 321*3cedbec3SEnji Cooper else 322*3cedbec3SEnji Cooper printf("ok %d - dup3(O_CLOEXEC) returned a correct fd\n", 323*3cedbec3SEnji Cooper test); 324*3cedbec3SEnji Cooper 325*3cedbec3SEnji Cooper /* Was close-on-exec set? */ 326*3cedbec3SEnji Cooper ++test; 327*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != FD_CLOEXEC) 328*3cedbec3SEnji Cooper printf( 329*3cedbec3SEnji Cooper "not ok %d - dup3(O_CLOEXEC) didn't set close-on-exec\n", 330*3cedbec3SEnji Cooper test); 331*3cedbec3SEnji Cooper else 332*3cedbec3SEnji Cooper printf("ok %d - dup3(O_CLOEXEC) set close-on-exec\n", 333*3cedbec3SEnji Cooper test); 334*3cedbec3SEnji Cooper 335*3cedbec3SEnji Cooper /* Does dup3(0) ever work? */ 336*3cedbec3SEnji Cooper if ((fd2 = dup3(fd1, fd1 + 1, 0)) < 0) 337*3cedbec3SEnji Cooper err(1, "dup3(0)"); 338*3cedbec3SEnji Cooper printf("ok %d - dup3(0) works\n", ++test); 339*3cedbec3SEnji Cooper 340*3cedbec3SEnji Cooper /* Do we get the right fd? */ 341*3cedbec3SEnji Cooper ++test; 342*3cedbec3SEnji Cooper if (fd2 != fd1 + 1) 343*3cedbec3SEnji Cooper printf( 344*3cedbec3SEnji Cooper "no ok %d - dup3(0) didn't give us the right fd\n", 345*3cedbec3SEnji Cooper test); 346*3cedbec3SEnji Cooper else 347*3cedbec3SEnji Cooper printf("ok %d - dup3(0) returned a correct fd\n", 348*3cedbec3SEnji Cooper test); 349*3cedbec3SEnji Cooper 350*3cedbec3SEnji Cooper /* Was close-on-exec cleared? */ 351*3cedbec3SEnji Cooper ++test; 352*3cedbec3SEnji Cooper if (fcntl(fd2, F_GETFD) != 0) 353*3cedbec3SEnji Cooper printf( 354*3cedbec3SEnji Cooper "not ok %d - dup3(0) didn't clear close-on-exec\n", 355*3cedbec3SEnji Cooper test); 356*3cedbec3SEnji Cooper else 357*3cedbec3SEnji Cooper printf("ok %d - dup3(0) cleared close-on-exec\n", 358*3cedbec3SEnji Cooper test); 359*3cedbec3SEnji Cooper 360*3cedbec3SEnji Cooper /* dup3() does not allow duplicating to the same fd */ 361*3cedbec3SEnji Cooper ++test; 362*3cedbec3SEnji Cooper if (dup3(fd1, fd1, O_CLOEXEC) != -1) 363*3cedbec3SEnji Cooper printf( 364*3cedbec3SEnji Cooper "not ok %d - dup3(fd1, fd1, O_CLOEXEC) succeeded\n", test); 365*3cedbec3SEnji Cooper else 366*3cedbec3SEnji Cooper printf("ok %d - dup3(fd1, fd1, O_CLOEXEC) failed\n", test); 367*3cedbec3SEnji Cooper 368*3cedbec3SEnji Cooper ++test; 369*3cedbec3SEnji Cooper if (dup3(fd1, fd1, 0) != -1) 370*3cedbec3SEnji Cooper printf( 371*3cedbec3SEnji Cooper "not ok %d - dup3(fd1, fd1, 0) succeeded\n", test); 372*3cedbec3SEnji Cooper else 373*3cedbec3SEnji Cooper printf("ok %d - dup3(fd1, fd1, 0) failed\n", test); 374*3cedbec3SEnji Cooper 375*3cedbec3SEnji Cooper ++test; 376*3cedbec3SEnji Cooper if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) 377*3cedbec3SEnji Cooper err(1, "getrlimit"); 378*3cedbec3SEnji Cooper if ((fd2 = dup3(fd1, rlp.rlim_cur + 1, O_CLOEXEC)) >= 0) 379*3cedbec3SEnji Cooper printf("not ok %d - dup3(O_CLOEXEC) bypassed NOFILE limit\n", 380*3cedbec3SEnji Cooper test); 381*3cedbec3SEnji Cooper else 382*3cedbec3SEnji Cooper printf("ok %d - dup3(O_CLOEXEC) didn't bypass NOFILE limit\n", 383*3cedbec3SEnji Cooper test); 384*3cedbec3SEnji Cooper 385*3cedbec3SEnji Cooper return (0); 386*3cedbec3SEnji Cooper } 387