selftests/nolibc: not include limits.h for nolibc
[linux-block.git] / tools / testing / selftests / nolibc / nolibc-test.c
CommitLineData
fddc8f81 1/* SPDX-License-Identifier: GPL-2.0 */
362aecb2 2
1da02f51
WT
3#define _GNU_SOURCE
4
362aecb2 5/* libc-specific include files
1da02f51 6 * The program may be built in 3 ways:
362aecb2 7 * $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined
1da02f51
WT
8 * $(CC) -nostdlib -I/path/to/nolibc/sysroot => _NOLIBC_* guards are present
9 * $(CC) with default libc => NOLIBC* never defined
362aecb2
WT
10 */
11#ifndef NOLIBC
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
1da02f51
WT
15#ifndef _NOLIBC_STDIO_H
16/* standard libcs need more includes */
17#include <linux/reboot.h>
18#include <sys/io.h>
19#include <sys/ioctl.h>
69f2cd9f 20#include <sys/mman.h>
1da02f51 21#include <sys/mount.h>
208aa9d9 22#include <sys/prctl.h>
1da02f51
WT
23#include <sys/reboot.h>
24#include <sys/stat.h>
25#include <sys/syscall.h>
26#include <sys/sysmacros.h>
27#include <sys/time.h>
28#include <sys/wait.h>
29#include <dirent.h>
30#include <errno.h>
31#include <fcntl.h>
32#include <poll.h>
33#include <sched.h>
34#include <signal.h>
35#include <stdarg.h>
2df07fc5
WT
36#include <stddef.h>
37#include <stdint.h>
1da02f51 38#include <unistd.h>
bd27fef3 39#include <limits.h>
1da02f51 40#endif
362aecb2
WT
41#endif
42
43/* will be used by nolibc by getenv() */
44char **environ;
45
23da7bc9
WT
46/* definition of a series of tests */
47struct test {
fddc8f81
TW
48 const char *name; /* test name */
49 int (*func)(int min, int max); /* handler */
23da7bc9
WT
50};
51
1da02f51
WT
52#ifndef _NOLIBC_STDLIB_H
53char *itoa(int i)
54{
55 static char buf[12];
56 int ret;
57
58 ret = snprintf(buf, sizeof(buf), "%d", i);
59 return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err";
60}
61#endif
62
362aecb2
WT
63#define CASE_ERR(err) \
64 case err: return #err
65
66/* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0,
67 * or the decimal value for less common ones.
68 */
69const char *errorname(int err)
70{
71 switch (err) {
72 case 0: return "SUCCESS";
73 CASE_ERR(EPERM);
74 CASE_ERR(ENOENT);
75 CASE_ERR(ESRCH);
76 CASE_ERR(EINTR);
77 CASE_ERR(EIO);
78 CASE_ERR(ENXIO);
79 CASE_ERR(E2BIG);
80 CASE_ERR(ENOEXEC);
81 CASE_ERR(EBADF);
82 CASE_ERR(ECHILD);
83 CASE_ERR(EAGAIN);
84 CASE_ERR(ENOMEM);
85 CASE_ERR(EACCES);
86 CASE_ERR(EFAULT);
87 CASE_ERR(ENOTBLK);
88 CASE_ERR(EBUSY);
89 CASE_ERR(EEXIST);
90 CASE_ERR(EXDEV);
91 CASE_ERR(ENODEV);
92 CASE_ERR(ENOTDIR);
93 CASE_ERR(EISDIR);
94 CASE_ERR(EINVAL);
95 CASE_ERR(ENFILE);
96 CASE_ERR(EMFILE);
97 CASE_ERR(ENOTTY);
98 CASE_ERR(ETXTBSY);
99 CASE_ERR(EFBIG);
100 CASE_ERR(ENOSPC);
101 CASE_ERR(ESPIPE);
102 CASE_ERR(EROFS);
103 CASE_ERR(EMLINK);
104 CASE_ERR(EPIPE);
105 CASE_ERR(EDOM);
106 CASE_ERR(ERANGE);
107 CASE_ERR(ENOSYS);
758f970f 108 CASE_ERR(EOVERFLOW);
362aecb2
WT
109 default:
110 return itoa(err);
111 }
112}
113
443de903
TW
114static void putcharn(char c, size_t n)
115{
116 char buf[64];
117
118 memset(buf, c, n);
119 buf[n] = '\0';
120 fputs(buf, stdout);
121}
122
362aecb2
WT
123static int pad_spc(int llen, int cnt, const char *fmt, ...)
124{
125 va_list args;
362aecb2
WT
126 int ret;
127
443de903 128 putcharn(' ', cnt - llen);
362aecb2
WT
129
130 va_start(args, fmt);
131 ret = vfprintf(stdout, fmt, args);
132 va_end(args);
443de903 133 return ret < 0 ? ret : ret + cnt - llen;
362aecb2
WT
134}
135
136/* The tests below are intended to be used by the macroes, which evaluate
137 * expression <expr>, print the status to stdout, and update the "ret"
138 * variable to count failures. The functions themselves return the number
139 * of failures, thus either 0 or 1.
140 */
141
142#define EXPECT_ZR(cond, expr) \
a0994fb9 143 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)
362aecb2
WT
144
145static int expect_zr(int expr, int llen)
146{
147 int ret = !(expr == 0);
148
149 llen += printf(" = %d ", expr);
a0994fb9 150 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
151 return ret;
152}
153
154
155#define EXPECT_NZ(cond, expr, val) \
a0994fb9 156 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)
362aecb2
WT
157
158static int expect_nz(int expr, int llen)
159{
160 int ret = !(expr != 0);
161
162 llen += printf(" = %d ", expr);
a0994fb9 163 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
164 return ret;
165}
166
167
168#define EXPECT_EQ(cond, expr, val) \
a0994fb9 169 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)
362aecb2 170
a0994fb9 171static int expect_eq(uint64_t expr, int llen, uint64_t val)
362aecb2
WT
172{
173 int ret = !(expr == val);
174
0858aec4 175 llen += printf(" = %lld ", (long long)expr);
a0994fb9 176 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
177 return ret;
178}
179
180
181#define EXPECT_NE(cond, expr, val) \
a0994fb9 182 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)
362aecb2
WT
183
184static int expect_ne(int expr, int llen, int val)
185{
186 int ret = !(expr != val);
187
188 llen += printf(" = %d ", expr);
a0994fb9 189 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
190 return ret;
191}
192
193
194#define EXPECT_GE(cond, expr, val) \
a0994fb9 195 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)
362aecb2
WT
196
197static int expect_ge(int expr, int llen, int val)
198{
199 int ret = !(expr >= val);
200
201 llen += printf(" = %d ", expr);
a0994fb9 202 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
203 return ret;
204}
205
206
207#define EXPECT_GT(cond, expr, val) \
a0994fb9 208 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)
362aecb2
WT
209
210static int expect_gt(int expr, int llen, int val)
211{
212 int ret = !(expr > val);
213
214 llen += printf(" = %d ", expr);
a0994fb9 215 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
216 return ret;
217}
218
219
220#define EXPECT_LE(cond, expr, val) \
a0994fb9 221 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)
362aecb2
WT
222
223static int expect_le(int expr, int llen, int val)
224{
225 int ret = !(expr <= val);
226
227 llen += printf(" = %d ", expr);
a0994fb9 228 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
229 return ret;
230}
231
232
233#define EXPECT_LT(cond, expr, val) \
a0994fb9 234 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)
362aecb2
WT
235
236static int expect_lt(int expr, int llen, int val)
237{
238 int ret = !(expr < val);
239
240 llen += printf(" = %d ", expr);
a0994fb9 241 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
362aecb2
WT
242 return ret;
243}
244
245
246#define EXPECT_SYSZR(cond, expr) \
a0994fb9 247 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)
362aecb2
WT
248
249static int expect_syszr(int expr, int llen)
250{
251 int ret = 0;
252
253 if (expr) {
254 ret = 1;
255 llen += printf(" = %d %s ", expr, errorname(errno));
a0994fb9 256 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2
WT
257 } else {
258 llen += printf(" = %d ", expr);
a0994fb9 259 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
260 }
261 return ret;
262}
263
264
265#define EXPECT_SYSEQ(cond, expr, val) \
a0994fb9 266 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)
362aecb2
WT
267
268static int expect_syseq(int expr, int llen, int val)
269{
270 int ret = 0;
271
272 if (expr != val) {
273 ret = 1;
274 llen += printf(" = %d %s ", expr, errorname(errno));
a0994fb9 275 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2
WT
276 } else {
277 llen += printf(" = %d ", expr);
a0994fb9 278 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
279 }
280 return ret;
281}
282
283
284#define EXPECT_SYSNE(cond, expr, val) \
a0994fb9 285 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)
362aecb2
WT
286
287static int expect_sysne(int expr, int llen, int val)
288{
289 int ret = 0;
290
291 if (expr == val) {
292 ret = 1;
293 llen += printf(" = %d %s ", expr, errorname(errno));
a0994fb9 294 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2
WT
295 } else {
296 llen += printf(" = %d ", expr);
a0994fb9 297 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
298 }
299 return ret;
300}
301
302
303#define EXPECT_SYSER(cond, expr, expret, experr) \
a0994fb9 304 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)
362aecb2
WT
305
306static int expect_syserr(int expr, int expret, int experr, int llen)
307{
308 int ret = 0;
309 int _errno = errno;
310
311 llen += printf(" = %d %s ", expr, errorname(_errno));
312 if (expr != expret || _errno != experr) {
313 ret = 1;
314 llen += printf(" != (%d %s) ", expret, errorname(experr));
a0994fb9 315 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 316 } else {
a0994fb9 317 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
318 }
319 return ret;
320}
321
322
323#define EXPECT_PTRZR(cond, expr) \
a0994fb9 324 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)
362aecb2
WT
325
326static int expect_ptrzr(const void *expr, int llen)
327{
328 int ret = 0;
329
330 llen += printf(" = <%p> ", expr);
331 if (expr) {
332 ret = 1;
a0994fb9 333 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 334 } else {
a0994fb9 335 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
336 }
337 return ret;
338}
339
340
341#define EXPECT_PTRNZ(cond, expr) \
a0994fb9 342 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)
362aecb2
WT
343
344static int expect_ptrnz(const void *expr, int llen)
345{
346 int ret = 0;
347
348 llen += printf(" = <%p> ", expr);
349 if (!expr) {
350 ret = 1;
a0994fb9 351 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 352 } else {
a0994fb9 353 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
354 }
355 return ret;
356}
357
358
359#define EXPECT_STRZR(cond, expr) \
a0994fb9 360 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
362aecb2
WT
361
362static int expect_strzr(const char *expr, int llen)
363{
364 int ret = 0;
365
366 llen += printf(" = <%s> ", expr);
367 if (expr) {
368 ret = 1;
a0994fb9 369 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 370 } else {
a0994fb9 371 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
372 }
373 return ret;
374}
375
376
377#define EXPECT_STRNZ(cond, expr) \
a0994fb9 378 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)
362aecb2
WT
379
380static int expect_strnz(const char *expr, int llen)
381{
382 int ret = 0;
383
384 llen += printf(" = <%s> ", expr);
385 if (!expr) {
386 ret = 1;
a0994fb9 387 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 388 } else {
a0994fb9 389 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
390 }
391 return ret;
392}
393
394
395#define EXPECT_STREQ(cond, expr, cmp) \
a0994fb9 396 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)
362aecb2
WT
397
398static int expect_streq(const char *expr, int llen, const char *cmp)
399{
400 int ret = 0;
401
402 llen += printf(" = <%s> ", expr);
403 if (strcmp(expr, cmp) != 0) {
404 ret = 1;
a0994fb9 405 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 406 } else {
a0994fb9 407 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
408 }
409 return ret;
410}
411
412
413#define EXPECT_STRNE(cond, expr, cmp) \
a0994fb9 414 do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)
362aecb2
WT
415
416static int expect_strne(const char *expr, int llen, const char *cmp)
417{
418 int ret = 0;
419
420 llen += printf(" = <%s> ", expr);
421 if (strcmp(expr, cmp) == 0) {
422 ret = 1;
a0994fb9 423 llen += pad_spc(llen, 64, "[FAIL]\n");
362aecb2 424 } else {
a0994fb9 425 llen += pad_spc(llen, 64, " [OK]\n");
362aecb2
WT
426 }
427 return ret;
428}
429
23da7bc9 430
362aecb2
WT
431/* declare tests based on line numbers. There must be exactly one test per line. */
432#define CASE_TEST(name) \
433 case __LINE__: llen += printf("%d %s", test, #name);
434
435
b4844fa0
WT
436/* used by some syscall tests below */
437int test_getdents64(const char *dir)
438{
439 char buffer[4096];
440 int fd, ret;
441 int err;
442
443 ret = fd = open(dir, O_RDONLY | O_DIRECTORY, 0);
444 if (ret < 0)
445 return ret;
446
447 ret = getdents64(fd, (void *)buffer, sizeof(buffer));
448 err = errno;
449 close(fd);
450
451 errno = err;
452 return ret;
453}
454
a290296a
AF
455static int test_getpagesize(void)
456{
457 long x = getpagesize();
458 int c;
459
460 if (x < 0)
461 return x;
462
463#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
464 /*
465 * x86 family is always 4K page.
466 */
467 c = (x == 4096);
468#elif defined(__aarch64__)
469 /*
470 * Linux aarch64 supports three values of page size: 4K, 16K, and 64K
471 * which are selected at kernel compilation time.
472 */
473 c = (x == 4096 || x == (16 * 1024) || x == (64 * 1024));
474#else
475 /*
476 * Assuming other architectures must have at least 4K page.
477 */
478 c = (x >= 4096);
479#endif
480
481 return !c;
482}
483
3ad09d72
TW
484static int test_fork(void)
485{
486 int status;
ed495f09
ZW
487 pid_t pid;
488
489 /* flush the printf buffer to avoid child flush it */
490 fflush(stdout);
491 fflush(stderr);
492
493 pid = fork();
3ad09d72
TW
494
495 switch (pid) {
496 case -1:
497 return 1;
498
499 case 0:
500 exit(123);
501
502 default:
503 pid = waitpid(pid, &status, 0);
504
505 return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123;
506 }
507}
508
87b9fa66
TW
509static int test_stat_timestamps(void)
510{
511 struct stat st;
512
513 if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime))
514 return 1;
515
516 if (stat("/proc/self/", &st))
517 return 1;
518
519 if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000)
520 return 1;
521
522 if (st.st_mtim.tv_sec != st.st_mtime || st.st_mtim.tv_nsec > 1000000000)
523 return 1;
524
525 if (st.st_ctim.tv_sec != st.st_ctime || st.st_ctim.tv_nsec > 1000000000)
526 return 1;
527
528 return 0;
529}
530
b4844fa0
WT
531/* Run syscall tests between IDs <min> and <max>.
532 * Return 0 on success, non-zero on failure.
533 */
534int run_syscall(int min, int max)
535{
536 struct stat stat_buf;
3e2d337b 537 int euid0;
7172f1c6 538 int proc;
b4844fa0
WT
539 int test;
540 int tmp;
541 int ret = 0;
542 void *p1, *p2;
543
7172f1c6
WT
544 /* <proc> indicates whether or not /proc is mounted */
545 proc = stat("/proc", &stat_buf) == 0;
546
3e2d337b
WT
547 /* this will be used to skip certain tests that can't be run unprivileged */
548 euid0 = geteuid() == 0;
549
b4844fa0 550 for (test = min; test >= 0 && test <= max; test++) {
fddc8f81 551 int llen = 0; /* line length */
b4844fa0
WT
552
553 /* avoid leaving empty lines below, this will insert holes into
554 * test numbers.
555 */
556 switch (test + __LINE__ + 1) {
557 CASE_TEST(getpid); EXPECT_SYSNE(1, getpid(), -1); break;
558 CASE_TEST(getppid); EXPECT_SYSNE(1, getppid(), -1); break;
1da02f51 559#ifdef NOLIBC
b4844fa0 560 CASE_TEST(gettid); EXPECT_SYSNE(1, gettid(), -1); break;
1da02f51 561#endif
b4844fa0
WT
562 CASE_TEST(getpgid_self); EXPECT_SYSNE(1, getpgid(0), -1); break;
563 CASE_TEST(getpgid_bad); EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;
564 CASE_TEST(kill_0); EXPECT_SYSZR(1, kill(getpid(), 0)); break;
565 CASE_TEST(kill_CONT); EXPECT_SYSZR(1, kill(getpid(), 0)); break;
566 CASE_TEST(kill_BADPID); EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;
567 CASE_TEST(sbrk); if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(1, (p2 == (void *)-1) || p2 == p1); break;
568 CASE_TEST(brk); EXPECT_SYSZR(1, brk(sbrk(0))); break;
569 CASE_TEST(chdir_root); EXPECT_SYSZR(1, chdir("/")); break;
570 CASE_TEST(chdir_dot); EXPECT_SYSZR(1, chdir(".")); break;
571 CASE_TEST(chdir_blah); EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;
7172f1c6
WT
572 CASE_TEST(chmod_net); EXPECT_SYSZR(proc, chmod("/proc/self/net", 0555)); break;
573 CASE_TEST(chmod_self); EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
574 CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
3e2d337b 575 CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break;
b4844fa0 576 CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
7172f1c6 577 CASE_TEST(chroot_exe); EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
b4844fa0
WT
578 CASE_TEST(close_m1); EXPECT_SYSER(1, close(-1), -1, EBADF); break;
579 CASE_TEST(close_dup); EXPECT_SYSZR(1, close(dup(0))); break;
580 CASE_TEST(dup_0); tmp = dup(0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
581 CASE_TEST(dup_m1); tmp = dup(-1); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
582 CASE_TEST(dup2_0); tmp = dup2(0, 100); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
583 CASE_TEST(dup2_m1); tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
584 CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
585 CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
586 CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;
3ad09d72 587 CASE_TEST(fork); EXPECT_SYSZR(1, test_fork()); break;
b4844fa0
WT
588 CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
589 CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
1da02f51 590#ifdef NOLIBC
b4844fa0
WT
591 CASE_TEST(gettimeofday_bad1); EXPECT_SYSER(1, gettimeofday((void *)1, NULL), -1, EFAULT); break;
592 CASE_TEST(gettimeofday_bad2); EXPECT_SYSER(1, gettimeofday(NULL, (void *)1), -1, EFAULT); break;
1da02f51 593#endif
a290296a 594 CASE_TEST(getpagesize); EXPECT_SYSZR(1, test_getpagesize()); break;
b4844fa0
WT
595 CASE_TEST(ioctl_tiocinq); EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
596 CASE_TEST(ioctl_tiocinq); EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
597 CASE_TEST(link_root1); EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
598 CASE_TEST(link_blah); EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;
3e2d337b 599 CASE_TEST(link_dir); EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;
7172f1c6 600 CASE_TEST(link_cross); EXPECT_SYSER(proc, link("/proc/self/net", "/blah"), -1, EXDEV); break;
b4844fa0
WT
601 CASE_TEST(lseek_m1); EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
602 CASE_TEST(lseek_0); EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
603 CASE_TEST(mkdir_root); EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
604 CASE_TEST(open_tty); EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
605 CASE_TEST(open_blah); EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
606 CASE_TEST(poll_null); EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
607 CASE_TEST(poll_stdout); EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;
608 CASE_TEST(poll_fault); EXPECT_SYSER(1, poll((void *)1, 1, 0), -1, EFAULT); break;
208aa9d9 609 CASE_TEST(prctl); EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
b4844fa0
WT
610 CASE_TEST(read_badf); EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
611 CASE_TEST(sched_yield); EXPECT_SYSZR(1, sched_yield()); break;
612 CASE_TEST(select_null); EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break;
613 CASE_TEST(select_stdout); EXPECT_SYSNE(1, ({ fd_set fds; FD_ZERO(&fds); FD_SET(1, &fds); select(2, NULL, &fds, NULL, NULL); }), -1); break;
614 CASE_TEST(select_fault); EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
615 CASE_TEST(stat_blah); EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
616 CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
87b9fa66 617 CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break;
b4844fa0
WT
618 CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
619 CASE_TEST(unlink_root); EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
620 CASE_TEST(unlink_blah); EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;
621 CASE_TEST(wait_child); EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;
622 CASE_TEST(waitpid_min); EXPECT_SYSER(1, waitpid(INT_MIN, &tmp, WNOHANG), -1, ESRCH); break;
623 CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
624 CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
625 CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
53fcfafa 626 CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;
ec8e1b73 627 CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;
b4844fa0
WT
628 case __LINE__:
629 return ret; /* must be last */
630 /* note: do not set any defaults so as to permit holes above */
631 }
632 }
633 return ret;
634}
635
95bc9894
WT
636int run_stdlib(int min, int max)
637{
638 int test;
639 int tmp;
640 int ret = 0;
641 void *p1, *p2;
642
643 for (test = min; test >= 0 && test <= max; test++) {
fddc8f81 644 int llen = 0; /* line length */
95bc9894
WT
645
646 /* avoid leaving empty lines below, this will insert holes into
647 * test numbers.
648 */
649 switch (test + __LINE__ + 1) {
650 CASE_TEST(getenv_TERM); EXPECT_STRNZ(1, getenv("TERM")); break;
651 CASE_TEST(getenv_blah); EXPECT_STRZR(1, getenv("blah")); break;
652 CASE_TEST(setcmp_blah_blah); EXPECT_EQ(1, strcmp("blah", "blah"), 0); break;
653 CASE_TEST(setcmp_blah_blah2); EXPECT_NE(1, strcmp("blah", "blah2"), 0); break;
654 CASE_TEST(setncmp_blah_blah); EXPECT_EQ(1, strncmp("blah", "blah", 10), 0); break;
655 CASE_TEST(setncmp_blah_blah4); EXPECT_EQ(1, strncmp("blah", "blah4", 4), 0); break;
656 CASE_TEST(setncmp_blah_blah5); EXPECT_NE(1, strncmp("blah", "blah5", 5), 0); break;
657 CASE_TEST(setncmp_blah_blah6); EXPECT_NE(1, strncmp("blah", "blah6", 6), 0); break;
658 CASE_TEST(strchr_foobar_o); EXPECT_STREQ(1, strchr("foobar", 'o'), "oobar"); break;
659 CASE_TEST(strchr_foobar_z); EXPECT_STRZR(1, strchr("foobar", 'z')); break;
660 CASE_TEST(strrchr_foobar_o); EXPECT_STREQ(1, strrchr("foobar", 'o'), "obar"); break;
661 CASE_TEST(strrchr_foobar_z); EXPECT_STRZR(1, strrchr("foobar", 'z')); break;
c80b5a0a
WT
662 CASE_TEST(memcmp_20_20); EXPECT_EQ(1, memcmp("aaa\x20", "aaa\x20", 4), 0); break;
663 CASE_TEST(memcmp_20_60); EXPECT_LT(1, memcmp("aaa\x20", "aaa\x60", 4), 0); break;
664 CASE_TEST(memcmp_60_20); EXPECT_GT(1, memcmp("aaa\x60", "aaa\x20", 4), 0); break;
665 CASE_TEST(memcmp_20_e0); EXPECT_LT(1, memcmp("aaa\x20", "aaa\xe0", 4), 0); break;
666 CASE_TEST(memcmp_e0_20); EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break;
667 CASE_TEST(memcmp_80_e0); EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break;
668 CASE_TEST(memcmp_e0_80); EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break;
d1209597
VD
669 CASE_TEST(limit_int8_max); EXPECT_EQ(1, INT8_MAX, (int8_t) 0x7f); break;
670 CASE_TEST(limit_int8_min); EXPECT_EQ(1, INT8_MIN, (int8_t) 0x80); break;
671 CASE_TEST(limit_uint8_max); EXPECT_EQ(1, UINT8_MAX, (uint8_t) 0xff); break;
672 CASE_TEST(limit_int16_max); EXPECT_EQ(1, INT16_MAX, (int16_t) 0x7fff); break;
673 CASE_TEST(limit_int16_min); EXPECT_EQ(1, INT16_MIN, (int16_t) 0x8000); break;
674 CASE_TEST(limit_uint16_max); EXPECT_EQ(1, UINT16_MAX, (uint16_t) 0xffff); break;
675 CASE_TEST(limit_int32_max); EXPECT_EQ(1, INT32_MAX, (int32_t) 0x7fffffff); break;
676 CASE_TEST(limit_int32_min); EXPECT_EQ(1, INT32_MIN, (int32_t) 0x80000000); break;
677 CASE_TEST(limit_uint32_max); EXPECT_EQ(1, UINT32_MAX, (uint32_t) 0xffffffff); break;
678 CASE_TEST(limit_int64_max); EXPECT_EQ(1, INT64_MAX, (int64_t) 0x7fffffffffffffff); break;
679 CASE_TEST(limit_int64_min); EXPECT_EQ(1, INT64_MIN, (int64_t) 0x8000000000000000); break;
680 CASE_TEST(limit_uint64_max); EXPECT_EQ(1, UINT64_MAX, (uint64_t) 0xffffffffffffffff); break;
681 CASE_TEST(limit_int_least8_max); EXPECT_EQ(1, INT_LEAST8_MAX, (int_least8_t) 0x7f); break;
682 CASE_TEST(limit_int_least8_min); EXPECT_EQ(1, INT_LEAST8_MIN, (int_least8_t) 0x80); break;
683 CASE_TEST(limit_uint_least8_max); EXPECT_EQ(1, UINT_LEAST8_MAX, (uint_least8_t) 0xff); break;
684 CASE_TEST(limit_int_least16_max); EXPECT_EQ(1, INT_LEAST16_MAX, (int_least16_t) 0x7fff); break;
685 CASE_TEST(limit_int_least16_min); EXPECT_EQ(1, INT_LEAST16_MIN, (int_least16_t) 0x8000); break;
686 CASE_TEST(limit_uint_least16_max); EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t) 0xffff); break;
687 CASE_TEST(limit_int_least32_max); EXPECT_EQ(1, INT_LEAST32_MAX, (int_least32_t) 0x7fffffff); break;
688 CASE_TEST(limit_int_least32_min); EXPECT_EQ(1, INT_LEAST32_MIN, (int_least32_t) 0x80000000); break;
689 CASE_TEST(limit_uint_least32_max); EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t) 0xffffffffU); break;
690 CASE_TEST(limit_int_least64_min); EXPECT_EQ(1, INT_LEAST64_MIN, (int_least64_t) 0x8000000000000000LL); break;
691 CASE_TEST(limit_int_least64_max); EXPECT_EQ(1, INT_LEAST64_MAX, (int_least64_t) 0x7fffffffffffffffLL); break;
692 CASE_TEST(limit_uint_least64_max); EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t) 0xffffffffffffffffULL); break;
693 CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
694 CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
695 CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
696 CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) INTPTR_MIN); break;
697 CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) INTPTR_MAX); break;
698 CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) UINTPTR_MAX); break;
699 CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) INTPTR_MIN); break;
700 CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) INTPTR_MAX); break;
701 CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) UINTPTR_MAX); break;
f9bf5944
TW
702 CASE_TEST(limit_int_fast64_min); EXPECT_EQ(1, INT_FAST64_MIN, (int_fast64_t) INT64_MIN); break;
703 CASE_TEST(limit_int_fast64_max); EXPECT_EQ(1, INT_FAST64_MAX, (int_fast64_t) INT64_MAX); break;
704 CASE_TEST(limit_uint_fast64_max); EXPECT_EQ(1, UINT_FAST64_MAX, (uint_fast64_t) UINT64_MAX); break;
d1209597
VD
705#if __SIZEOF_LONG__ == 8
706 CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x8000000000000000LL); break;
707 CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffffffffffffLL); break;
708 CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffffffffffULL); break;
709 CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x8000000000000000LL); break;
710 CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffffffffffffLL); break;
711 CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffffffffffULL); break;
712#elif __SIZEOF_LONG__ == 4
713 CASE_TEST(limit_intptr_min); EXPECT_EQ(1, INTPTR_MIN, (intptr_t) 0x80000000); break;
714 CASE_TEST(limit_intptr_max); EXPECT_EQ(1, INTPTR_MAX, (intptr_t) 0x7fffffff); break;
715 CASE_TEST(limit_uintptr_max); EXPECT_EQ(1, UINTPTR_MAX, (uintptr_t) 0xffffffffU); break;
716 CASE_TEST(limit_ptrdiff_min); EXPECT_EQ(1, PTRDIFF_MIN, (ptrdiff_t) 0x80000000); break;
717 CASE_TEST(limit_ptrdiff_max); EXPECT_EQ(1, PTRDIFF_MAX, (ptrdiff_t) 0x7fffffff); break;
718 CASE_TEST(limit_size_max); EXPECT_EQ(1, SIZE_MAX, (size_t) 0xffffffffU); break;
719#else
720# warning "__SIZEOF_LONG__ is undefined"
721#endif /* __SIZEOF_LONG__ */
95bc9894
WT
722 case __LINE__:
723 return ret; /* must be last */
724 /* note: do not set any defaults so as to permit holes above */
725 }
726 }
727 return ret;
728}
729
69f2cd9f
TW
730#define EXPECT_VFPRINTF(c, expected, fmt, ...) \
731 ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__)
732
733static int expect_vfprintf(int llen, size_t c, const char *expected, const char *fmt, ...)
734{
735 int ret, fd, w, r;
736 char buf[100];
737 FILE *memfile;
738 va_list args;
739
740 fd = memfd_create("vfprintf", 0);
741 if (fd == -1) {
742 pad_spc(llen, 64, "[FAIL]\n");
743 return 1;
744 }
745
746 memfile = fdopen(fd, "w+");
747 if (!memfile) {
748 pad_spc(llen, 64, "[FAIL]\n");
749 return 1;
750 }
751
752 va_start(args, fmt);
753 w = vfprintf(memfile, fmt, args);
754 va_end(args);
755
756 if (w != c) {
757 llen += printf(" written(%d) != %d", w, (int) c);
758 pad_spc(llen, 64, "[FAIL]\n");
759 return 1;
760 }
761
762 fflush(memfile);
763 lseek(fd, 0, SEEK_SET);
764
765 r = read(fd, buf, sizeof(buf) - 1);
766 buf[r] = '\0';
767
768 fclose(memfile);
769
770 if (r != w) {
771 llen += printf(" written(%d) != read(%d)", w, r);
772 pad_spc(llen, 64, "[FAIL]\n");
773 return 1;
774 }
775
776 llen += printf(" \"%s\" = \"%s\"", expected, buf);
777 ret = strncmp(expected, buf, c);
778
779 pad_spc(llen, 64, ret ? "[FAIL]\n" : " [OK]\n");
780 return ret;
781}
782
783static int run_vfprintf(int min, int max)
784{
785 int test;
786 int tmp;
787 int ret = 0;
788 void *p1, *p2;
789
790 for (test = min; test >= 0 && test <= max; test++) {
fddc8f81 791 int llen = 0; /* line length */
69f2cd9f
TW
792
793 /* avoid leaving empty lines below, this will insert holes into
794 * test numbers.
795 */
796 switch (test + __LINE__ + 1) {
797 CASE_TEST(empty); EXPECT_VFPRINTF(0, "", ""); break;
798 CASE_TEST(simple); EXPECT_VFPRINTF(3, "foo", "foo"); break;
799 CASE_TEST(string); EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break;
800 CASE_TEST(number); EXPECT_VFPRINTF(4, "1234", "%d", 1234); break;
801 CASE_TEST(negnumber); EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break;
802 CASE_TEST(unsigned); EXPECT_VFPRINTF(5, "12345", "%u", 12345); break;
803 CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break;
804 CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break;
805 CASE_TEST(pointer); EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break;
806 case __LINE__:
807 return ret; /* must be last */
808 /* note: do not set any defaults so as to permit holes above */
809 }
810 }
811 return ret;
812}
813
97357168
TW
814static int smash_stack(void)
815{
816 char buf[100];
e7654c3f 817 volatile char *ptr = buf;
aa662d12 818 size_t i;
97357168 819
aa662d12 820 for (i = 0; i < 200; i++)
e7654c3f 821 ptr[i] = 'P';
97357168
TW
822
823 return 1;
824}
825
826static int run_protection(int min, int max)
827{
828 pid_t pid;
829 int llen = 0, status;
830
831 llen += printf("0 -fstackprotector ");
832
818924d1 833#if !defined(_NOLIBC_STACKPROTECTOR)
97357168
TW
834 llen += printf("not supported");
835 pad_spc(llen, 64, "[SKIPPED]\n");
836 return 0;
837#endif
838
818924d1 839#if defined(_NOLIBC_STACKPROTECTOR)
85250921
TW
840 if (!__stack_chk_guard) {
841 llen += printf("__stack_chk_guard not initialized");
842 pad_spc(llen, 64, "[FAIL]\n");
843 return 1;
844 }
845#endif
846
97357168
TW
847 pid = -1;
848 pid = fork();
849
850 switch (pid) {
851 case -1:
852 llen += printf("fork()");
853 pad_spc(llen, 64, "[FAIL]\n");
854 return 1;
855
856 case 0:
857 close(STDOUT_FILENO);
858 close(STDERR_FILENO);
859
9a75575b 860 prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
97357168
TW
861 smash_stack();
862 return 1;
863
864 default:
865 pid = waitpid(pid, &status, 0);
866
867 if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
868 llen += printf("waitpid()");
869 pad_spc(llen, 64, "[FAIL]\n");
870 return 1;
871 }
872 pad_spc(llen, 64, " [OK]\n");
873 return 0;
874 }
875}
876
1a5454f6
WT
877/* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
878int prepare(void)
879{
880 struct stat stat_buf;
881
882 /* It's possible that /dev doesn't even exist or was not mounted, so
883 * we'll try to create it, mount it, or create minimal entries into it.
884 * We want at least /dev/null and /dev/console.
885 */
886 if (stat("/dev/.", &stat_buf) == 0 || mkdir("/dev", 0755) == 0) {
887 if (stat("/dev/console", &stat_buf) != 0 ||
888 stat("/dev/null", &stat_buf) != 0) {
889 /* try devtmpfs first, otherwise fall back to manual creation */
890 if (mount("/dev", "/dev", "devtmpfs", 0, 0) != 0) {
891 mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1));
892 mknod("/dev/null", 0666 | S_IFCHR, makedev(1, 3));
893 }
894 }
895 }
896
897 /* If no /dev/console was found before calling init, stdio is closed so
898 * we need to reopen it from /dev/console. If it failed above, it will
899 * still fail here and we cannot emit a message anyway.
900 */
901 if (close(dup(1)) == -1) {
902 int fd = open("/dev/console", O_RDWR);
903
904 if (fd >= 0) {
905 if (fd != 0)
906 dup2(fd, 0);
907 if (fd != 1)
908 dup2(fd, 1);
909 if (fd != 2)
910 dup2(fd, 2);
911 if (fd > 2)
912 close(fd);
913 puts("\nSuccessfully reopened /dev/console.");
914 }
915 }
916
917 /* try to mount /proc if not mounted. Silently fail otherwise */
918 if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) {
919 if (stat("/proc/self", &stat_buf) != 0)
920 mount("/proc", "/proc", "proc", 0, 0);
921 }
922
923 return 0;
924}
b4844fa0 925
23da7bc9 926/* This is the definition of known test names, with their functions */
c4560bd8 927static const struct test test_names[] = {
23da7bc9 928 /* add new tests here */
97357168
TW
929 { .name = "syscall", .func = run_syscall },
930 { .name = "stdlib", .func = run_stdlib },
69f2cd9f 931 { .name = "vfprintf", .func = run_vfprintf },
97357168 932 { .name = "protection", .func = run_protection },
23da7bc9
WT
933 { 0 }
934};
935
362aecb2
WT
936int main(int argc, char **argv, char **envp)
937{
938 int min = 0;
939 int max = __INT_MAX__;
940 int ret = 0;
23da7bc9
WT
941 int err;
942 int idx;
943 char *test;
362aecb2
WT
944
945 environ = envp;
946
1a5454f6
WT
947 /* when called as init, it's possible that no console was opened, for
948 * example if no /dev file system was provided. We'll check that fd#1
949 * was opened, and if not we'll attempt to create and open /dev/console
950 * and /dev/null that we'll use for later tests.
951 */
952 if (getpid() == 1)
953 prepare();
954
23da7bc9
WT
955 /* the definition of a series of tests comes from either argv[1] or the
956 * "NOLIBC_TEST" environment variable. It's made of a comma-delimited
957 * series of test names and optional ranges:
958 * syscall:5-15[:.*],stdlib:8-10
959 */
960 test = argv[1];
961 if (!test)
962 test = getenv("NOLIBC_TEST");
963
964 if (test) {
965 char *comma, *colon, *dash, *value;
966
967 do {
968 comma = strchr(test, ',');
969 if (comma)
970 *(comma++) = '\0';
971
972 colon = strchr(test, ':');
973 if (colon)
974 *(colon++) = '\0';
975
976 for (idx = 0; test_names[idx].name; idx++) {
977 if (strcmp(test, test_names[idx].name) == 0)
978 break;
979 }
980
981 if (test_names[idx].name) {
982 /* The test was named, it will be called at least
983 * once. We may have an optional range at <colon>
984 * here, which defaults to the full range.
985 */
986 do {
987 min = 0; max = __INT_MAX__;
988 value = colon;
989 if (value && *value) {
990 colon = strchr(value, ':');
991 if (colon)
992 *(colon++) = '\0';
993
994 dash = strchr(value, '-');
995 if (dash)
996 *(dash++) = '\0';
997
998 /* support :val: :min-max: :min-: :-max: */
999 if (*value)
1000 min = atoi(value);
1001 if (!dash)
1002 max = min;
1003 else if (*dash)
1004 max = atoi(dash);
1005
1006 value = colon;
1007 }
1008
1009 /* now's time to call the test */
1010 printf("Running test '%s'\n", test_names[idx].name);
1011 err = test_names[idx].func(min, max);
1012 ret += err;
1013 printf("Errors during this test: %d\n\n", err);
1014 } while (colon && *colon);
1015 } else
1016 printf("Ignoring unknown test name '%s'\n", test);
1017
1018 test = comma;
1019 } while (test && *test);
1020 } else {
1021 /* no test mentioned, run everything */
1022 for (idx = 0; test_names[idx].name; idx++) {
1023 printf("Running test '%s'\n", test_names[idx].name);
1024 err = test_names[idx].func(min, max);
1025 ret += err;
1026 printf("Errors during this test: %d\n\n", err);
1027 }
1028 }
1029
362aecb2 1030 printf("Total number of errors: %d\n", ret);
f49896d7
WT
1031
1032 if (getpid() == 1) {
1033 /* we're running as init, there's no other process on the
1034 * system, thus likely started from a VM for a quick check.
1035 * Exiting will provoke a kernel panic that may be reported
1036 * as an error by Qemu or the hypervisor, while stopping
1037 * cleanly will often be reported as a success. This allows
1038 * to use the output of this program for bisecting kernels.
1039 */
1040 printf("Leaving init with final status: %d\n", !!ret);
1041 if (ret == 0)
1042 reboot(LINUX_REBOOT_CMD_POWER_OFF);
aa73a86c
WT
1043#if defined(__x86_64__)
1044 /* QEMU started with "-device isa-debug-exit -no-reboot" will
1045 * exit with status code 2N+1 when N is written to 0x501. We
1046 * hard-code the syscall here as it's arch-dependent.
1047 */
1da02f51 1048#if defined(_NOLIBC_SYS_H)
aa73a86c 1049 else if (my_syscall3(__NR_ioperm, 0x501, 1, 1) == 0)
1da02f51
WT
1050#else
1051 else if (ioperm(0x501, 1, 1) == 0)
1052#endif
7f291cfa 1053 __asm__ volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0));
aa73a86c
WT
1054 /* if it does nothing, fall back to the regular panic */
1055#endif
f49896d7
WT
1056 }
1057
362aecb2
WT
1058 printf("Exiting with status %d\n", !!ret);
1059 return !!ret;
1060}