int main(int argc, char *argv[]) { int rc; gamut_opts opts; signal(SIGPIPE, SIG_IGN); memset(&opts, 0, sizeof(opts)); /* Use line buffering for stdout */ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); rc = parse_opts(argc, argv, &opts); if(rc < 0) { s_log(G_EMERG, "Error parsing options.\n"); exit(EXIT_FAILURE); } else if(!rc) { usage(argv[0]); exit(EXIT_FAILURE); } /* * In this order, perform these steps (if necessary) * 1. Redirect to a log file * 2. Restore benchmark data from a file * 3. Run the benchmarks * 4. Save the new benchmark data * 5. Quit after benchmarks * 6. Run calibration (if no benchmark data) * 7. Run a trace file and exit * 8. Accept commands from stdin */ /* * 1. Redirect to a log file */ if(redirect_stdout) { redirect_output(); } /* * 2. Restore benchmark data from a file */ if(load_benchmarks) { s_log(G_NOTICE, "Loading benchmark data ... "); load_benchmark_data(); s_log(G_NOTICE, "done.\n"); } /* * 3. Run the benchmarks */ if(run_benchmarks) { s_log(G_NOTICE, "Running %u calibration trials.\n", DEF_BMARK_TRIALS); benchmark_delays(DEF_BMARK_TRIALS); } /* * 4. Save the new benchmark data */ if(save_benchmarks) { s_log(G_NOTICE, "Saving benchmark data ... "); save_benchmark_data(); s_log(G_NOTICE, "done.\n"); /* * 5. Quit after benchmarks */ if(quit_benchmarks) exit(EXIT_SUCCESS); } /* * 6. Run calibration (if no benchmark data is available yet) */ if(!load_benchmarks && !run_benchmarks) { s_log(G_NOTICE, "Calibrating node attributes ... "); benchmark_delays(1); s_log(G_NOTICE, "done.\n"); } init_opts(&opts); start_reaper(&opts); start_input(&opts); execute_gamut(&opts); stop_input(&opts); killall_workers(&opts); stop_reaper(&opts); return 0; }
int main(int argc, char **argv) { struct sockaddr_un addr; pid_t pid, sid; int pipefd[2]; int clfd; char deamonize; if(argc==2 && !strncmp(argv[1], "-f", 3)) { deamonize=0; } else { deamonize=1; } if(deamonize) { if(pipe2(pipefd, O_CLOEXEC)) { print( FATAL, "pipe2: %s", strerror(errno) ); return EXIT_FAILURE; } pid = fork(); if(pid<0) { print( FATAL, "fork: %s", strerror(errno) ); return EXIT_FAILURE; } else if(pid) { close(pipefd[1]); if(!read(pipefd[0], &clfd, 1)) return EXIT_FAILURE; return EXIT_SUCCESS; } close(pipefd[0]); umask(0); if(open_logfile(LOG_PATH)) { print( FATAL, "cannot open logfile"); return EXIT_FAILURE; } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); set_logger(file_logger); sid = setsid(); if(sid<0) { print( FATAL, "setsid: %s", strerror(errno) ); return EXIT_FAILURE; } } if(init_structs()) return EXIT_FAILURE; if(load_handlers()) return EXIT_FAILURE; if(load_users()) return EXIT_FAILURE; if(remove_old_socket()) return EXIT_FAILURE; sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if(sockfd < 0) { print( FATAL, "socket: %s", strerror(errno) ); return EXIT_FAILURE; } if(register_signal_handlers()) { close(sockfd); return EXIT_FAILURE; } memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path)-1); if(bind(sockfd, (struct sockaddr*)&addr, sizeof(addr))) { print( FATAL, "bind: %s", strerror(errno) ); close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } if(listen(sockfd, 5)) { print( FATAL, "listen: %s", strerror(errno) ); close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } if(start_reaper()) { close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } #ifndef NDEBUG chmod(SOCKET_PATH, 0666); #endif if(deamonize) { if(write(pipefd[1], "!", 1) != 1) { print( FATAL, "cannot notify that daemon started" ); return EXIT_FAILURE; } close(pipefd[1]); } while(1) { if((clfd=accept(sockfd, NULL, NULL)) < 0) { if(errno == EINVAL) { #ifndef NDEBUG print( DEBUG, "socket closed" ); #endif } print( ERROR, "accept: %s", strerror(errno) ); break; } if(serve_new_client(clfd)) { print( WARNING, "cannot serve new connection" ); close(clfd); } } unlink(SOCKET_PATH); close_connections(); stop_reaper(); destroy_structs(); unload_users(); unload_handlers(); return EXIT_SUCCESS; }