parse args before setting up the shm.
[trinity.git] / trinity.c
blob40a7af09b3150d58293f7d4faf0658f897e58313
1 #include <stdlib.h>
2 #include <malloc.h>
3 #include <string.h>
4 #include <sys/prctl.h>
5 #include <sys/types.h>
6 #include <sys/wait.h>
8 #include "arch.h"
9 #include "trinity.h"
10 #include "files.h"
11 #include "log.h"
12 #include "maps.h"
13 #include "pids.h"
14 #include "params.h"
15 #include "random.h"
16 #include "signals.h"
17 #include "shm.h"
18 #include "tables.h"
19 #include "ioctls.h"
20 #include "protocols.h"
21 #include "uid.h"
22 #include "config.h" // for VERSION
24 char *progname = NULL;
26 unsigned int page_size;
27 unsigned int num_online_cpus;
28 unsigned int max_children;
31 * just in case we're not using the test.sh harness, we
32 * change to the tmp dir if it exists.
34 static void change_tmp_dir(void)
36 struct stat sb;
37 const char tmpdir[]="tmp/";
38 int ret;
40 /* Check if it exists, bail early if it doesn't */
41 ret = (lstat(tmpdir, &sb));
42 if (ret == -1)
43 return;
45 /* Just in case a previous run screwed the perms. */
46 ret = chmod(tmpdir, 0777);
47 if (ret == -1)
48 output(0, "Couldn't chmod %s to 0777.\n", tmpdir);
50 ret = chdir(tmpdir);
51 if (ret == -1)
52 output(0, "Couldn't change to %s\n", tmpdir);
55 int main(int argc, char* argv[])
57 int ret = EXIT_SUCCESS;
58 int childstatus;
59 pid_t pid;
60 const char taskname[13]="trinity-main";
62 outputstd("Trinity v" __stringify(VERSION) " Dave Jones <davej@redhat.com>\n");
64 progname = argv[0];
66 initpid = getpid();
68 init_uids();
70 page_size = getpagesize();
71 num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
72 max_children = num_online_cpus; /* possibly overridden in params. */
74 select_syscall_tables();
76 parse_args(argc, argv);
78 if (create_shm())
79 exit(EXIT_FAILURE);
81 kernel_taint_initial = check_tainted();
82 if (kernel_taint_initial != 0)
83 output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n");
85 if (logging == TRUE)
86 open_logfiles();
88 if (munge_tables() == FALSE) {
89 ret = EXIT_FAILURE;
90 goto out;
93 if (show_syscall_list == TRUE) {
94 dump_syscall_tables();
95 goto out;
98 init_syscalls();
100 if (show_ioctl_list == TRUE) {
101 dump_ioctls();
102 goto out;
105 do_uid0_check();
107 if (do_specific_proto == TRUE)
108 find_specific_proto(specific_proto_optarg);
110 init_shared_pages();
112 parse_devices();
114 pids_init();
116 setup_main_signals();
118 change_tmp_dir();
120 /* check if we ctrl'c or something went wrong during init. */
121 if (shm->exit_reason != STILL_RUNNING)
122 goto cleanup_fds;
124 init_watchdog();
126 /* do an extra fork so that the watchdog and the children don't share a common parent */
127 fflush(stdout);
128 pid = fork();
129 if (pid == 0) {
130 shm->mainpid = getpid();
132 setup_main_signals();
134 output(0, "Main thread is alive.\n");
135 prctl(PR_SET_NAME, (unsigned long) &taskname);
136 set_seed(0);
138 if (setup_fds() == FALSE) {
139 shm->exit_reason = EXIT_FD_INIT_FAILURE; // FIXME: Later, push this down to multiple EXIT's.
140 _exit(EXIT_FAILURE);
143 if (no_files == FALSE) {
144 if (files_in_index == 0) {
145 shm->exit_reason = EXIT_NO_FILES;
146 _exit(EXIT_FAILURE);
150 if (dropprivs == TRUE) //FIXME: Push down into child processes later.
151 drop_privs();
153 main_loop();
155 _exit(EXIT_SUCCESS);
158 /* wait for main loop process to exit. */
159 (void)waitpid(pid, &childstatus, 0);
161 /* wait for watchdog to exit. */
162 waitpid(watchdog_pid, &childstatus, 0);
164 output(0, "\nRan %ld syscalls. Successes: %ld Failures: %ld\n",
165 shm->total_syscalls_done - 1, shm->successes, shm->failures);
167 cleanup_fds:
169 close_sockets();
171 destroy_shared_mappings();
173 if (logging == TRUE)
174 close_logfiles();
176 out:
178 exit(ret);