Tue Mar 6 10:32:15 2012 UTC ()
A test case for PR kern/46077: fstat() returns EINVAL on dup'd connected
socket. Expected failure on NetBSD x86, 5.0 - 6.0. Does not fail on Linux.


(jruoho)
diff -r1.2 -r1.3 src/tests/lib/libc/sys/t_stat.c

cvs diff -r1.2 -r1.3 src/tests/lib/libc/sys/t_stat.c (switch to unified diff)

--- src/tests/lib/libc/sys/t_stat.c 2011/10/16 08:28:10 1.2
+++ src/tests/lib/libc/sys/t_stat.c 2012/03/06 10:32:15 1.3
@@ -1,369 +1,418 @@ @@ -1,369 +1,418 @@
1/* $NetBSD: t_stat.c,v 1.2 2011/10/16 08:28:10 jruoho Exp $ */ 1/* $NetBSD: t_stat.c,v 1.3 2012/03/06 10:32:15 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen. 8 * by Jukka Ruohonen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_stat.c,v 1.2 2011/10/16 08:28:10 jruoho Exp $"); 32__RCSID("$NetBSD: t_stat.c,v 1.3 2012/03/06 10:32:15 jruoho Exp $");
33 33
34#include <sys/stat.h> 34#include <sys/stat.h>
 35#include <sys/socket.h>
35#include <sys/types.h> 36#include <sys/types.h>
36 37
 38#include <arpa/inet.h>
 39
37#include <atf-c.h> 40#include <atf-c.h>
38#include <errno.h> 41#include <errno.h>
39#include <fcntl.h> 42#include <fcntl.h>
40#include <fts.h> 43#include <fts.h>
41#include <limits.h> 44#include <limits.h>
42#include <string.h> 45#include <string.h>
43#include <unistd.h> 46#include <unistd.h>
44 47
45#include <stdio.h> 48#include <stdio.h>
46 49
47static const char *path = "stat"; 50static const char *path = "stat";
48 51
49ATF_TC_WITH_CLEANUP(stat_chflags); 52ATF_TC_WITH_CLEANUP(stat_chflags);
50ATF_TC_HEAD(stat_chflags, tc) 53ATF_TC_HEAD(stat_chflags, tc)
51{ 54{
52 atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)"); 55 atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)");
53} 56}
54 57
55ATF_TC_BODY(stat_chflags, tc) 58ATF_TC_BODY(stat_chflags, tc)
56{ 59{
57 struct stat sa, sb; 60 struct stat sa, sb;
58 int fd; 61 int fd;
59 62
60 (void)memset(&sa, 0, sizeof(struct stat)); 63 (void)memset(&sa, 0, sizeof(struct stat));
61 (void)memset(&sb, 0, sizeof(struct stat)); 64 (void)memset(&sb, 0, sizeof(struct stat));
62 65
63 fd = open(path, O_RDONLY | O_CREAT); 66 fd = open(path, O_RDONLY | O_CREAT);
64 67
65 ATF_REQUIRE(fd != -1); 68 ATF_REQUIRE(fd != -1);
66 ATF_REQUIRE(stat(path, &sa) == 0); 69 ATF_REQUIRE(stat(path, &sa) == 0);
67 ATF_REQUIRE(chflags(path, UF_NODUMP) == 0); 70 ATF_REQUIRE(chflags(path, UF_NODUMP) == 0);
68 ATF_REQUIRE(stat(path, &sb) == 0); 71 ATF_REQUIRE(stat(path, &sb) == 0);
69 72
70 if (sa.st_flags == sb.st_flags) 73 if (sa.st_flags == sb.st_flags)
71 atf_tc_fail("stat(2) did not detect chflags(2)"); 74 atf_tc_fail("stat(2) did not detect chflags(2)");
72 75
73 ATF_REQUIRE(close(fd) == 0); 76 ATF_REQUIRE(close(fd) == 0);
74 ATF_REQUIRE(unlink(path) == 0); 77 ATF_REQUIRE(unlink(path) == 0);
75} 78}
76 79
77ATF_TC_CLEANUP(stat_chflags, tc) 80ATF_TC_CLEANUP(stat_chflags, tc)
78{ 81{
79 (void)unlink(path); 82 (void)unlink(path);
80} 83}
81 84
82ATF_TC(stat_dir); 85ATF_TC(stat_dir);
83ATF_TC_HEAD(stat_dir, tc) 86ATF_TC_HEAD(stat_dir, tc)
84{ 87{
85 atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories"); 88 atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories");
86} 89}
87 90
88ATF_TC_BODY(stat_dir, tc) 91ATF_TC_BODY(stat_dir, tc)
89{ 92{
90 const short depth = 2; 93 const short depth = 2;
91 struct stat sa, sb; 94 struct stat sa, sb;
92 char *argv[2]; 95 char *argv[2];
93 FTSENT *ftse; 96 FTSENT *ftse;
94 FTS *fts; 97 FTS *fts;
95 int ops; 98 int ops;
96 99
97 argv[1] = NULL; 100 argv[1] = NULL;
98 argv[0] = __UNCONST("/"); 101 argv[0] = __UNCONST("/");
99 102
100 ops = FTS_NOCHDIR; 103 ops = FTS_NOCHDIR;
101 ops |= FTS_PHYSICAL; 104 ops |= FTS_PHYSICAL;
102 105
103 fts = fts_open(argv, ops, NULL); 106 fts = fts_open(argv, ops, NULL);
104 ATF_REQUIRE(fts != NULL); 107 ATF_REQUIRE(fts != NULL);
105 108
106 while ((ftse = fts_read(fts)) != NULL) { 109 while ((ftse = fts_read(fts)) != NULL) {
107 110
108 if (ftse->fts_level < 1) 111 if (ftse->fts_level < 1)
109 continue; 112 continue;
110 113
111 if (ftse->fts_level > depth) { 114 if (ftse->fts_level > depth) {
112 (void)fts_set(fts, ftse, FTS_SKIP); 115 (void)fts_set(fts, ftse, FTS_SKIP);
113 continue; 116 continue;
114 } 117 }
115 118
116 switch(ftse->fts_info) { 119 switch(ftse->fts_info) {
117 120
118 case FTS_DP: 121 case FTS_DP:
119 122
120 (void)memset(&sa, 0, sizeof(struct stat)); 123 (void)memset(&sa, 0, sizeof(struct stat));
121 (void)memset(&sb, 0, sizeof(struct stat)); 124 (void)memset(&sb, 0, sizeof(struct stat));
122 125
123 ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0); 126 ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0);
124 ATF_REQUIRE(chdir(ftse->fts_path) == 0); 127 ATF_REQUIRE(chdir(ftse->fts_path) == 0);
125 ATF_REQUIRE(stat(".", &sb) == 0); 128 ATF_REQUIRE(stat(".", &sb) == 0);
126 129
127 /* 130 /*
128 * The previous two stat(2) calls 131 * The previous two stat(2) calls
129 * should be for the same directory. 132 * should be for the same directory.
130 */ 133 */
131 if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino) 134 if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino)
132 atf_tc_fail("inconsistent stat(2)"); 135 atf_tc_fail("inconsistent stat(2)");
133 136
134 /* 137 /*
135 * Check that fts(3)'s stat(2) 138 * Check that fts(3)'s stat(2)
136 * call equals the manual one. 139 * call equals the manual one.
137 */ 140 */
138 if (sb.st_ino != ftse->fts_statp->st_ino) 141 if (sb.st_ino != ftse->fts_statp->st_ino)
139 atf_tc_fail("stat(2) and fts(3) differ"); 142 atf_tc_fail("stat(2) and fts(3) differ");
140 143
141 break; 144 break;
142 145
143 default: 146 default:
144 break; 147 break;
145 } 148 }
146 } 149 }
147 150
148 (void)fts_close(fts); 151 (void)fts_close(fts);
149} 152}
150 153
151ATF_TC(stat_err); 154ATF_TC(stat_err);
152ATF_TC_HEAD(stat_err, tc) 155ATF_TC_HEAD(stat_err, tc)
153{ 156{
154 atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family"); 157 atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family");
155} 158}
156 159
157ATF_TC_BODY(stat_err, tc) 160ATF_TC_BODY(stat_err, tc)
158{ 161{
159 char buf[NAME_MAX + 1]; 162 char buf[NAME_MAX + 1];
160 struct stat st; 163 struct stat st;
161 164
162 (void)memset(buf, 'x', sizeof(buf)); 165 (void)memset(buf, 'x', sizeof(buf));
163 166
164 errno = 0; 167 errno = 0;
165 ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1); 168 ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1);
166 169
167 errno = 0; 170 errno = 0;
168 ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1); 171 ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1);
169 172
170 errno = 0; 173 errno = 0;
171 ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1); 174 ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1);
172 175
173 errno = 0; 176 errno = 0;
174 ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1); 177 ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1);
175 178
176 errno = 0; 179 errno = 0;
177 ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1); 180 ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1);
178 181
179 errno = 0; 182 errno = 0;
180 ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1); 183 ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1);
181 184
182 errno = 0; 185 errno = 0;
183 ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1); 186 ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1);
184 187
185 errno = 0; 188 errno = 0;
186 ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); 189 ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
187 190
188 errno = 0; 191 errno = 0;
189 ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); 192 ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
190} 193}
191 194
192ATF_TC_WITH_CLEANUP(stat_mtime); 195ATF_TC_WITH_CLEANUP(stat_mtime);
193ATF_TC_HEAD(stat_mtime, tc) 196ATF_TC_HEAD(stat_mtime, tc)
194{ 197{
195 atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)"); 198 atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)");
196} 199}
197 200
198ATF_TC_BODY(stat_mtime, tc) 201ATF_TC_BODY(stat_mtime, tc)
199{ 202{
200 struct stat sa, sb; 203 struct stat sa, sb;
201 int fd[3]; 204 int fd[3];
202 size_t i; 205 size_t i;
203 206
204 for (i = 0; i < __arraycount(fd); i++) { 207 for (i = 0; i < __arraycount(fd); i++) {
205 208
206 (void)memset(&sa, 0, sizeof(struct stat)); 209 (void)memset(&sa, 0, sizeof(struct stat));
207 (void)memset(&sb, 0, sizeof(struct stat)); 210 (void)memset(&sb, 0, sizeof(struct stat));
208 211
209 fd[i] = open(path, O_WRONLY | O_CREAT); 212 fd[i] = open(path, O_WRONLY | O_CREAT);
210 213
211 ATF_REQUIRE(fd[i] != -1); 214 ATF_REQUIRE(fd[i] != -1);
212 ATF_REQUIRE(write(fd[i], "X", 1) == 1); 215 ATF_REQUIRE(write(fd[i], "X", 1) == 1);
213 ATF_REQUIRE(stat(path, &sa) == 0); 216 ATF_REQUIRE(stat(path, &sa) == 0);
214 217
215 (void)sleep(1); 218 (void)sleep(1);
216 219
217 ATF_REQUIRE(write(fd[i], "X", 1) == 1); 220 ATF_REQUIRE(write(fd[i], "X", 1) == 1);
218 ATF_REQUIRE(stat(path, &sb) == 0); 221 ATF_REQUIRE(stat(path, &sb) == 0);
219 222
220 ATF_REQUIRE(close(fd[i]) == 0); 223 ATF_REQUIRE(close(fd[i]) == 0);
221 ATF_REQUIRE(unlink(path) == 0); 224 ATF_REQUIRE(unlink(path) == 0);
222 225
223 if (sa.st_mtime == sb.st_mtime) 226 if (sa.st_mtime == sb.st_mtime)
224 atf_tc_fail("mtimes did not change"); 227 atf_tc_fail("mtimes did not change");
225 } 228 }
226} 229}
227 230
228ATF_TC_CLEANUP(stat_mtime, tc) 231ATF_TC_CLEANUP(stat_mtime, tc)
229{ 232{
230 (void)unlink(path); 233 (void)unlink(path);
231} 234}
232 235
233ATF_TC_WITH_CLEANUP(stat_perm); 236ATF_TC_WITH_CLEANUP(stat_perm);
234ATF_TC_HEAD(stat_perm, tc) 237ATF_TC_HEAD(stat_perm, tc)
235{ 238{
236 atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)"); 239 atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)");
237 atf_tc_set_md_var(tc, "require.user", "root"); 240 atf_tc_set_md_var(tc, "require.user", "root");
238} 241}
239 242
240ATF_TC_BODY(stat_perm, tc) 243ATF_TC_BODY(stat_perm, tc)
241{ 244{
242 struct stat sa, sb; 245 struct stat sa, sb;
243 gid_t gid; 246 gid_t gid;
244 uid_t uid; 247 uid_t uid;
245 int fd; 248 int fd;
246 249
247 (void)memset(&sa, 0, sizeof(struct stat)); 250 (void)memset(&sa, 0, sizeof(struct stat));
248 (void)memset(&sb, 0, sizeof(struct stat)); 251 (void)memset(&sb, 0, sizeof(struct stat));
249 252
250 uid = getuid(); 253 uid = getuid();
251 gid = getgid(); 254 gid = getgid();
252 255
253 fd = open(path, O_RDONLY | O_CREAT); 256 fd = open(path, O_RDONLY | O_CREAT);
254 257
255 ATF_REQUIRE(fd != -1); 258 ATF_REQUIRE(fd != -1);
256 ATF_REQUIRE(fstat(fd, &sa) == 0); 259 ATF_REQUIRE(fstat(fd, &sa) == 0);
257 ATF_REQUIRE(stat(path, &sb) == 0); 260 ATF_REQUIRE(stat(path, &sb) == 0);
258 261
259 if (gid != sa.st_gid || sa.st_gid != sb.st_gid) 262 if (gid != sa.st_gid || sa.st_gid != sb.st_gid)
260 atf_tc_fail("invalid GID"); 263 atf_tc_fail("invalid GID");
261 264
262 if (uid != sa.st_uid || sa.st_uid != sb.st_uid) 265 if (uid != sa.st_uid || sa.st_uid != sb.st_uid)
263 atf_tc_fail("invalid UID"); 266 atf_tc_fail("invalid UID");
264 267
265 ATF_REQUIRE(close(fd) == 0); 268 ATF_REQUIRE(close(fd) == 0);
266 ATF_REQUIRE(unlink(path) == 0); 269 ATF_REQUIRE(unlink(path) == 0);
267} 270}
268 271
269ATF_TC_CLEANUP(stat_perm, tc) 272ATF_TC_CLEANUP(stat_perm, tc)
270{ 273{
271 (void)unlink(path); 274 (void)unlink(path);
272} 275}
273 276
274ATF_TC_WITH_CLEANUP(stat_size); 277ATF_TC_WITH_CLEANUP(stat_size);
275ATF_TC_HEAD(stat_size, tc) 278ATF_TC_HEAD(stat_size, tc)
276{ 279{
277 atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)"); 280 atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)");
278} 281}
279 282
280ATF_TC_BODY(stat_size, tc) 283ATF_TC_BODY(stat_size, tc)
281{ 284{
282 struct stat sa, sb, sc; 285 struct stat sa, sb, sc;
283 const size_t n = 10; 286 const size_t n = 10;
284 size_t i; 287 size_t i;
285 int fd; 288 int fd;
286 289
287 fd = open(path, O_WRONLY | O_CREAT); 290 fd = open(path, O_WRONLY | O_CREAT);
288 ATF_REQUIRE(fd >= 0); 291 ATF_REQUIRE(fd >= 0);
289 292
290 for (i = 0; i < n; i++) { 293 for (i = 0; i < n; i++) {
291 294
292 (void)memset(&sa, 0, sizeof(struct stat)); 295 (void)memset(&sa, 0, sizeof(struct stat));
293 (void)memset(&sb, 0, sizeof(struct stat)); 296 (void)memset(&sb, 0, sizeof(struct stat));
294 (void)memset(&sc, 0, sizeof(struct stat)); 297 (void)memset(&sc, 0, sizeof(struct stat));
295 298
296 ATF_REQUIRE(fstat(fd, &sa) == 0); 299 ATF_REQUIRE(fstat(fd, &sa) == 0);
297 ATF_REQUIRE(write(fd, "X", 1) == 1); 300 ATF_REQUIRE(write(fd, "X", 1) == 1);
298 ATF_REQUIRE(fstat(fd, &sb) == 0); 301 ATF_REQUIRE(fstat(fd, &sb) == 0);
299 ATF_REQUIRE(stat(path, &sc) == 0); 302 ATF_REQUIRE(stat(path, &sc) == 0);
300 303
301 if (sa.st_size + 1 != sb.st_size) 304 if (sa.st_size + 1 != sb.st_size)
302 atf_tc_fail("invalid file size"); 305 atf_tc_fail("invalid file size");
303 306
304 if (sb.st_size != sc.st_size) 307 if (sb.st_size != sc.st_size)
305 atf_tc_fail("stat(2) and fstat(2) mismatch"); 308 atf_tc_fail("stat(2) and fstat(2) mismatch");
306 } 309 }
307 310
308 ATF_REQUIRE(close(fd) == 0); 311 ATF_REQUIRE(close(fd) == 0);
309 ATF_REQUIRE(unlink(path) == 0); 312 ATF_REQUIRE(unlink(path) == 0);
310} 313}
311 314
312ATF_TC_CLEANUP(stat_size, tc) 315ATF_TC_CLEANUP(stat_size, tc)
313{ 316{
314 (void)unlink(path); 317 (void)unlink(path);
315} 318}
316 319
 320ATF_TC(stat_socket);
 321ATF_TC_HEAD(stat_socket, tc)
 322{
 323 atf_tc_set_md_var(tc, "descr", "Test fstat(2) with a socket");
 324}
 325
 326ATF_TC_BODY(stat_socket, tc)
 327{
 328 struct sockaddr_in addr;
 329 struct stat st;
 330 uint32_t iaddr;
 331 int fd, flags;
 332
 333 atf_tc_expect_fail("PR kern/46077");
 334
 335 (void)memset(&st, 0, sizeof(struct stat));
 336 (void)memset(&addr, 0, sizeof(struct sockaddr_in));
 337
 338 fd = socket(AF_INET, SOCK_STREAM, 0);
 339 ATF_REQUIRE(fd >= 0);
 340
 341 flags = fcntl(fd, F_GETFL);
 342
 343 ATF_REQUIRE(flags != -1);
 344 ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1);
 345 ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1);
 346
 347 addr.sin_port = htons(42);
 348 addr.sin_family = AF_INET;
 349 addr.sin_addr.s_addr = iaddr;
 350
 351 errno = 0;
 352
 353 ATF_REQUIRE_ERRNO(EINPROGRESS,
 354 connect(fd, (struct sockaddr *)&addr,
 355 sizeof(struct sockaddr_in)) == -1);
 356
 357 errno = 0;
 358
 359 if (fstat(fd, &st) != 0 || errno != 0)
 360 atf_tc_fail("fstat(2) failed for a EINPROGRESS socket");
 361
 362 (void)close(fd);
 363}
 364
317ATF_TC_WITH_CLEANUP(stat_symlink); 365ATF_TC_WITH_CLEANUP(stat_symlink);
318ATF_TC_HEAD(stat_symlink, tc) 366ATF_TC_HEAD(stat_symlink, tc)
319{ 367{
320 atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)"); 368 atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)");
321} 369}
322 370
323ATF_TC_BODY(stat_symlink, tc) 371ATF_TC_BODY(stat_symlink, tc)
324{ 372{
325 const char *pathlink = "pathlink"; 373 const char *pathlink = "pathlink";
326 struct stat sa, sb; 374 struct stat sa, sb;
327 int fd; 375 int fd;
328 376
329 (void)memset(&sa, 0, sizeof(struct stat)); 377 (void)memset(&sa, 0, sizeof(struct stat));
330 (void)memset(&sb, 0, sizeof(struct stat)); 378 (void)memset(&sb, 0, sizeof(struct stat));
331 379
332 fd = open(path, O_WRONLY | O_CREAT); 380 fd = open(path, O_WRONLY | O_CREAT);
333 381
334 ATF_REQUIRE(fd >= 0); 382 ATF_REQUIRE(fd >= 0);
335 ATF_REQUIRE(symlink(path, pathlink) == 0); 383 ATF_REQUIRE(symlink(path, pathlink) == 0);
336 ATF_REQUIRE(stat(pathlink, &sa) == 0); 384 ATF_REQUIRE(stat(pathlink, &sa) == 0);
337 ATF_REQUIRE(lstat(pathlink, &sb) == 0); 385 ATF_REQUIRE(lstat(pathlink, &sb) == 0);
338 386
339 if (S_ISLNK(sa.st_mode) != 0) 387 if (S_ISLNK(sa.st_mode) != 0)
340 atf_tc_fail("stat(2) detected symbolic link"); 388 atf_tc_fail("stat(2) detected symbolic link");
341 389
342 if (S_ISLNK(sb.st_mode) == 0) 390 if (S_ISLNK(sb.st_mode) == 0)
343 atf_tc_fail("lstat(2) did not detect symbolic link"); 391 atf_tc_fail("lstat(2) did not detect symbolic link");
344 392
345 if (sa.st_mode == sb.st_mode) 393 if (sa.st_mode == sb.st_mode)
346 atf_tc_fail("inconsistencies between stat(2) and lstat(2)"); 394 atf_tc_fail("inconsistencies between stat(2) and lstat(2)");
347 395
348 ATF_REQUIRE(unlink(path) == 0); 396 ATF_REQUIRE(unlink(path) == 0);
349 ATF_REQUIRE(unlink(pathlink) == 0); 397 ATF_REQUIRE(unlink(pathlink) == 0);
350} 398}
351 399
352ATF_TC_CLEANUP(stat_symlink, tc) 400ATF_TC_CLEANUP(stat_symlink, tc)
353{ 401{
354 (void)unlink(path); 402 (void)unlink(path);
355} 403}
356 404
357ATF_TP_ADD_TCS(tp) 405ATF_TP_ADD_TCS(tp)
358{ 406{
359 407
360 ATF_TP_ADD_TC(tp, stat_chflags); 408 ATF_TP_ADD_TC(tp, stat_chflags);
361 ATF_TP_ADD_TC(tp, stat_dir); 409 ATF_TP_ADD_TC(tp, stat_dir);
362 ATF_TP_ADD_TC(tp, stat_err); 410 ATF_TP_ADD_TC(tp, stat_err);
363 ATF_TP_ADD_TC(tp, stat_mtime); 411 ATF_TP_ADD_TC(tp, stat_mtime);
364 ATF_TP_ADD_TC(tp, stat_perm); 412 ATF_TP_ADD_TC(tp, stat_perm);
365 ATF_TP_ADD_TC(tp, stat_size); 413 ATF_TP_ADD_TC(tp, stat_size);
 414 ATF_TP_ADD_TC(tp, stat_socket);
366 ATF_TP_ADD_TC(tp, stat_symlink); 415 ATF_TP_ADD_TC(tp, stat_symlink);
367 416
368 return atf_no_error(); 417 return atf_no_error();
369} 418}