move eventfd stuff out to own file
[trinity.git] / trinity.c
blob4d8d200c7a89282a4182d0fe1331ed671af5e992
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
23 #include "taint.h"
25 char *progname = NULL;
27 unsigned int page_size;
28 unsigned int num_online_cpus;
29 unsigned int max_children;
32 * just in case we're not using the test.sh harness, we
33 * change to the tmp dir if it exists.
35 static void change_tmp_dir(void)
37 struct stat sb;
38 const char tmpdir[]="tmp/";
39 int ret;
41 /* Check if it exists, bail early if it doesn't */
42 ret = (lstat(tmpdir, &sb));
43 if (ret == -1)
44 return;
46 /* Just in case a previous run screwed the perms. */
47 ret = chmod(tmpdir, 0777);
48 if (ret == -1)
49 output(0, "Couldn't chmod %s to 0777.\n", tmpdir);
51 ret = chdir(tmpdir);
52 if (ret == -1)
53 output(0, "Couldn't change to %s\n", tmpdir);
56 int main(int argc, char* argv[])
58 int ret = EXIT_SUCCESS;
59 int childstatus;
60 pid_t pid;
61 const char taskname[13]="trinity-main";
63 outputstd("Trinity v" __stringify(VERSION) " Dave Jones <davej@redhat.com>\n");
65 progname = argv[0];
67 initpid = getpid();
69 page_size = getpagesize();
70 num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
71 max_children = num_online_cpus; /* possibly overridden in params. */
73 select_syscall_tables();
75 create_shm();
77 parse_args(argc, argv);
79 create_shm_arrays();
81 init_uids();
83 if (logging == TRUE)
84 open_logfiles();
86 init_shm();
88 kernel_taint_initial = check_tainted();
89 if (kernel_taint_initial != 0)
90 output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n");
92 if (munge_tables() == FALSE) {
93 ret = EXIT_FAILURE;
94 goto out;
97 if (show_syscall_list == TRUE) {
98 dump_syscall_tables();
99 goto out;
102 init_syscalls();
104 if (show_ioctl_list == TRUE) {
105 dump_ioctls();
106 goto out;
109 do_uid0_check();
111 if (do_specific_proto == TRUE)
112 find_specific_proto(specific_proto_optarg);
114 init_shared_pages();
116 parse_devices();
118 pids_init();
120 setup_main_signals();
122 change_tmp_dir();
124 /* check if we ctrl'c or something went wrong during init. */
125 if (shm->exit_reason != STILL_RUNNING)
126 goto cleanup_fds;
128 init_watchdog();
130 /* do an extra fork so that the watchdog and the children don't share a common parent */
131 fflush(stdout);
132 pid = fork();
133 if (pid == 0) {
134 shm->mainpid = getpid();
136 setup_main_signals();
138 output(0, "Main thread is alive.\n");
139 prctl(PR_SET_NAME, (unsigned long) &taskname);
140 set_seed(0);
142 if (setup_fds() == FALSE) {
143 shm->exit_reason = EXIT_FD_INIT_FAILURE; // FIXME: Later, push this down to multiple EXIT's.
144 _exit(EXIT_FAILURE);
147 if (no_files == FALSE) {
148 if (files_in_index == 0) {
149 shm->exit_reason = EXIT_NO_FILES;
150 _exit(EXIT_FAILURE);
154 if (dropprivs == TRUE) //FIXME: Push down into child processes later.
155 drop_privs();
157 main_loop();
159 _exit(EXIT_SUCCESS);
162 /* wait for main loop process to exit. */
163 (void)waitpid(pid, &childstatus, 0);
165 /* wait for watchdog to exit. */
166 waitpid(watchdog_pid, &childstatus, 0);
168 output(0, "\nRan %ld syscalls. Successes: %ld Failures: %ld\n",
169 shm->total_syscalls_done - 1, shm->successes, shm->failures);
171 cleanup_fds:
173 close_sockets();
175 destroy_shared_mappings();
177 if (logging == TRUE)
178 close_logfiles();
180 out:
182 exit(ret);