Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/test/dup/dup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getafile
  2. main

   1 /*
   2  * $OpenBSD: dup2test.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
   3  * $OpenBSD: dup2_self.c,v 1.3 2003/07/31 21:48:08 deraadt Exp $
   4  * $OpenBSD: fcntl_dup.c,v 1.2 2003/07/31 21:48:08 deraadt Exp $
   5  *
   6  * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain.
   7  *
   8  * $FreeBSD: src/tools/regression/file/dup/dup.c,v 1.2.2.1.2.1 2008/11/25 02:59:29 kensmith Exp $
   9  */
  10 
  11 /* Modified for Prex by Kohsuke Ohtani */
  12 
  13 /*
  14  * Test #1:  check if dup(2) works.
  15  * Test #2:  check if dup2(2) works.
  16  * Test #3:  check if dup2(2) returned a fd we asked for.
  17  * Test #4:  check if dup2(2) cleared close-on-exec flag for duped fd.
  18  * Test #5:  check if dup2(2) allows to dup fd to itself.
  19  * Test #6:  check if dup2(2) returned a fd we asked for.
  20  * Test #7:  check if dup2(2) did not clear close-on-exec flag for duped fd.
  21  * Test #8:  check if fcntl(F_DUPFD) works.
  22  * Test #9:  check if fcntl(F_DUPFD) cleared close-on-exec flag for duped fd.
  23  * Test #10: check if dup2() to a fd > current maximum number of open files
  24  *           limit work.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/time.h>
  29 #include <sys/resource.h>
  30 
  31 #include <err.h>
  32 #include <fcntl.h>
  33 #include <stdio.h>
  34 #include <stdlib.h>
  35 #include <unistd.h>
  36 
  37 static int      getafile(void);
  38 
  39 static int
  40 getafile(void)
  41 {
  42         int fd;
  43 
  44         char temp[] = "/tmp/dup2XXXXXXXXX";
  45         if ((fd = mkstemp(temp)) < 0)
  46                 err(1, "mkstemp");
  47         remove(temp);
  48         if (ftruncate(fd, 1024) != 0)
  49                 err(1, "ftruncate");
  50         return (fd);
  51 }
  52 
  53 int
  54 main(int argc, char *argv[])
  55 {
  56         struct rlimit rlp;
  57         int orgfd, fd1, fd2, test = 0;
  58 
  59         orgfd = getafile();
  60 
  61         printf("1..17\n");
  62 
  63         /* If dup(2) ever work? */
  64         if ((fd1 = dup(orgfd)) < 0)
  65                 err(1, "dup");
  66         printf("ok %d - dup(2) works\n", ++test);
  67 
  68         /* Set close-on-exec */
  69         if (fcntl(fd1, F_SETFD, 1) != 0)
  70                 err(1, "fcntl(F_SETFD)");
  71 
  72         /* If dup2(2) ever work? */
  73         if ((fd2 = dup2(fd1, fd1 + 1)) < 0)
  74                 err(1, "dup2");
  75         printf("ok %d - dup2(2) works\n", ++test);
  76 
  77         /* Do we get the right fd? */
  78         ++test;
  79         if (fd2 != fd1 + 1)
  80                 printf("no ok %d - dup2(2) didn't give us the right fd\n",
  81                     test);
  82         else
  83                 printf("ok %d - dup2(2) returned a correct fd\n", test);
  84 
  85 #if 0
  86         /* Was close-on-exec cleared? */
  87         ++test;
  88         if (fcntl(fd2, F_GETFD) != 0)
  89                 printf("not ok %d - dup2(2) didn't clear close-on-exec\n",
  90                     test);
  91         else
  92                 printf("ok %d - dup2(2) cleared close-on-exec\n", test);
  93 #endif
  94 
  95         /*
  96          * Dup to itself.
  97          *
  98          * We're testing a small tweak in dup2 semantics.
  99          * Normally dup and dup2 will clear the close-on-exec
 100          * flag on the new fd (which appears to be an implementation
 101          * mistake from start and not some planned behavior).
 102          * In todays implementations of dup and dup2 we have to make
 103          * an effort to really clear that flag.  But all tested
 104          * implementations of dup2 have another tweak.  If we
 105          * dup2(old, new) when old == new, the syscall short-circuits
 106          * and returns early (because there is no need to do all the
 107          * work (and there is a risk for serious mistakes)).
 108          * So although the docs say that dup2 should "take 'old',
 109          * close 'new' perform a dup(2) of 'old' into 'new'"
 110          * the docs are not really followed because close-on-exec
 111          * is not cleared on 'new'.
 112          *
 113          * Since everyone has this bug, we pretend that this is
 114          * the way it is supposed to be and test here that it really
 115          * works that way.
 116          *
 117          * This is a fine example on where two separate implementation
 118          * fuckups take out each other and make the end-result the way
 119          * it was meant to be.
 120          */
 121         if ((fd2 = dup2(fd1, fd1)) < 0)
 122                 err(1, "dup2");
 123         printf("ok %d - dup2(2) to itself works\n", ++test);
 124 
 125         /* Do we get the right fd? */
 126         ++test;
 127         if (fd2 != fd1)
 128                 printf("not ok %d - dup2(2) didn't give us the right fd\n",
 129                     test);
 130         else
 131                 printf("ok %d - dup2(2) to itself returned a correct fd\n",
 132                     test);
 133 
 134 #if 0
 135         /* Was close-on-exec cleared? */
 136         ++test;
 137         if (fcntl(fd2, F_GETFD) == 0)
 138                 printf("not ok %d - dup2(2) cleared close-on-exec\n", test);
 139         else
 140                 printf("ok %d - dup2(2) didn't clear close-on-exec\n", test);
 141 #endif
 142 
 143         /* Does fcntl(F_DUPFD) work? */
 144         if ((fd2 = fcntl(fd1, F_DUPFD, 0)) < 0)
 145                 err(1, "fcntl(F_DUPFD)");
 146         printf("ok %d - fcntl(F_DUPFD) works\n", ++test);
 147 
 148 #if 0
 149         /* Was close-on-exec cleared? */
 150         ++test;
 151         if (fcntl(fd2, F_GETFD) != 0)
 152                 printf(
 153                     "not ok %d - fcntl(F_DUPFD) didn't clear close-on-exec\n",
 154                     test);
 155         else
 156                 printf("ok %d - fcntl(F_DUPFD) cleared close-on-exec\n", test);
 157 
 158 #endif
 159         ++test;
 160         if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
 161                 err(1, "getrlimit");
 162         if ((fd2 = dup2(fd1, (int)(rlp.rlim_cur + 1))) >= 0)
 163                 printf("not ok %d - dup2(2) bypassed NOFILE limit\n", test);
 164         else
 165                 printf("ok %d - dup2(2) didn't bypass NOFILE limit\n", test);
 166 
 167         return (0);
 168 }

/* [<][>][^][v][top][bottom][index][help] */