]> granicus.if.org Git - strace/blob - tests/xselect.c
Introduce generic STRINGIFY and STRINGIFY_VAL macros
[strace] / tests / xselect.c
1 /*
2  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
3  * Copyright (c) 2015-2017 The strace developers.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Based on test by Dr. David Alan Gilbert <dave@treblig.org>
31  */
32
33 #include <assert.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/select.h>
38
39 static fd_set set[0x1000000 / sizeof(fd_set)];
40
41 int main(void)
42 {
43         TAIL_ALLOC_OBJECT_CONST_PTR(struct timeval, tv);
44         struct timeval tv_in;
45         int fds[2];
46         long rc;
47
48         if (pipe(fds))
49                 perror_msg_and_fail("pipe");
50
51         /*
52          * Start with a nice simple select.
53          */
54         FD_ZERO(set);
55         FD_SET(fds[0], set);
56         FD_SET(fds[1], set);
57         rc = syscall(TEST_SYSCALL_NR, fds[1] + 1, set, set, set, NULL);
58         if (rc < 0)
59                 perror_msg_and_skip(TEST_SYSCALL_STR);
60         assert(rc == 1);
61         printf("%s(%d, [%d %d], [%d %d], [%d %d], NULL) = 1 ()\n",
62                TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
63                fds[0], fds[1], fds[0], fds[1]);
64
65         /*
66          * Odd timeout.
67          */
68         FD_SET(fds[0], set);
69         FD_SET(fds[1], set);
70         tv->tv_sec = 0xdeadbeefU;
71         tv->tv_usec = 0xfacefeedU;
72         memcpy(&tv_in, tv, sizeof(tv_in));
73         rc = syscall(TEST_SYSCALL_NR, fds[1] + 1, set, set, set, tv);
74         if (rc < 0) {
75                 printf("%s(%d, [%d %d], [%d %d], [%d %d]"
76                        ", {tv_sec=%lld, tv_usec=%llu}) = %s\n",
77                        TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
78                        fds[0], fds[1], fds[0], fds[1], (long long) tv->tv_sec,
79                        zero_extend_signed_to_ull(tv->tv_usec), sprintrc(rc));
80         } else {
81                 printf("%s(%d, [%d %d], [%d %d], [%d %d]"
82                        ", {tv_sec=%lld, tv_usec=%llu}) = %ld"
83                        " (left {tv_sec=%lld, tv_usec=%llu})\n",
84                        TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
85                        fds[0], fds[1], fds[0], fds[1], (long long) tv_in.tv_sec,
86                        zero_extend_signed_to_ull(tv_in.tv_usec),
87                        rc, (long long) tv->tv_sec,
88                        zero_extend_signed_to_ull(tv->tv_usec));
89         }
90
91         FD_SET(fds[0], set);
92         FD_SET(fds[1], set);
93         tv->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
94         tv->tv_usec = (long) 0xbadc0dedfacefeedLL;
95         memcpy(&tv_in, tv, sizeof(tv_in));
96         rc = syscall(TEST_SYSCALL_NR, fds[1] + 1, set, set, set, tv);
97         if (rc < 0) {
98                 printf("%s(%d, [%d %d], [%d %d], [%d %d]"
99                        ", {tv_sec=%lld, tv_usec=%llu}) = %s\n",
100                        TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
101                        fds[0], fds[1], fds[0], fds[1], (long long) tv->tv_sec,
102                        zero_extend_signed_to_ull(tv->tv_usec), sprintrc(rc));
103         } else {
104                 printf("%s(%d, [%d %d], [%d %d], [%d %d]"
105                        ", {tv_sec=%lld, tv_usec=%llu}) = %ld"
106                        " (left {tv_sec=%lld, tv_usec=%llu})\n",
107                        TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
108                        fds[0], fds[1], fds[0], fds[1], (long long) tv_in.tv_sec,
109                        zero_extend_signed_to_ull(tv_in.tv_usec),
110                        rc, (long long) tv->tv_sec,
111                        zero_extend_signed_to_ull(tv->tv_usec));
112         }
113
114         /*
115          * Another simple one, with a timeout.
116          */
117         FD_SET(1, set);
118         FD_SET(2, set);
119         FD_SET(fds[0], set);
120         FD_SET(fds[1], set);
121         tv->tv_sec = 0xc0de1;
122         tv->tv_usec = 0xc0de2;
123         memcpy(&tv_in, tv, sizeof(tv_in));
124         assert(syscall(TEST_SYSCALL_NR, fds[1] + 1, NULL, set, NULL, tv) == 3);
125         printf("%s(%d, NULL, [1 2 %d %d], NULL, {tv_sec=%lld, tv_usec=%llu})"
126                " = 3 (out [1 2 %d], left {tv_sec=%lld, tv_usec=%llu})\n",
127                TEST_SYSCALL_STR, fds[1] + 1, fds[0], fds[1],
128                (long long) tv_in.tv_sec,
129                zero_extend_signed_to_ull(tv_in.tv_usec),
130                fds[1],
131                (long long) tv->tv_sec,
132                zero_extend_signed_to_ull(tv->tv_usec));
133
134         /*
135          * Now the crash case that trinity found, negative nfds
136          * but with a pointer to a large chunk of valid memory.
137          */
138         FD_ZERO(set);
139         FD_SET(fds[1], set);
140         assert(syscall(TEST_SYSCALL_NR, -1, NULL, set, NULL, NULL) == -1);
141         printf("%s(-1, NULL, %p, NULL, NULL) = -1 EINVAL (%m)\n",
142                TEST_SYSCALL_STR, set);
143
144         /*
145          * Another variant, with nfds exceeding FD_SETSIZE limit.
146          */
147         FD_ZERO(set);
148         FD_SET(fds[0], set);
149         tv->tv_sec = 0;
150         tv->tv_usec = 123;
151         assert(syscall(TEST_SYSCALL_NR, FD_SETSIZE + 1, set, set + 1, NULL, tv) == 0);
152         printf("%s(%d, [%d], [], NULL, {tv_sec=0, tv_usec=123}) = 0 (Timeout)\n",
153                TEST_SYSCALL_STR, FD_SETSIZE + 1, fds[0]);
154
155         puts("+++ exited with 0 +++");
156         return 0;
157 }