Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / test / dup / dup.c @ 03e9c04a

History | View | Annotate | Download (4.57 KB)

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
}