blob: a6a6672281366fb589079fb7a33e294cad0fa314 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 * crash02.c - Test OS robustness by executing syscalls with random args.
3 *
4 * Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
5 *
6 * This test program was inspired from crashme, by GEORGE J. CARRETT.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
Garrett Cooper2c282152010-12-16 00:55:50 -080012 *
plars865695b2001-08-27 22:15:12 +000013 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Garrett Cooper1ffecc92010-12-18 00:03:44 -080015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
plars865695b2001-08-27 22:15:12 +000016 * GNU General Public License for more details.
Garrett Cooper2c282152010-12-16 00:55:50 -080017 *
plars865695b2001-08-27 22:15:12 +000018 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
Garrett Cooper1ffecc92010-12-18 00:03:44 -080020 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
plars865695b2001-08-27 22:15:12 +000021 */
22
23/*
24A signal handler is set up so that in most cases the machine exception
25generated by the illegal syscall, bad operands, etc in the procedure
26made up of random data are caught; and another round of randomness may
27be tried. Eventually a random syscall may corrupt the program or
28the machine state in such a way that the program must halt. This is
29a test of the robustness of the hardware/software for instruction
30fault handling.
31
32Note: Running this program just a few times, using total CPU time of
33less than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
34robustness. Having it run for hours, with tens of thousands of cases
35would be a different thing. It would also make sense to run this
36stress test at the same time you run other tests, like a multi-user
37benchmark.
38
39CAUTION: running this program may crash your system, your disk and all
40 your data along! DO NOT RUN IT ON PRODUCTION SYSTEMS!
41 CONSIDER YOUR DISK FRIED.
42 REMEMBER THE DISCLAIMER PART OF THE LICENSE.
43
44 Running as user nobody and with all your filesystems
45 remounted to readonly may be wise..
46
plars865695b2001-08-27 22:15:12 +000047TODO:
48 * in rand_long(), stuff in some real pointers to random data
49 * Does a syscall is supposed to send SIGSEGV?
50*/
51
subrata_modak1b779092009-05-25 15:27:10 +000052#define _GNU_SOURCE
53#include <sys/syscall.h>
plars865695b2001-08-27 22:15:12 +000054#include <stdio.h>
55#include <stdlib.h>
56#include <string.h>
57#include <signal.h>
58#include <setjmp.h>
59#include <time.h>
60#include <unistd.h>
61#include <errno.h>
62#include <sys/types.h>
63#include <sys/wait.h>
64
65#include "test.h"
plars865695b2001-08-27 22:15:12 +000066
Wanlong Gao354ebb42012-12-07 10:10:04 +080067char *TCID = "crash02";
68int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000069
70static int x_opt = 0;
71static int v_opt = 0;
72static char *v_copt;
73static int s_opt = 0;
74static char *s_copt;
75static int l_opt = 0;
76static char *l_copt;
77static int n_opt = 0;
78static char *n_copt;
79
80int verbose_level = 2;
81
82/* depends on architecture.. */
83unsigned int sysno_max = 127;
84
85int nseed;
86int ntries = 100;
87
88/* max time allowed per try, in seconds */
89#define MAX_TRY_TIME 5
90
plars865695b2001-08-27 22:15:12 +000091void cleanup()
92{
plars865695b2001-08-27 22:15:12 +000093
94 tst_rmdir();
95
plars865695b2001-08-27 22:15:12 +000096}
97
98void setup()
99{
100 /*
101 * setup a default signal hander and a
102 * temporary working directory.
103 */
104 tst_sig(FORK, DEF_HANDLER, cleanup);
105
106 TEST_PAUSE;
107
108 tst_tmpdir();
109}
110
111void help()
112{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800113 printf
114 (" -x dry run, hexdump random code instead\n");
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800115 printf(" -l x max syscall no\n");
116 printf(" -v x verbose level\n");
117 printf(" -s x random seed\n");
118 printf(" -n x ntries\n");
plars865695b2001-08-27 22:15:12 +0000119}
120
121/*
122 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800123option_t options[] = {
124 {"v:", &v_opt, &v_copt},
125 {"l:", &l_opt, &l_copt},
126 {"s:", &s_opt, &s_copt},
127 {"n:", &n_opt, &n_copt},
128 {"x", &x_opt, NULL},
plars865695b2001-08-27 22:15:12 +0000129
Wanlong Gao354ebb42012-12-07 10:10:04 +0800130 {NULL, NULL, NULL}
plars865695b2001-08-27 22:15:12 +0000131};
132
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133void badboy_fork();
134void badboy_loop();
plars865695b2001-08-27 22:15:12 +0000135
Wanlong Gao354ebb42012-12-07 10:10:04 +0800136void summarize_errno();
plars865695b2001-08-27 22:15:12 +0000137void record_errno(unsigned int n);
138
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139int main(int argc, char *argv[])
plars865695b2001-08-27 22:15:12 +0000140{
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200141 const char *msg;
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800142 int lc;
plars865695b2001-08-27 22:15:12 +0000143
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800144 if ((msg = parse_opts(argc, argv, options, help)) != NULL)
145 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000146
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800147 if (v_opt)
148 verbose_level = atoi(v_copt);
plars865695b2001-08-27 22:15:12 +0000149
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800150 if (n_opt)
151 ntries = atoi(n_copt);
plars865695b2001-08-27 22:15:12 +0000152
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800153 if (l_opt)
154 sysno_max = atoi(l_copt);
plars865695b2001-08-27 22:15:12 +0000155
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800156 if (s_opt)
157 nseed = atoi(s_copt);
158 else
159 nseed = time(NULL);
plars865695b2001-08-27 22:15:12 +0000160
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800161 setup();
plars865695b2001-08-27 22:15:12 +0000162
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800163 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800164 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000165
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800166 tst_resm(TINFO, "crashme02 %d %d %d", sysno_max, nseed, ntries);
plars865695b2001-08-27 22:15:12 +0000167
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800168 srand(nseed);
169 badboy_fork();
plars865695b2001-08-27 22:15:12 +0000170
171 /* still there? */
172 tst_resm(TPASS, "we're still here, OS seems to be robust");
173
174 nseed++;
175 }
176 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800177 tst_exit();
plars865695b2001-08-27 22:15:12 +0000178}
179
180/* ************************* */
181int badboy_pid;
182
Wanlong Gao354ebb42012-12-07 10:10:04 +0800183void my_signal(int sig, void (*func) ());
plars865695b2001-08-27 22:15:12 +0000184
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800185void monitor_fcn(int sig)
plars865695b2001-08-27 22:15:12 +0000186{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800187 int status;
plars865695b2001-08-27 22:15:12 +0000188
Garrett Cooper2c282152010-12-16 00:55:50 -0800189 if (verbose_level >= 3)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 printf("time limit reached on pid. using kill.\n");
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800191
192 status = kill(badboy_pid, SIGKILL);
193 if (status < 0) {
194 if (verbose_level >= 3)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800195 printf("failed to kill process\n");
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800196 }
plars865695b2001-08-27 22:15:12 +0000197}
198
Wanlong Gao354ebb42012-12-07 10:10:04 +0800199void badboy_fork()
plars865695b2001-08-27 22:15:12 +0000200{
201 int status, pid;
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800202 pid_t child;
203 child = fork();
204 badboy_pid = status;
205 switch (child) {
206 case -1:
207 perror("fork");
208 case 0:
plars865695b2001-08-27 22:15:12 +0000209#ifdef DEBUG_LATE_BADBOY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800210 sleep(ntries * MAX_TRY_TIME + 10);
plars865695b2001-08-27 22:15:12 +0000211#else
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800212 badboy_loop();
plars865695b2001-08-27 22:15:12 +0000213#endif
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800214 exit(0);
215 default:
216 if (verbose_level > 3)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800217 printf("badboy pid = %d\n", badboy_pid);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800218
219 /* don't trust the child to return at night */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800220 my_signal(SIGALRM, monitor_fcn);
221 alarm(ntries * MAX_TRY_TIME);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800222
Wanlong Gao354ebb42012-12-07 10:10:04 +0800223 pid = waitpid(-1, &status, WUNTRACED);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800224 if (pid <= 0)
225 perror("wait");
226 else {
227 if (verbose_level > 3)
228 printf("pid %d exited with status %d\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800229 pid, status);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800230#if 0
231 record_status(status);
232#endif
233 }
plars865695b2001-08-27 22:15:12 +0000234 }
plars865695b2001-08-27 22:15:12 +0000235 alarm(0);
236}
237
238/* *************** status recording ************************* */
239
240/* errno status table (max is actually around 127) */
241#define STATUS_MAX 256
242static int errno_table[STATUS_MAX];
243
244void record_errno(unsigned int n)
245{
246 if (n >= STATUS_MAX)
247 return;
248
249 errno_table[n]++;
250}
251
252/* may not work with -c option */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800253void summarize_errno()
plars865695b2001-08-27 22:15:12 +0000254{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800255 int i;
plars865695b2001-08-27 22:15:12 +0000256
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800257 if (x_opt || verbose_level < 2)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 return;
plars865695b2001-08-27 22:15:12 +0000259
Wanlong Gao354ebb42012-12-07 10:10:04 +0800260 printf("errno status ... number of cases\n");
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800261 for (i = 0; i < STATUS_MAX; i++) {
262 if (errno_table[i])
Wanlong Gao354ebb42012-12-07 10:10:04 +0800263 printf("%12d ... %5d\n", i, errno_table[i]);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800264 }
plars865695b2001-08-27 22:15:12 +0000265}
266
plars865695b2001-08-27 22:15:12 +0000267/* ************* badboy ******************************************* */
268
269jmp_buf again_buff;
270
Wanlong Gao354ebb42012-12-07 10:10:04 +0800271unsigned char *bad_malloc(int n);
272void my_signal(int sig, void (*func) ());
273void again_handler(int sig);
274void try_one_crash(int try_num);
275void set_up_signals();
276int in_blacklist(int sysno);
plars865695b2001-08-27 22:15:12 +0000277
278/* badboy "entry" point */
279
280/*
281 * Unlike crashme, faulty syscalls are not supposed to barf
282 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800283void badboy_loop()
plars865695b2001-08-27 22:15:12 +0000284{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800285 int i;
plars865695b2001-08-27 22:15:12 +0000286
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800287 for (i = 0; i < ntries; ++i) {
288 /* level 5 */
plars865695b2001-08-27 22:15:12 +0000289
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800290 if (!x_opt && verbose_level >= 5) {
291 printf("try %d\n", i);
292 }
plars865695b2001-08-27 22:15:12 +0000293
Wanlong Gao354ebb42012-12-07 10:10:04 +0800294 if (setjmp(again_buff) == 3) {
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800295 if (verbose_level >= 5)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800296 printf("Barfed\n");
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800297 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800298 set_up_signals();
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800299 alarm(MAX_TRY_TIME);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800300 try_one_crash(i);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800301 }
plars865695b2001-08-27 22:15:12 +0000302 }
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800303 summarize_errno();
plars865695b2001-08-27 22:15:12 +0000304}
305
Wanlong Gao354ebb42012-12-07 10:10:04 +0800306void again_handler(int sig)
plars865695b2001-08-27 22:15:12 +0000307{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800308 char *ss;
plars865695b2001-08-27 22:15:12 +0000309
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800310 switch (sig) {
311 case SIGILL:
312 ss = " illegal instruction";
313 break;
plars865695b2001-08-27 22:15:12 +0000314#ifdef SIGTRAP
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800315 case SIGTRAP:
316 ss = " trace trap";
317 break;
plars865695b2001-08-27 22:15:12 +0000318#endif
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800319 case SIGFPE:
320 ss = " arithmetic exception";
321 break;
plars865695b2001-08-27 22:15:12 +0000322#ifdef SIGBUS
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800323 case SIGBUS:
324 ss = " bus error";
325 break;
plars865695b2001-08-27 22:15:12 +0000326#endif
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800327 case SIGSEGV:
328 ss = " segmentation violation";
329 break;
plars865695b2001-08-27 22:15:12 +0000330#ifdef SIGIOT
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800331 case SIGIOT:
332 ss = " IOT instruction";
333 break;
plars865695b2001-08-27 22:15:12 +0000334#endif
335#ifdef SIGEMT
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800336 case SIGEMT:
337 ss = " EMT instruction";
338 break;
plars865695b2001-08-27 22:15:12 +0000339#endif
340#ifdef SIGALRM
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800341 case SIGALRM:
342 ss = " alarm clock";
343 break;
plars865695b2001-08-27 22:15:12 +0000344#endif
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800345 case SIGINT:
346 ss = " interrupt";
347 break;
348 default:
349 ss = "";
350 }
351 if (verbose_level >= 5)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800352 printf("Got signal %d%s\n", sig, ss);
plars865695b2001-08-27 22:15:12 +0000353
Wanlong Gao354ebb42012-12-07 10:10:04 +0800354 longjmp(again_buff, 3);
plars865695b2001-08-27 22:15:12 +0000355}
356
Wanlong Gao354ebb42012-12-07 10:10:04 +0800357void my_signal(int sig, void (*func) ())
plars865695b2001-08-27 22:15:12 +0000358{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800359 struct sigaction act;
plars865695b2001-08-27 22:15:12 +0000360
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800361 act.sa_handler = func;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800362 memset(&act.sa_mask, 0x00, sizeof(sigset_t));
363 act.sa_flags = SA_NOMASK | SA_RESTART;
364 sigaction(sig, &act, 0);
plars865695b2001-08-27 22:15:12 +0000365}
366
Wanlong Gao354ebb42012-12-07 10:10:04 +0800367void set_up_signals()
plars865695b2001-08-27 22:15:12 +0000368{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800369 my_signal(SIGILL, again_handler);
plars865695b2001-08-27 22:15:12 +0000370#ifdef SIGTRAP
Wanlong Gao354ebb42012-12-07 10:10:04 +0800371 my_signal(SIGTRAP, again_handler);
plars865695b2001-08-27 22:15:12 +0000372#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800373 my_signal(SIGFPE, again_handler);
plars865695b2001-08-27 22:15:12 +0000374#ifdef SIGBUS
Wanlong Gao354ebb42012-12-07 10:10:04 +0800375 my_signal(SIGBUS, again_handler);
plars865695b2001-08-27 22:15:12 +0000376#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800377 my_signal(SIGSEGV, again_handler);
plars865695b2001-08-27 22:15:12 +0000378#ifdef SIGIOT
Wanlong Gao354ebb42012-12-07 10:10:04 +0800379 my_signal(SIGIOT, again_handler);
plars865695b2001-08-27 22:15:12 +0000380#endif
381#ifdef SIGEMT
Wanlong Gao354ebb42012-12-07 10:10:04 +0800382 my_signal(SIGEMT, again_handler);
plars865695b2001-08-27 22:15:12 +0000383#endif
384#ifdef SIGALRM
Wanlong Gao354ebb42012-12-07 10:10:04 +0800385 my_signal(SIGALRM, again_handler);
plars865695b2001-08-27 22:15:12 +0000386#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800387 my_signal(SIGINT, again_handler);
plars865695b2001-08-27 22:15:12 +0000388}
389
390/*
391 * NB: rand() (ie. RAND_MAX) might be on 31bits only!
392 *
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800393 * FIXME: 64-bit systems
plars865695b2001-08-27 22:15:12 +0000394 *
395 * TODO: improve arg mixing (16bits and 8bits values, NULLs, etc.).
Garrett Cooper2c282152010-12-16 00:55:50 -0800396 * big values as returned by rand() are no so interresting
397 * (except when used as pointers) because they may fall too
plars865695b2001-08-27 22:15:12 +0000398 * quickly in the invalid parameter sieve. Smaller values,
399 * will be more insidious because they may refer to existing
400 * objects (pids, fd, etc.).
401 */
402long int rand_long()
403{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800404 int r1, r2;
plars865695b2001-08-27 22:15:12 +0000405
Wanlong Gao354ebb42012-12-07 10:10:04 +0800406 r1 = rand();
407 r2 = rand();
Garrett Cooper2c282152010-12-16 00:55:50 -0800408
Wanlong Gao354ebb42012-12-07 10:10:04 +0800409 if (r1 & 0x10000L)
410 r1 = 0;
411 if (!r1 && (r2 & 0x50000L))
412 r2 = 0;
413 else if (!r1 && (r2 & 0x20000L))
414 r2 &= 0x00ffL;
plars865695b2001-08-27 22:15:12 +0000415
Wanlong Gao354ebb42012-12-07 10:10:04 +0800416 return (long int)((r1 & 0xffffL) << 16) | (r2 & 0xffffL);
plars865695b2001-08-27 22:15:12 +0000417}
418
Wanlong Gao354ebb42012-12-07 10:10:04 +0800419void try_one_crash(int try_num)
plars865695b2001-08-27 22:15:12 +0000420{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800421 long int sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
plars865695b2001-08-27 22:15:12 +0000422
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800423 do {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800424 sysno = rand() % sysno_max;
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800425 } while (in_blacklist(sysno));
subrata_modak1b779092009-05-25 15:27:10 +0000426
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800427 arg1 = rand_long();
428 arg2 = rand_long();
429 arg3 = rand_long();
430 arg4 = rand_long();
431 arg5 = rand_long();
432 arg6 = rand_long();
433 arg7 = rand_long();
plars865695b2001-08-27 22:15:12 +0000434
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800435 if (x_opt) {
436 if (verbose_level >= 1)
437 printf("%04d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800438 "%#lx, %#lx, %#lx)\n",
439 try_num, sysno, arg1, arg2, arg3, arg4, arg5,
440 arg6, arg7);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800441 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800442 syscall(sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800443 record_errno(errno);
444 }
plars865695b2001-08-27 22:15:12 +0000445}
446
subrata_modak1b779092009-05-25 15:27:10 +0000447/* The following syscalls create new processes which may cause the test
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800448 unable to finish. */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800449int in_blacklist(int sysno)
subrata_modak1b779092009-05-25 15:27:10 +0000450{
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800451 int i;
452 const int list[] = {
yaberauneyaef772532009-10-09 17:55:43 +0000453#if defined(__ia64__)
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800454 SYS_clone2,
subrata_modak1b779092009-05-25 15:27:10 +0000455#else
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800456 /*
457 * No SYS_fork(vfork) on IA-64. Instead, it uses,
458 * clone(child_stack=0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD)
459 * clone2()
460 */
Garrett Cooper2c282152010-12-16 00:55:50 -0800461
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800462 /*
463 * NOTE (garrcoop):
464 * Could not find reference to SYS_fork(vfork) on mips32
465 * with the Montavista / Octeon toolchain. Need to develop an
466 * autoconf check for this item.
467 */
yaberauneyaef772532009-10-09 17:55:43 +0000468#if defined(__NR_vfork) && __NR_vfork
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800469 SYS_vfork,
470#elif defined(__NR_fork) && __NR_fork
471 SYS_fork,
yaberauneyaef772532009-10-09 17:55:43 +0000472#endif
subrata_modak1b779092009-05-25 15:27:10 +0000473#endif /* __ia64__ */
yaberauneyaef772532009-10-09 17:55:43 +0000474#if defined(__NR_clone) && __NR_clone
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800475 SYS_clone,
yaberauneyaef772532009-10-09 17:55:43 +0000476#endif
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800477 -1
478 };
plars865695b2001-08-27 22:15:12 +0000479
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800480 for (i = 0; list[i] != -1; i++) {
481 if (sysno == list[i])
482 return 1;
483 }
subrata_modak1b779092009-05-25 15:27:10 +0000484
Garrett Cooper1ffecc92010-12-18 00:03:44 -0800485 return 0;
Chris Dearmanec6edca2012-10-17 19:54:01 -0700486}