use usleep for <1s sleeps
[trinity.git] / trinity.c
bloba7d44a7d35b84a08475332e9716d4180e9a3ed3b
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 create_shm();
78 parse_args(argc, argv);
80 create_shm_arrays();
82 if (logging == TRUE)
83 open_logfiles();
85 init_shm();
87 kernel_taint_initial = check_tainted();
88 if (kernel_taint_initial != 0)
89 output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n");
91 if (munge_tables() == FALSE) {
92 ret = EXIT_FAILURE;
93 goto out;
96 if (show_syscall_list == TRUE) {
97 dump_syscall_tables();
98 goto out;
101 init_syscalls();
103 if (show_ioctl_list == TRUE) {
104 dump_ioctls();
105 goto out;
108 do_uid0_check();
110 if (do_specific_proto == TRUE)
111 find_specific_proto(specific_proto_optarg);
113 init_shared_pages();
115 parse_devices();
117 pids_init();
119 setup_main_signals();
121 change_tmp_dir();
123 /* check if we ctrl'c or something went wrong during init. */
124 if (shm->exit_reason != STILL_RUNNING)
125 goto cleanup_fds;
127 init_watchdog();
129 /* do an extra fork so that the watchdog and the children don't share a common parent */
130 fflush(stdout);
131 pid = fork();
132 if (pid == 0) {
133 shm->mainpid = getpid();
135 setup_main_signals();
137 output(0, "Main thread is alive.\n");
138 prctl(PR_SET_NAME, (unsigned long) &taskname);
139 set_seed(0);
141 if (setup_fds() == FALSE) {
142 shm->exit_reason = EXIT_FD_INIT_FAILURE; // FIXME: Later, push this down to multiple EXIT's.
143 _exit(EXIT_FAILURE);
146 if (no_files == FALSE) {
147 if (files_in_index == 0) {
148 shm->exit_reason = EXIT_NO_FILES;
149 _exit(EXIT_FAILURE);
153 if (dropprivs == TRUE) //FIXME: Push down into child processes later.
154 drop_privs();
156 main_loop();
158 _exit(EXIT_SUCCESS);
161 /* wait for main loop process to exit. */
162 (void)waitpid(pid, &childstatus, 0);
164 /* wait for watchdog to exit. */
165 waitpid(watchdog_pid, &childstatus, 0);
167 output(0, "\nRan %ld syscalls. Successes: %ld Failures: %ld\n",
168 shm->total_syscalls_done - 1, shm->successes, shm->failures);
170 cleanup_fds:
172 close_sockets();
174 destroy_shared_mappings();
176 if (logging == TRUE)
177 close_logfiles();
179 out:
181 exit(ret);