1*340aa6c7Santon /* $OpenBSD: vnode.c,v 1.3 2020/12/03 19:16:57 anton Exp $ */
261af947aSbluhm
3df8370aeSanton /*
4df8370aeSanton * Copyright (c) 2020 Anton Lindqvist <anton@openbsd.org>
5df8370aeSanton *
6df8370aeSanton * Permission to use, copy, modify, and distribute this software for any
7df8370aeSanton * purpose with or without fee is hereby granted, provided that the above
8df8370aeSanton * copyright notice and this permission notice appear in all copies.
9df8370aeSanton *
10df8370aeSanton * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11df8370aeSanton * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12df8370aeSanton * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13df8370aeSanton * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14df8370aeSanton * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15df8370aeSanton * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16df8370aeSanton * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17df8370aeSanton */
18df8370aeSanton
19df8370aeSanton #include <err.h>
20*340aa6c7Santon #include <errno.h>
21df8370aeSanton #include <signal.h>
22*340aa6c7Santon #include <stdarg.h>
23df8370aeSanton #include <stdio.h>
24df8370aeSanton #include <stdlib.h>
25df8370aeSanton #include <string.h>
26df8370aeSanton #include <unistd.h>
27df8370aeSanton
28*340aa6c7Santon #include "extern.h"
29df8370aeSanton
30df8370aeSanton static void sighandler(int);
31df8370aeSanton static void __dead usage(void);
32df8370aeSanton
33*340aa6c7Santon int loglevel = 0;
34df8370aeSanton
35*340aa6c7Santon static int gotsig;
36*340aa6c7Santon
37df8370aeSanton int
main(int argc,char * argv[])38df8370aeSanton main(int argc, char *argv[])
39df8370aeSanton {
40*340aa6c7Santon struct {
41*340aa6c7Santon const char *t_name;
42*340aa6c7Santon int (*t_func)(struct context *);
43*340aa6c7Santon } tests[] = {
44*340aa6c7Santon { "deadlock", test_deadlock },
45df8370aeSanton
46*340aa6c7Santon { NULL, NULL },
47*340aa6c7Santon };
48*340aa6c7Santon struct context ctx;
49*340aa6c7Santon int ch, i;
50*340aa6c7Santon
51*340aa6c7Santon memset(&ctx, 0, sizeof(ctx));
52*340aa6c7Santon ctx.c_iterations = 100;
53*340aa6c7Santon
54*340aa6c7Santon while ((ch = getopt(argc, argv, "If:v")) != -1) {
55df8370aeSanton switch (ch) {
56df8370aeSanton case 'I':
57*340aa6c7Santon ctx.c_iterations = -1;
58*340aa6c7Santon break;
59*340aa6c7Santon case 'f':
60*340aa6c7Santon ctx.c_path = optarg;
61*340aa6c7Santon break;
62*340aa6c7Santon case 'v':
63*340aa6c7Santon loglevel++;
64df8370aeSanton break;
65df8370aeSanton default:
66df8370aeSanton usage();
67df8370aeSanton }
68df8370aeSanton }
69df8370aeSanton argc -= optind;
70df8370aeSanton argv += optind;
71*340aa6c7Santon if (argc != 1 || ctx.c_path == NULL)
72df8370aeSanton usage();
73df8370aeSanton
74df8370aeSanton if (signal(SIGINT, sighandler) == SIG_ERR)
75df8370aeSanton err(1, "signal");
76df8370aeSanton
77*340aa6c7Santon for (i = 0;; i++) {
78*340aa6c7Santon if (tests[i].t_name == NULL)
79*340aa6c7Santon err(1, "%s: no such test", *argv);
80df8370aeSanton
81*340aa6c7Santon if (strcmp(tests[i].t_name, *argv))
82*340aa6c7Santon continue;
83df8370aeSanton
84*340aa6c7Santon return tests[i].t_func(&ctx);
85df8370aeSanton }
86df8370aeSanton
87df8370aeSanton return 0;
88df8370aeSanton }
89df8370aeSanton
90*340aa6c7Santon int
ctx_abort(struct context * ctx)91*340aa6c7Santon ctx_abort(struct context *ctx)
92df8370aeSanton {
93*340aa6c7Santon if (gotsig)
94*340aa6c7Santon return 1;
95*340aa6c7Santon if (ctx->c_iterations > 0 && --ctx->c_iterations == 0)
96*340aa6c7Santon return 1;
97*340aa6c7Santon return 0;
98df8370aeSanton }
99df8370aeSanton
100*340aa6c7Santon void
logit(const char * fmt,...)101*340aa6c7Santon logit(const char *fmt, ...)
102df8370aeSanton {
103*340aa6c7Santon char buf[1024];
104*340aa6c7Santon va_list ap;
105*340aa6c7Santon char *p = buf;
106*340aa6c7Santon ssize_t siz = sizeof(buf);
107*340aa6c7Santon int n;
108df8370aeSanton
109*340aa6c7Santon n = snprintf(p, siz, "[%d] ", getpid());
110*340aa6c7Santon if (n < 0 || n >= siz)
111*340aa6c7Santon errc(1, ENAMETOOLONG, "%s", __func__);
112*340aa6c7Santon p += n;
113*340aa6c7Santon siz -= n;
114df8370aeSanton
115*340aa6c7Santon va_start(ap, fmt);
116*340aa6c7Santon n = vsnprintf(p, siz, fmt, ap);
117*340aa6c7Santon va_end(ap);
118*340aa6c7Santon if (n < 0 || n >= siz)
119*340aa6c7Santon errc(1, ENAMETOOLONG, "%s", __func__);
120*340aa6c7Santon p += n;
121*340aa6c7Santon siz -= n;
122df8370aeSanton
123*340aa6c7Santon fprintf(stderr, "%s\n", buf);
124df8370aeSanton }
125df8370aeSanton
126df8370aeSanton static void
sighandler(int signo)127df8370aeSanton sighandler(int signo)
128df8370aeSanton {
129df8370aeSanton gotsig = signo;
130df8370aeSanton }
131df8370aeSanton
132df8370aeSanton static void __dead
usage(void)133df8370aeSanton usage(void)
134df8370aeSanton {
135*340aa6c7Santon fprintf(stderr, "usage: vnode [-Iv] -f path test-case\n");
136df8370aeSanton exit(1);
137df8370aeSanton }
138