int main(int argc, char ** argv) { //初始化两个信号集,一个只有usr1,一个只有usr2 sigemptyset(&t_sigset_usr); sigemptyset(&t_sigset_old); sigemptyset(&t_sigset_zero); sigaddset(&t_sigset_usr, SIGUSR1); sigaddset(&t_sigset_usr, SIGUSR2); //注册信号处理程序, signal(SIGUSR1, do_sig_usr); signal(SIGUSR2, do_sig_usr); //父进程阻塞usr信号 sigprocmask(SIG_SETMASK, &t_sigset_usr, NULL ); pid_t child_pid; //父进程fork一个子进程出来 child_pid = fork(); if (child_pid == 0) { //子进程,从2开始写 num = 2; //注册信号处理程序, signal(SIGUSR1, do_sig_usr); signal(SIGUSR2, do_sig_usr); //子进程阻塞usr信号 sigprocmask(SIG_SETMASK, &t_sigset_usr, NULL ); //子进程准备完毕,通知父进程去写 tell_parent(); while (1) { //始终等待父进程唤醒 wait_parent(); write_num_to_file(); tell_parent(); } } else { //父进程 while (1) { //始终等待子进程唤醒 wait_child(); write_num_to_file(); tell_child(child_pid); } } //子进程写入数据,并且告知父进程,然后投入睡眠,等待父进程唤醒 //父进程等待子进程 exit(0); }
int Y_Exit(int exit_code, UserContext *user_context){ pcb_t *parent = (pcb_t*)running_proc->parent; //Set states running_proc->exit_code = exit_code; running_proc->state = ZOMBIE; // Tell other people tell_children(running_proc); tell_parent(running_proc); // Scheulde next process to run next_schedule(user_context); log_info("Next schedule done (this will never reached actually)"); }
int child_process() { int shm_id; void* shm_ptr = NULL; if(-1 == wait_parent()) { printf("[C]fail to wait_parent\n"); return -1; } shm_id = shmget(SHM_KEY, SHM_SIZE, SHM_MODE); if(-1 == shm_id) { printf("[C]Fail to open shm, errno: %d, errmsg: %s\n", errno, strerror(errno)); return -1; } shm_ptr = shmat(shm_id, 0, 0); if((void*)-1 == shm_ptr) { printf("[C]Fail to attach to shm, errno: %d, errmsg: %s\n", errno, strerror(errno)); return -1; } char buf[1024] = {0}; memcpy((void*)buf, shm_ptr, strlen(shm_ptr)); printf("[C]Shm contents: %s\n", buf); shmdt(shm_ptr); if(-1 == tell_parent()) { printf("[C]Fail to tell_parent\n"); return -1; } return 0; }
int main(int argc, char *argv[]) { struct sigaction sa; struct rlimit limit; int i, c, rc; int opt_foreground = 0, opt_allow_links = 0; enum startup_state opt_startup = startup_enable; extern char *optarg; extern int optind; struct ev_loop *loop; struct ev_io netlink_watcher; struct ev_signal sigterm_watcher; struct ev_signal sighup_watcher; struct ev_signal sigusr1_watcher; struct ev_signal sigusr2_watcher; struct ev_signal sigchld_watcher; /* Get params && set mode */ while ((c = getopt(argc, argv, "flns:")) != -1) { switch (c) { case 'f': opt_foreground = 1; break; case 'l': opt_allow_links=1; break; case 'n': do_fork = 0; break; case 's': for (i=0; i<startup_INVALID; i++) { if (strncmp(optarg, startup_states[i], strlen(optarg)) == 0) { opt_startup = i; break; } } if (i == startup_INVALID) { fprintf(stderr, "unknown startup mode '%s'\n", optarg); usage(); } break; default: usage(); } } /* check for trailing command line following options */ if (optind < argc) { usage(); } if (opt_allow_links) set_allow_links(1); if (opt_foreground) { config.daemonize = D_FOREGROUND; set_aumessage_mode(MSG_STDERR, DBG_YES); } else { config.daemonize = D_BACKGROUND; set_aumessage_mode(MSG_SYSLOG, DBG_NO); (void) umask( umask( 077 ) | 022 ); } #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 4; } #endif /* Register sighandlers */ sa.sa_flags = 0 ; sigemptyset( &sa.sa_mask ) ; /* Ignore all signals by default */ sa.sa_handler = SIG_IGN; for (i=1; i<NSIG; i++) sigaction( i, &sa, NULL ); atexit(clean_exit); /* Raise the rlimits in case we're being started from a shell * with restrictions. Not a fatal error. */ limit.rlim_cur = RLIM_INFINITY; limit.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_FSIZE, &limit); setrlimit(RLIMIT_CPU, &limit); /* Load the Configuration File */ if (load_config(&config, TEST_AUDITD)) return 6; if (config.priority_boost != 0) { errno = 0; rc = nice((int)-config.priority_boost); if (rc == -1 && errno) { audit_msg(LOG_ERR, "Cannot change priority (%s)", strerror(errno)); return 1; } } /* Daemonize or stay in foreground for debugging */ if (config.daemonize == D_BACKGROUND) { if (become_daemon() != 0) { audit_msg(LOG_ERR, "Cannot daemonize (%s)", strerror(errno)); tell_parent(FAILURE); return 1; } openlog("auditd", LOG_PID, LOG_DAEMON); } /* Init netlink */ if ((fd = audit_open()) < 0) { audit_msg(LOG_ERR, "Cannot open netlink audit socket"); tell_parent(FAILURE); return 1; } /* Init the event handler thread */ write_pid_file(); if (init_event(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (init_dispatcher(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Get machine name ready for use */ if (resolve_node(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Write message to log that we are alive */ { struct utsname ubuf; char start[DEFAULT_BUF_SZ]; const char *fmt = audit_lookup_format((int)config.log_format); if (fmt == NULL) fmt = "UNKNOWN"; if (uname(&ubuf) != 0) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (getsubj(subj)) snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d subj=%s res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid(), subj); else snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid()); if (send_audit_event(AUDIT_DAEMON_START, start)) { audit_msg(LOG_ERR, "Cannot send start message"); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } } /* Tell kernel not to kill us */ avoid_oom_killer(); /* let config manager init */ init_config_manager(); if (opt_startup != startup_nochange && (audit_is_enabled(fd) < 2) && audit_set_enabled(fd, (int)opt_startup) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set initial audit startup state to '%s', exiting", startup_states[opt_startup]); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Tell the kernel we are alive */ if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set audit pid, exiting"); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Depending on value of opt_startup (-s) set initial audit state */ loop = ev_default_loop (EVFLAG_NOENV); ev_io_init (&netlink_watcher, netlink_handler, fd, EV_READ); ev_io_start (loop, &netlink_watcher); ev_signal_init (&sigterm_watcher, term_handler, SIGTERM); ev_signal_start (loop, &sigterm_watcher); ev_signal_init (&sighup_watcher, hup_handler, SIGHUP); ev_signal_start (loop, &sighup_watcher); ev_signal_init (&sigusr1_watcher, user1_handler, SIGUSR1); ev_signal_start (loop, &sigusr1_watcher); ev_signal_init (&sigusr2_watcher, user2_handler, SIGUSR2); ev_signal_start (loop, &sigusr2_watcher); ev_signal_init (&sigchld_watcher, child_handler, SIGCHLD); ev_signal_start (loop, &sigchld_watcher); if (auditd_tcp_listen_init (loop, &config)) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); tell_parent(FAILURE); } else { /* Now tell parent that everything went OK */ tell_parent(SUCCESS); audit_msg(LOG_NOTICE, "Init complete, auditd %s listening for events (startup state %s)", VERSION, startup_states[opt_startup]); } /* Parent should be gone by now... */ if (do_fork) close(init_pipe[1]); // Init complete, start event loop if (!stop) ev_loop (loop, 0); auditd_tcp_listen_uninit (loop, &config); // Tear down IO watchers Part 1 ev_signal_stop (loop, &sighup_watcher); ev_signal_stop (loop, &sigusr1_watcher); ev_signal_stop (loop, &sigusr2_watcher); ev_signal_stop (loop, &sigterm_watcher); /* Write message to log that we are going down */ rc = audit_request_signal_info(fd); if (rc > 0) { struct audit_reply trep; rc = get_reply(fd, &trep, rc); if (rc > 0) { char txt[MAX_AUDIT_MESSAGE_LENGTH]; snprintf(txt, sizeof(txt), "auditd normal halt, sending auid=%u " "pid=%d subj=%s res=success", trep.signal_info->uid, trep.signal_info->pid, trep.signal_info->ctx); send_audit_event(AUDIT_DAEMON_END, txt); } } if (rc <= 0) send_audit_event(AUDIT_DAEMON_END, "auditd normal halt, sending auid=? " "pid=? subj=? res=success"); free(rep); // Tear down IO watchers Part 2 ev_io_stop (loop, &netlink_watcher); // Give DAEMON_END event a little time to be sent in case // of remote logging usleep(10000); // 10 milliseconds shutdown_dispatcher(); // Tear down IO watchers Part 3 ev_signal_stop (loop, &sigchld_watcher); close_down(); free_config(&config); ev_default_destroy(); return 0; }