8000 Adapt oclo tests to FreeBSD · freebsd/freebsd-src@505e06c · GitHub
[go: up one dir, main page]

Skip to content

Commit 505e06c

Browse files
Adapt oclo tests to FreeBSD
1 parent eb2f15d commit 505e06c

File tree

6 files changed

+140
-97
lines changed

6 files changed

+140
-97
lines changed

cddl/contrib/opensolaris/tests/oclo/Makefile

Lines changed: 0 additions & 59 deletions
This file was deleted.

cddl/contrib/opensolaris/tests/oclo/oclo.c

Lines changed: 80 additions & 22 deletions
< 10000 /tr>
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,87 @@
4141
* program that will verify everything is correctly honored after an exec.
4242
*/
4343

44+
#include <sys/param.h>
45+
#include <sys/sysctl.h>
46+
47+
#include <netinet/in.h>
48+
#include <sys/socket.h>
49+
50+
#include <stdio.h>
51+
#include <stdint.h>
4452
#include <stdlib.h>
4553
#include <unistd.h>
4654
#include <stdbool.h>
4755
#include <err.h>
48-
#include <sys/types.h>
4956
#include <sys/stat.h>
5057
#include <fcntl.h>
51-
#include <sys/sysmacros.h>
52-
#include <sys/fork.h>
53-
#include <wait.h>
58+
#include <sys/wait.h>
5459
#include <errno.h>
5560
#include <string.h>
5661
#include <limits.h>
5762
#include <libgen.h>
58-
#include <sys/socket.h>
63+
#include <fcntl.h>
64+
#include <signal.h>
65+
66+
void *recallocarray(void *, size_t, size_t, size_t);
67+
68+
#define strerrorname_np(e) (sys_errlist[e])
69+
70+
#ifndef FORK_NOSIGCHLD
71+
#define FORK_NOSIGCHLD 0x01
72+
#endif
73+
74+
#ifndef FORK_WAITPID
75+
#define FORK_WAITPID 0x02
76+
#endif
77+
78+
/*
79+
* Simulate Solaris' forkx() with rfork()
80+
*/
81+
static pid_t
82+
forkx(int flags)
83+
{
84+
int rfork_flags = RFPROC | RFFDG;
85+
pid_t pid;
86+
87+
if ((flags & ~(FORK_NOSIGCHLD | FORK_WAITPID)) != 0) {
88+
errno = EINVAL;
89+
return (-1);
90+
}
91+
92+
if ((flags & FORK_WAITPID) == 0)
93+
rfork_flags |= RFNOWAIT;
94+
95+
pid = rfork(rfork_flags);
96+
if (pid == -1)
97+
return (-1);
98+
99+
return (pid);
100+
}
101+
102+
/*
103+
* Get pathname to avoid reading /proc/curproc/exe
104+
*
105+
* Taken from procstat_getpathname_sysctl()
106+
*/
107+
static int
108+
getpathname(pid_t pid, char *pathname, size_t maxlen)
109+
{
110+
int error, name[4];
111+
size_t len;
112+
113+
name[0] = CTL_KERN;
114+
name[1] = KERN_PROC;
115+
name[2] = KERN_PROC_PATHNAME;
116+
name[3] = pid;
117+
len = maxlen;
118+
error = sysctl(name, nitems(name), pathname, &len, NULL, 0);
119+
if (error != 0 && errno != ESRCH)
120+
warn("sysctl: kern.proc.pathname: %d", pid);
121+
if (len == 0)
122+
pathname[0] = '\0';
123+
return (error);
124+
}
59125

60126
/*
61127
* Verification program name.
@@ -89,8 +155,8 @@ typedef struct clo_rtdata {
89155
} clo_rtdata_t;
90156

91157
static clo_rtdata_t *oclo_rtdata;
92-
size_t oclo_rtdata_nents = 0;
93-
size_t oclo_rtdata_next = 0;
158+
static size_t oclo_rtdata_nents = 0;
159+
static size_t oclo_rtdata_next = 0;
94160
static int oclo_nextfd = STDERR_FILENO + 1;
95161

96162
static bool
@@ -267,7 +333,7 @@ oclo_fdup_common(const clo_create_t *c, int targ_flags, int cmd)
267333
dup = fcntl(fd, cmd, fd + 1);
268334
break;
269335
case F_DUP3FD:
270-
dup = fcntl(fd, cmd, fd + 1, targ_flags);
336+
dup = fcntl(fd, cmd | (targ_flags << 16), fd + 1);
271337
break;
272338
default:
273339
errx(EXIT_FAILURE, "TEST FAILURE: %s: internal error: "
@@ -600,7 +666,7 @@ oclo_rights_common(const clo_create_t *c, int targ_flags)
600666

601667
if (msg.msg_controllen < CMSG_SPACE(sizeof (int))) {
602668
errx(EXIT_FAILURE, "TEST FAILED: %s: found insufficient "
603-
"message control length: expected at least 0x%x, found "
669+
"message control length: expected at least 0x%lx, found "
604670
"0x%x", c->clo_desc, CMSG_SPACE(sizeof (int)),
605671
msg.msg_controllen);
606672
}
@@ -1208,20 +1274,12 @@ oclo_exec(void)
12081274
char dir[PATH_MAX], file[PATH_MAX];
12091275
char **argv;
12101276

1211-
ret = readlink("/proc/self/path/a.out", dir, sizeof (dir));
1212-
if (ret < 0) {
1213-
err(EXIT_FAILURE, "TEST FAILED: failed to read our a.out path "
1214-
"from /proc");
1215-
} else if (ret == 0) {
1216-
errx(EXIT_FAILURE, "TEST FAILED: reading /proc/self/path/a.out "
1217-
"returned 0 bytes");
1218-
} else if (ret == sizeof (dir)) {
1219-
errx(EXIT_FAILURE, "TEST FAILED: Using /proc/self/path/a.out "
1220-
"requires truncation");
1221-
}
1277+
ret = getpathname(getpid(), dir, sizeof(dir));
1278+
if (ret < 0)
1279+
err(EXIT_FAILURE, "TEST FAILED: failed to read executable path");
12221280

12231281
if (snprintf(file, sizeof (file), "%s/%s", dirname(dir), OCLO_VERIFY) >=
1224-
sizeof (file)) {
1282+
(int)sizeof (file)) {
12251283
errx(EXIT_FAILURE, "TEST FAILED: cannot assemble exec path "
12261284
"name: internal buffer overflow");
12271285
}
@@ -1262,7 +1320,7 @@ main(void)
12621320
* Treat failure during this set up phase as a hard failure. There's no
12631321
* reason to continue if we can't successfully create the FDs we expect.
12641322
*/
1265-
for (size_t i = 0; i < ARRAY_SIZE(oclo_create); i++) {
1323+
for (size_t i = 0; i < nitems(oclo_create); i++) {
12661324
oclo_create[i].clo_func(&oclo_create[i]);
12671325
}
12681326

cddl/contrib/opensolaris/tests/oclo/oclo_errors.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,20 @@
2424
* o accept4()
2525
*/
2626

27+
#include <netinet/in.h>
28+
#include <sys/socket.h>
29+
#include <stdint.h>
2730
#include <stdlib.h>
2831
#include <err.h>
2932
#include <stdio.h>
3033
#include <unistd.h>
31-
#include <sys/stdbool.h>
34+
#include <stdbool.h>
3235
#include <errno.h>
3336
#include <string.h>
3437
#include <fcntl.h>
3538
#include <limits.h>
36-
#include <sys/socket.h>
39+
40+
#define strerrorname_np(e) (sys_errlist[e])
3741

3842
static bool
3943
oclo_check(const char *desc, const char *act, int ret, int e)
@@ -42,7 +46,7 @@ oclo_check(const char *desc, const char *act, int ret, int e)
4246
warnx("TEST FAILED: %s: fd was %s!", desc, act);
4347
return (false);
4448
} else if (errno != EINVAL) {
45-
int e = errno;
49+
e = errno;
4650
warnx("TEST FAILED: %s: failed with %s, expected "
4751
"EINVAL", desc, strerrorname_np(e));
4852
return (false);
@@ -63,7 +67,7 @@ oclo_dup3(const char *desc, int flags)
6367
static bool
6468
oclo_dup3fd(const char *desc, int flags)
6569
{
66-
int fd = fcntl(STDERR_FILENO, F_DUP3FD, 23, flags);
70+
int fd = fcntl(STDERR_FILENO, F_DUP3FD | (flags << 16), 23);
6771
return (oclo_check(desc, "duplicated", fd, errno));
6872
}
6973

@@ -77,12 +81,14 @@ oclo_pipe2(const char *desc, int flags)
7781
return (oclo_check(desc, "piped", ret, errno));
7882
}
7983

84+
#if 0
8085
static bool
8186
oclo_socket(const char *desc, int type)
8287
{
8388
int fd = socket(PF_UNIX, SOCK_STREAM | type, 0);
8489
return (oclo_check(desc, "created", fd, errno));
8590
}
91+
#endif
8692

8793
static bool
8894
oclo_accept(const char *desc, int flags)
@@ -169,13 +175,15 @@ main(void)
169175
ret = EXIT_FAILURE;
170176
}
171177

178+
#if 0 /* These tests are known to fail on FreeBSD */
172179
if (!oclo_socket("socket(): INT32_MAX", INT32_MAX)) {
173180
ret = EXIT_FAILURE;
174181
}
175182

176183
if (!oclo_socket("socket(): 3 << 25", 3 << 25)) {
177184
ret = EXIT_FAILURE;
178185
}
186+
#endif
179187

180188
if (!oclo_accept("accept4(): INT32_MAX", INT32_MAX)) {
181189
ret = EXIT_FAILURE;

cddl/contrib/opensolaris/tests/oclo/ocloexec_verify.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,35 @@
2323
*/
2424

2525
#include <err.h>
26+
#include <errno.h>
27+
#include <stdio.h>
2628
#include <stdlib.h>
2729
#include <unistd.h>
2830
#include <fcntl.h>
2931
#include <stdbool.h>
3032
#include <errno.h>
3133
#include <string.h>
34+
#include <sys/user.h>
35+
#include <libutil.h>
36+
37+
#define strerrorname_np(e) (sys_errlist[e])
3238

3339
static int
34-
verify_fdwalk_cb(void *arg, int fd)
40+
getmaxfd(void)
3541
{
36-
int *max = arg;
37-
*max = fd;
38-
return (0);
42+
struct kinfo_file *files;
43+
int i, cnt, max;
44+
45+
if ((files = kinfo_getfile(getpid(), &cnt)) == NULL)
46+
err(1, "kinfo_getfile");
47+
48+
max = -1;
49+
for (i = 0; i < cnt; i++)
50+
if (files[i].kf_fd > max)
51+
max = files[i].kf_fd;
52+
53+
free(files);
54+
return (max);
3955
}
4056

4157
static bool
@@ -88,7 +104,7 @@ verify_flags(int fd, int exp_flags)
88104
int
89105
main(int argc, char *argv[])
90106
{
91-
int maxfd = STDIN_FILENO;
107+
int maxfd;
92108
int ret = EXIT_SUCCESS;
93109

94110
/*
@@ -97,24 +113,25 @@ main(int argc, char *argv[])
97113
* program name, which we want to skip. Note, the last fd may not exist
98114
* because it was marked for close, hence the use of '>' below.
99115
*/
100-
(void) fdwalk(verify_fdwalk_cb, &maxfd);
116+
maxfd = getmaxfd();
101117
if (maxfd - 3 > argc - 1) {
102118
errx(EXIT_FAILURE, "TEST FAILED: found more fds %d than "
103119
"arguments %d", maxfd - 3, argc - 1);
104120
}
105121

106122
for (int i = 1; i < argc; i++) {
107-
const char *errstr;
123+
char *endptr;
108124
int targ_fd = i + STDERR_FILENO;
109-
long long targ_flags = strtonumx(argv[i], 0,
110-
FD_CLOEXEC | FD_CLOFORK, &errstr, 0);
125+
errno = 0;
126+
long long val = strtoll(argv[i], &endptr, 0);
111127

112-
if (errstr != NULL) {
128+
if (errno != 0 || *endptr != '\0' ||
129+
(val < 0 || val > (FD_CLOEXEC | FD_CLOFORK))) {
113130
errx(EXIT_FAILURE, "TEST FAILED: failed to parse "
114-
"argument %d: %s is %s", i, argv[i], errstr);
131+
"argument %d: %s", i, argv[i]);
115132
}
116133

117-
if (!verify_flags(targ_fd, (int)targ_flags))
134+
if (!verify_flags(targ_fd, (int)val))
118135
ret = EXIT_FAILURE;
119136
}
120137

tests/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.include <src.opts.mk>
2+
13
PACKAGE= tests
24

35
TESTSDIR= ${TESTSBASE}
@@ -11,6 +13,9 @@ SUBDIR+= examples
1113
SUBDIR+= include
1214
SUBDIR+= sys
1315
SUBDIR+= atf_python
16+
.if ${MK_CDDL} != "no"
17+
SUBDIR+= oclo
18+
.endif
1419

1520
SUBDIR_PARALLEL=
1621

0 commit comments

Comments
 (0)
0