int main(int argc, char *argv[]) { atexit(cleanup); sigset_t mask; sigfillset(&mask); sigdelset(&mask, SIGUSR1); sigprocmask(SIG_SETMASK, &mask, NULL); struct sigaction act; memset(&act, 0, sizeof act); act.sa_handler = sigint_handler; sigaction(SIGUSR1, &act, NULL); srand(time(NULL)); shm_id = shmget(SHM_KEY, MEM_SIZE, S_IRUSR); sem_id = semget(SEM_KEY, 0, S_IWUSR | S_IRUSR); if (shm_id < 0 || sem_id < 0) { printf("Error while opening shared memory and/or semaphores occurred.\n"); return 1; } shm = shmat(shm_id, NULL, 0); if (shm == (void *)-1) { printf("Error while accessing shared memory occurred.\n"); return 1; } struct sembuf sem_op; sem_op.sem_flg = 0; int task_index; int tasks_num; struct timeval tval; while (1) { sem_op.sem_num = 0; sem_op.sem_op = -1; if (semop(sem_id, &sem_op, 1) == -1) on_host_closed(); sem_op.sem_num = 2; if (semop(sem_id, &sem_op, 1) == -1) on_host_closed(); task_index = shm->start_index; shm->start_index = (task_index + 1) % ARRAY_LEN; tasks_num = shm->end_index - shm->start_index; if (tasks_num < 0) tasks_num += ARRAY_LEN; gettimeofday(&tval, NULL); printf("%d %ld.%ld Get task from position %d. Number of waiting tasks: %d.\n", getpid(), tval.tv_sec, tval.tv_usec/1000, task_index, tasks_num); fflush(stdout); sem_op.sem_num = 2; sem_op.sem_op = 1; if (semop(sem_id, &sem_op, 1) == -1) on_host_closed(); sem_op.sem_num = 1; sem_op.sem_op = 1; if (semop(sem_id, &sem_op, 1) == -1) on_host_closed(); nanosleep(&delay, NULL); } }
void mpls_send(struct attacks *attacks) { sigset_t mask; struct mpls_data *mpls_data; libnet_ptag_t t; libnet_t *lhandler; int32_t sent; int32_t payload_size=0, packet_size=0; u_int8_t *payload=NULL; dlist_t *p; struct interface_data *iface_data; struct interface_data *iface_data2; pthread_mutex_lock(&attacks->attack_th.finished); pthread_detach(pthread_self()); mpls_data = attacks->data; sigfillset(&mask); if (pthread_sigmask(SIG_BLOCK, &mask, NULL)) { thread_error("mpls_send pthread_sigmask()",errno); return; } if (mpls_data->ip_payload && mpls_data->ip_payload[0]) { payload_size = strlen((const char *)mpls_data->ip_payload); payload = mpls_data->ip_payload; } for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) { iface_data = (struct interface_data *) dlist_data(p); lhandler = iface_data->libnet_handler; switch(mpls_data->proto) { case IPPROTO_TCP: packet_size = LIBNET_TCP_H + payload_size; t = libnet_build_tcp( mpls_data->src_port, /* source port */ mpls_data->dst_port, /* destination port */ 0x666, /* sequence number */ 0x00000000, /* acknowledgement num */ TH_SYN, /* control flags */ 32767, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ packet_size, /* TCP packet size */ payload, /* payload */ payload_size, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ break; case IPPROTO_UDP: packet_size = LIBNET_UDP_H + payload_size; t = libnet_build_udp( mpls_data->src_port, /* source port */ mpls_data->dst_port, /* destination port */ packet_size, /* UDP packet size */ 0, /* checksum */ payload, /* payload */ payload_size, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ break; case IPPROTO_ICMP: packet_size = LIBNET_ICMPV4_ECHO_H + payload_size; t = libnet_build_icmpv4_echo( ICMP_ECHO, /* type */ 0, /* code */ 0, /* checksum */ 0x42, /* id */ 0x42, /* sequence number */ payload, /* payload */ payload_size, /* payload size */ lhandler, /* libnet handle */ 0); break; } if (t == -1) { thread_libnet_error("Can't build tcp/udp/icmp header",lhandler); libnet_clear_packet(lhandler); return; } t = libnet_build_ipv4( LIBNET_IPV4_H + packet_size, /* length */ 0, /* TOS */ 242, /* IP ID */ 0, /* IP Frag */ 128, /* TTL */ mpls_data->proto, /* protocol */ 0, /* checksum */ htonl(mpls_data->src_ip), /* source IP */ htonl(mpls_data->dst_ip), /* destination IP */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build IP header",lhandler); libnet_clear_packet(lhandler); return; } t = libnet_build_mpls( mpls_data->label1, /* label */ mpls_data->exp1, /* experimental */ LIBNET_MPLS_BOS_ON, /* bottom of stack */ mpls_data->ttl1, /* ttl */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build MPLS header",lhandler); libnet_clear_packet(lhandler); return; } if (mpls_data->double_hdr) { t = libnet_build_mpls( mpls_data->label2, /* label */ mpls_data->exp2, /* experimental */ LIBNET_MPLS_BOS_OFF, /* bottom of stack */ mpls_data->ttl2, /* ttl */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build MPLS header",lhandler); libnet_clear_packet(lhandler); return; } } t = libnet_build_ethernet( mpls_data->mac_dest, /* ethernet destination */ mpls_data->mac_source, /* ethernet source */ ETHERTYPE_MPLS, /* protocol type */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build Ethernet header",lhandler); libnet_clear_packet(lhandler); return; } /* * Write it to the wire. */ sent = libnet_write(lhandler); if (sent == -1) { thread_libnet_error("libnet_write error", lhandler); libnet_clear_packet(lhandler); return; } libnet_clear_packet(lhandler); protocols[PROTO_MPLS].packets_out++; iface_data2 = interfaces_get_struct(iface_data->ifname); iface_data2->packets_out[PROTO_MPLS]++; } }
/* * Uptime thread... */ void * th_uptime(void *arg) { int ret,n; struct timeval timeout; sigset_t mask; write_log(0,"\n th_uptime thread = %d\n",(int)pthread_self()); sigfillset(&mask); if (pthread_sigmask(SIG_BLOCK, &mask, NULL)) { thread_error("th_uptime pthread_sigmask()",errno); th_uptime_exit(); } if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL)) { thread_error("th_uptime pthread_setcancelstate()",errno); th_uptime_exit(); } pthread_cleanup_push( &th_uptime_clean, (void *)NULL ); if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) { thread_error("th_uptime pthread_setcancelstate()",errno); th_uptime_exit(); } if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { n=errno; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); thread_error("th_uptime pthread_setcanceltype()",n); th_uptime_exit(); } while(1) { timeout.tv_sec = 1; timeout.tv_usec = 0; if ( (ret=select( 0, NULL, NULL, NULL, &timeout ) ) == -1 ) { n=errno; thread_error("th_uptime select()",n); continue; } if ( !ret ) /* Timeout, update uptime... */ uptime++; } pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_cleanup_pop(0); return (NULL); }
/** * @brief Program entry point. * @param argc The argument count * @param argv The argument vector * @return EXIT_SUCCESS, EXIT_PARITY_ERROR, EXIT_MULTIPLE_ERRORS **/ int main(int argc, char *argv[]) { uint8_t client_count = 0; int shmfd; /* setup signal handlers */ const int signals[] = {SIGINT, SIGTERM}; struct sigaction s; s.sa_handler = signal_handler; s.sa_flags = 0; if(sigfillset(&s.sa_mask) < 0) { bail_out(EXIT_FAILURE, "sigfillset"); } for(int i = 0; i < COUNT_OF(signals); i++) { if (sigaction(signals[i], &s, NULL) < 0) { bail_out(EXIT_FAILURE, "sigaction"); } } /* Handle arguments */ if (argc > 0) { progname = argv[0]; } if (argc > 2) { fprintf(stderr, "USAGE: %s [input_file]", progname); exit(EXIT_FAILURE); } switch (argc) { /* Handle dict input from stdin */ case 1: printf("Please input your dictionary: \n"); in_stream = stdin; read_dict(); break; /* Handle dict input from file */ case 2: if ((in_stream = fopen(argv[1], "r")) == NULL) { bail_out(EXIT_FAILURE, "Invalid File"); } read_dict(); break; default: fprintf(stderr, "USAGE: %s [input_file]", progname); exit(EXIT_FAILURE); break; } /* Create a new Shared Memory Segment (shm_open) */ shmfd = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_EXCL, PERMISSION); if (shmfd == (-1)) { bail_out(EXIT_FAILURE, "shm_open failed"); } /* Truncate a file to a specified length extend (set size) */ if (ftruncate(shmfd, sizeof *shared) == -1) { (void) close(shmfd); bail_out(EXIT_FAILURE, "ftruncate failed"); } /* Map shared memory object */ shared = mmap(NULL, sizeof *shared, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); if (shared == MAP_FAILED) { (void) close(shmfd); bail_out(EXIT_FAILURE, "MMAP failed"); } if (close(shmfd) == -1) { bail_out(EXIT_FAILURE, "close(shmfd) failed"); } shared->sc_terminate = -1; /* Create new named semaphores */ s_server = sem_open(S_SERVER, O_CREAT | O_EXCL, PERMISSION, 0); s_client = sem_open(S_CLIENT, O_CREAT | O_EXCL, PERMISSION, 1); s_return = sem_open(S_RETURN, O_CREAT | O_EXCL, PERMISSION, 0); if(s_server == SEM_FAILED || s_client == SEM_FAILED || s_return == SEM_FAILED) { bail_out(EXIT_FAILURE, "sem_open(3) failed"); } sem_set = 1; struct ClientList *el_pre = NULL; struct ClientList *el_cur = NULL; /* Keep server open until it gets killed. */ while (!want_quit) { /* Critical section entry. */ /* Wait until server is allowed to access SHM. */ if (sem_wait(s_server) == -1) { if(errno == EINTR) continue; bail_out(EXIT_FAILURE, "sem_wait(3) failed"); } /* Setup data for existing client. */ if (shared->s_id >= 0) { el_cur = client_list; while (el_cur != NULL && el_cur->server_id != shared->s_id) { printf("elpre\n"); el_pre = el_cur; printf("elcur\n"); el_cur = el_cur->next; } if (el_cur == NULL) { bail_out(EXIT_FAILURE, "Client does not exist"); } el_cur->guess = shared->c_guess; } /* Setup new client to list. */ if (shared->s_id == -1) { /* Allocate element and set to zero. */ el_cur = (struct ClientList *) calloc (1, sizeof(struct ClientList)); if (el_cur == NULL) { bail_out(EXIT_FAILURE, "calloc(3) failed"); } /* Assign unique ID based on client count. */ el_cur->server_id = client_count++; el_cur->game_count = 0; /* Add the current element to our list. */ el_cur->next = client_list; client_list = el_cur; } /* Check if client has terminated. */ if (shared->sc_terminate >= 1) { DEBUG("Terminating client...\n"); /* Remove client from list. */ if (client_list == el_cur) { client_list = el_cur->next; } else { el_pre->next = el_cur->next; } free(el_cur); /* Free allocated resources. */ /* Reset sc_terminate. */ shared->sc_terminate = -1; if (sem_post(s_client) == -1) { bail_out(EXIT_FAILURE, "sem_post(3) failed"); } /* Skip the rest of the game as we have nothing to do here */ continue; } /* Check game status of client. */ if (shared->status_id == CreateGame) { /* Start a new game. */ DEBUG("Setting up game for client %d\n", shared->s_id); create_game(el_cur); } if (shared->status_id == Running) { /* Check guess. */ DEBUG("Checking guess of client %d\n", shared->s_id); check_guess(el_cur); } /* Write server answer back into SHM. */ shared->s_id = el_cur->server_id; shared->status_id = el_cur->status_id; shared->s_errors = el_cur->errors; strncpy(shared->s_word, el_cur->client_word, MAX_DATA); /* Let the client know that there is an answer. */ if (sem_post(s_return) == -1) { bail_out(EXIT_FAILURE, "sem_post(3) failed"); } /* critical section end. */ } /* Free stuff */ free(strings); }
int my_waitpid (int pid, int *status, int flags) { int ret, out_errno; linux_debug ("my_waitpid (%d, 0x%x)\n", pid, flags); if (flags & __WALL) { sigset_t block_mask, org_mask, wake_mask; int wnohang; wnohang = (flags & WNOHANG) != 0; flags &= ~(__WALL | __WCLONE); if (!wnohang) { flags |= WNOHANG; /* Block all signals while here. This avoids knowing about LinuxThread's signals. */ sigfillset (&block_mask); sigprocmask (SIG_BLOCK, &block_mask, &org_mask); /* ... except during the sigsuspend below. */ sigemptyset (&wake_mask); } while (1) { /* Since all signals are blocked, there's no need to check for EINTR here. */ ret = waitpid (pid, status, flags); out_errno = errno; if (ret == -1 && out_errno != ECHILD) break; else if (ret > 0) break; if (flags & __WCLONE) { /* We've tried both flavors now. If WNOHANG is set, there's nothing else to do, just bail out. */ if (wnohang) break; linux_debug ("blocking\n"); /* Block waiting for signals. */ sigsuspend (&wake_mask); } flags ^= __WCLONE; } if (!wnohang) sigprocmask (SIG_SETMASK, &org_mask, NULL); } else { do ret = waitpid (pid, status, flags); while (ret == -1 && errno == EINTR); out_errno = errno; } linux_debug ("my_waitpid (%d, 0x%x): status(%x), %d\n", pid, flags, status ? *status : -1, ret); errno = out_errno; return ret; }
int stub_pid1(sd_id128_t uuid) { enum { STATE_RUNNING, STATE_REBOOT, STATE_POWEROFF, } state = STATE_RUNNING; sigset_t fullmask, oldmask, waitmask; usec_t quit_usec = USEC_INFINITY; pid_t pid; int r; /* The new environment we set up, on the stack. */ char new_environment[] = "container=systemd-nspawn\0" "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful * for allowing arbitrary processes run in a container, and still have all zombies reaped. */ assert_se(sigfillset(&fullmask) >= 0); assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0); pid = fork(); if (pid < 0) return log_error_errno(errno, "Failed to fork child pid: %m"); if (pid == 0) { /* Return in the child */ assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0); setsid(); return 0; } reset_all_signal_handlers(); log_close(); close_all_fds(NULL, 0); log_open(); /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also, * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ * find them set. */ sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX); reset_environ(new_environment, sizeof(new_environment)); rename_process("STUBINIT"); assert_se(sigemptyset(&waitmask) >= 0); assert_se(sigset_add_many(&waitmask, SIGCHLD, /* posix: process died */ SIGINT, /* sysv: ctrl-alt-del */ SIGRTMIN+3, /* systemd: halt */ SIGRTMIN+4, /* systemd: poweroff */ SIGRTMIN+5, /* systemd: reboot */ SIGRTMIN+6, /* systemd: kexec */ SIGRTMIN+13, /* systemd: halt */ SIGRTMIN+14, /* systemd: poweroff */ SIGRTMIN+15, /* systemd: reboot */ SIGRTMIN+16, /* systemd: kexec */ -1) >= 0); /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't * support reexec/reloading in this stub process. */ for (;;) { siginfo_t si; usec_t current_usec; si.si_pid = 0; r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG); if (r < 0) { r = log_error_errno(errno, "Failed to reap children: %m"); goto finish; } current_usec = now(CLOCK_MONOTONIC); if (si.si_pid == pid || current_usec >= quit_usec) { /* The child we started ourselves died or we reached a timeout. */ if (state == STATE_REBOOT) { /* dispatch a queued reboot */ (void) reboot(RB_AUTOBOOT); r = log_error_errno(errno, "Failed to reboot: %m"); goto finish; } else if (state == STATE_POWEROFF) (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */ if (si.si_pid == pid && si.si_code == CLD_EXITED) r = si.si_status; /* pass on exit code */ else r = 255; /* signal, coredump, timeout, … */ goto finish; } if (si.si_pid != 0) /* We reaped something. Retry until there's nothing more to reap. */ continue; if (quit_usec == USEC_INFINITY) r = sigwaitinfo(&waitmask, &si); else { struct timespec ts; r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec)); } if (r < 0) { if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */ continue; if (errno == EAGAIN) /* timeout reached */ continue; r = log_error_errno(errno, "Failed to wait for signal: %m"); goto finish; } if (si.si_signo == SIGCHLD) continue; /* Let's reap this */ if (state != STATE_RUNNING) continue; /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a * constant… */ if (si.si_signo == SIGRTMIN+3 || si.si_signo == SIGRTMIN+4 || si.si_signo == SIGRTMIN+13 || si.si_signo == SIGRTMIN+14) state = STATE_POWEROFF; else if (si.si_signo == SIGINT || si.si_signo == SIGRTMIN+5 || si.si_signo == SIGRTMIN+6 || si.si_signo == SIGRTMIN+15 || si.si_signo == SIGRTMIN+16) state = STATE_REBOOT; else assert_not_reached("Got unexpected signal"); r = kill_and_sigcont(pid, SIGTERM); /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those * processes which handle both. That's because services tend to bind configuration reload or something * else to SIGHUP. */ if (r != -ESRCH) (void) kill(pid, SIGHUP); quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC; } finish: _exit(r < 0 ? EXIT_FAILURE : r); }
/** * Set up log file and run in the backgroud */ void daemonize() { #ifdef WINDOWS if (!debug) { int fd; FILE *pidfh; if ((fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) { perror("Can't open log file"); exit(1); } if (strcmp(pidfile, "")) { // Write out the pid file, before we redirect STDERR to the log. if ((pidfh = fopen(pidfile, "w")) == NULL) { perror("Can't open pid file for writing"); exit(1); } fprintf(pidfh, "%d\n", GetCurrentProcessId()); fclose(pidfh); } dup2(fd, 2); close(fd); applog = stderr; } #else // WINDOWS if (!debug) { int pid, fd; FILE *pidfh; if ((fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) { perror("Can't open log file"); exit(1); } if ((pid = fork()) == -1) { perror("Couldn't fork"); exit(1); } else if (pid > 0) { parent = 1; exit(0); } if (strcmp(pidfile, "")) { // Write out the pid file, before we redirect STDERR to the log. if ((pidfh = fopen(pidfile, "w")) == NULL) { perror("Can't open pid file for writing"); exit(1); } fprintf(pidfh, "%d\n", getpid()); fclose(pidfh); } setsid(); dup2(fd, 2); close(fd); for (fd = 0; fd < 30; fd++) { if ((fd != 2) && (fd != listener)) { close(fd); } } #ifdef VMS chdir("SYS$LOGIN"); #else chdir("/"); #endif umask(0); applog = stderr; } nice(-20); { struct sigaction act; sigfillset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; act.sa_handler = gotsig; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); act.sa_handler = gotpipe; sigaction(SIGPIPE, &act, NULL); act.sa_handler = SIG_IGN; sigaction(SIGCHLD, &act, NULL); } #endif // WINDOWS }
int schedule_unload(pid_t pid, FAR struct binary_s *bin) { struct sigaction act; struct sigaction oact; sigset_t sigset; irqstate_t flags; int errorcode; int ret; /* Make sure that SIGCHLD is unmasked */ (void)sigemptyset(&sigset); (void)sigaddset(&sigset, SIGCHLD); ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL); if (ret != OK) { /* The errno value will get trashed by the following debug output */ errorcode = get_errno(); bvdbg("ERROR: sigprocmask failed: %d\n", ret); goto errout; } /* Add the structure to the list. We want to do this *before* connecting * the signal handler. This does, however, make error recovery more * complex if sigaction() fails below because then we have to remove the * unload structure for the list in an unexpected context. */ unload_list_add(pid, bin); /* Register the SIGCHLD handler */ act.sa_sigaction = unload_callback; act.sa_flags = SA_SIGINFO; (void)sigfillset(&act.sa_mask); (void)sigdelset(&act.sa_mask, SIGCHLD); ret = sigaction(SIGCHLD, &act, &oact); if (ret != OK) { /* The errno value will get trashed by the following debug output */ errorcode = get_errno(); bvdbg("ERROR: sigaction failed: %d\n" , ret); /* Emergency removal from the list */ flags = irqsave(); if (unload_list_remove(pid) != bin) { blldbg("ERROR: Failed to remove structure\n"); } goto errout; } return OK; errout: set_errno(errorcode); return ERROR; }
void CnxtAdslLEDTask(void *sem) { BOOL HandShakeLED; BOOL ShowtimeLED; struct task_struct *tsk = current ; tsk->session = 1 ; tsk->pgrp = 1 ; #if defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE) strcpy ( tsk->comm, "CnxtGshdslLEDTask" ) ; #else strcpy ( tsk->comm, "CnxtAdslLEDTask" ) ; #endif /* sigstop and sigcont will stop and wakeup kupdate */ spin_lock_irq(&tsk->sigmask_lock); sigfillset(&tsk->blocked); siginitsetinv(¤t->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); up((struct semaphore *)sem); TaskDelayConnect ( GP_TIMER_DMT_LED ) ; while(1) { /* Condensed Showtime State to two Booleans - In Showtime and In Training */ ShowtimeLED= FALSE; HandShakeLED= FALSE; switch (HWSTATE.dwLineStatus) { case HW_IO_MODEM_STATUS_ACTIVATED: ShowtimeLED= TRUE; break; case HW_IO_MODEM_STATUS_CHANNEL_ANALYSIS: case HW_IO_MODEM_STATUS_TRANSCEIVER_TRAINING: case HW_IO_MODEM_STATUS_EXCHANGE: case HW_IO_MODEM_STATUS_ACTIVATION: HandShakeLED= TRUE; break; } /* Blink Showtime LED if in Training */ if (ShowtimeLED || HandShakeLED) { WriteGPIOData( GPOUT_SHOWTIME_LED,LED_ON ); } /* This logic is for a blinking Showtime LED */ if (!ShowtimeLED) { WriteGPIOData( GPOUT_SHOWTIME_LED,LED_OFF ); } TaskDelayMsec(LED_DELAY_PERIOD); } }
int main(int argc, char *argv[]) { static struct sigaction act; act.sa_handler = get_signal; sigfillset(&(act.sa_mask)); sigaction(SIGSEGV, &act, NULL); int no_curses = 0; extern char *optarg; extern int optind, optopt; int c, refresh_tmp_time = 0; char *endptr; while ((c = getopt(argc, argv, ":r:ch")) != -1) { switch (c) { case 'r': refresh_tmp_time = (int) strtol(optarg, &endptr, 10); if ((refresh_tmp_time) && (refresh_tmp_time < 30)) { refresh_time = refresh_tmp_time * 1000; } break; case 'c': no_curses = 1; break; case 'h': printf("Usage: dbtop [parameters]\n"); printf("no parameters - standart ncurses mode\n\n"); printf("parameters:\n"); printf("-r interval - refresh interval for ncurses mode(in seconds)\n"); printf("-c - show one time users list (no ncurses)\n"); exit(0); break; } } _socket = connect_to_server_dbtop(); in = fdopen(_socket, "r+"); out = fdopen(_socket, "w"); if (!in || !out) { printf("Can't connect to socket. Maybe governor is not started\n"); exit(-1); } if (no_curses) { client_type_t ctt = DBTOPCL; fwrite(&ctt, sizeof(client_type_t), 1, out); fflush(out); accounts = NULL; recv_accounts = NULL; read_info(); printOneScreenNoCurses(); exit(0); } /// /*client_type_t ctt = DBTOP; fwrite(&ctt, sizeof(client_type_t), 1, out); fflush(out);*/ accounts = NULL; recv_accounts = NULL; initscr(); signal(SIGALRM, end_pgm); signal(SIGHUP, end_pgm); signal(SIGPIPE, end_pgm); signal(SIGQUIT, end_pgm); signal(SIGTERM, end_pgm); signal(SIGINT, end_pgm); noecho(); nonl(); intrflush(stdscr, false); keypad(stdscr, true); curs_set(0); if (has_colors()) { start_color(); use_default_colors(); init_pair(1, COLOR_GREEN, COLOR_BLUE); init_pair(2, COLOR_BLUE, -1); init_pair(3, COLOR_RED, -1); } raw(); halfdelay(5); read_keys(); closesock(); }
static pid_t spawn_ras(struct ast_channel *chan, char *args) { pid_t pid; int x; char *c; char *argv[PPP_MAX_ARGS]; int argc = 0; char *stringp=NULL; sigset_t fullset, oldset; sigfillset(&fullset); pthread_sigmask(SIG_BLOCK, &fullset, &oldset); /* Start by forking */ pid = fork(); if (pid) { pthread_sigmask(SIG_SETMASK, &oldset, NULL); return pid; } /* Restore original signal handlers */ for (x=0;x<NSIG;x++) signal(x, SIG_DFL); pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); /* Execute RAS on File handles */ dup2(chan->fds[0], STDIN_FILENO); /* Drop high priority */ if (ast_opt_high_priority) ast_set_priority(0); /* Close other file descriptors */ for (x=STDERR_FILENO + 1;x<1024;x++) close(x); /* Reset all arguments */ memset(argv, 0, sizeof(argv)); /* First argument is executable, followed by standard arguments for dahdi PPP */ argv[argc++] = PPP_EXEC; argv[argc++] = "nodetach"; /* And all the other arguments */ stringp=args; c = strsep(&stringp, ","); while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) { argv[argc++] = c; c = strsep(&stringp, ","); } argv[argc++] = "plugin"; argv[argc++] = "dahdi.so"; argv[argc++] = "stdin"; /* Finally launch PPP */ execv(PPP_EXEC, argv); fprintf(stderr, "Failed to exec PPPD!\n"); exit(1); }
int _SMERP_posixMain( int argc, char* argv[] ) { // i18n global stuff if ( setlocale( LC_ALL, "" ) == NULL ) { std::cerr << "Unable to set locale. Falling back to default." << std::endl; } else { if ( bindtextdomain( "SMERP", "../po" ) == NULL ) { std::cerr << "Not enough memory to bind textdomain" << std::endl; return _SMERP::ErrorCodes::FAILURE; } if ( textdomain( "SMERP" ) == NULL ) { std::cerr << "Not enough memory to set textdomain" << std::endl; return _SMERP::ErrorCodes::FAILURE; } } // end of i18n global stuff try { _SMERP::Version appVersion( MAJOR_VERSION, MINOR_VERSION, REVISION_NUMBER ); _SMERP::CmdLineConfig cmdLineCfg; const char *configFile; // it's just a DUMMY for now _SMERP::HandlerConfiguration handlerConfig; if ( !cmdLineCfg.parse( argc, argv )) { // there was an error parsing the command line std::cerr << cmdLineCfg.errMsg() << std::endl << std::endl; cmdLineCfg.usage( std::cerr ); std::cerr << std::endl; return _SMERP::ErrorCodes::FAILURE; } // command line has been parsed successfully // if cmdLineCfg.errMsg() is not empty than we have a warning if ( !cmdLineCfg.errMsg().empty() ) // there was a warning parsing the command line std::cerr << "BOO:" << cmdLineCfg.errMsg() << std::endl << std::endl; // if we have to print the version or the help do it and exit if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_VERSION ) { std::cout << std::endl << gettext( "BOBOBO version " ) << appVersion.toString() << std::endl << std::endl; return _SMERP::ErrorCodes::OK; } if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_HELP ) { std::cout << std::endl << gettext( "BOBOBO version " ) << appVersion.toString() << std::endl; cmdLineCfg.usage( std::cout ); std::cout << std::endl; return _SMERP::ErrorCodes::OK; } // decide what configuration file to use if ( !cmdLineCfg.cfgFile.empty() ) // if it has been specified than that's The One ! (and only) configFile = cmdLineCfg.cfgFile.c_str(); else configFile = _SMERP::CfgFileConfig::chooseFile( DEFAULT_MAIN_CONFIG, DEFAULT_USER_CONFIG, DEFAULT_LOCAL_CONFIG ); if ( configFile == NULL ) { // there is no configuration file std::cerr << gettext ( "MOMOMO: no configuration file found !" ) << std::endl << std::endl; return _SMERP::ErrorCodes::FAILURE; } _SMERP::CfgFileConfig cfgFileCfg; if ( !cfgFileCfg.parse( configFile )) { // there was an error parsing the configuration file std::cerr << cfgFileCfg.errMsg() << std::endl << std::endl; return _SMERP::ErrorCodes::FAILURE; } else if ( !cfgFileCfg.errMsg().empty()) std::cerr << cfgFileCfg.errMsg() << std::endl; // configuration file has been parsed successfully // build the application configuration _SMERP::ApplicationConfiguration config( cmdLineCfg, cfgFileCfg); // now here we know where to log to on stderr _SMERP::LogBackend::instance().setConsoleLevel( config.stderrLogLevel ); // Check the configuration if ( cmdLineCfg.command == _SMERP::CmdLineConfig::CHECK_CONFIG ) { std::cout << std::endl << gettext( "BOBOBO version " ) << appVersion.toString() << std::endl; if ( config.check() ) { if ( config.errMsg().empty() ) { std::cout << "Configuration OK" << std::endl << std::endl; return _SMERP::ErrorCodes::OK; } else { std::cout << "WARNING: " << config.errMsg() << std::endl << std::endl; return _SMERP::ErrorCodes::OK; } } else { std::cout << "ERROR: " << config.errMsg() << std::endl << std::endl; return _SMERP::ErrorCodes::OK; } } if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_CONFIG ) { std::cout << std::endl << gettext( "BOBOBO version " ) << appVersion.toString() << std::endl; config.print( std::cout ); std::cout << std::endl; return _SMERP::ErrorCodes::OK; } if ( cmdLineCfg.command == _SMERP::CmdLineConfig::TEST_CONFIG ) { std::cout << "Not implemented yet" << std::endl << std::endl; return _SMERP::ErrorCodes::OK; } // Daemon stuff if( !config.foreground ) { // Aba: maybe also in the foreground? // try to lock the pidfile, bail out if not possible if( boost::filesystem::exists( config.pidFile ) ) { boost::interprocess::file_lock lock( config.pidFile.c_str( ) ); if( lock.try_lock( ) ) { std::cerr << "Pidfile is locked, another daemon running?" << std::endl; return _SMERP::ErrorCodes::FAILURE; } } // daemonize, lose process group, terminal output, etc. if( daemon( 0, 0 ) ) { std::cerr << "Daemonizing server failed" << std::endl; return _SMERP::ErrorCodes::FAILURE; } // now here we lost constrol over the console, we should // create a temporary logger which at least tells what's // going on in the syslog _SMERP::LogBackend::instance().setSyslogLevel( config.syslogLogLevel ); _SMERP::LogBackend::instance().setSyslogFacility( config.syslogFacility ); _SMERP::LogBackend::instance().setSyslogIdent( config.syslogIdent ); // if we are root we can drop privileges now struct group *groupent; struct passwd *passwdent; groupent = getgrnam( config.group.c_str( ) ); passwdent = getpwnam( config.user.c_str( ) ); if( groupent == NULL || passwdent == NULL ) { LOG_CRITICAL << "Illegal group '" << config.group << "' or user '" << config.user << "'"; return _SMERP::ErrorCodes::FAILURE; } if( setgid( groupent->gr_gid ) < 0 ) { LOG_CRITICAL << "setgid for group '" << config.group << "' failed!"; return _SMERP::ErrorCodes::FAILURE; } if( setuid( passwdent->pw_uid ) < 0 ) { LOG_CRITICAL << "setgid for user '" << config.user << "' failed!"; return _SMERP::ErrorCodes::FAILURE; } // create a pid file and lock id std::ofstream pidFile( config.pidFile.c_str( ), std::ios_base::trunc ); if( !pidFile.good( ) ) { LOG_CRITICAL << "Unable to create PID file '" << config.pidFile << "'!"; return _SMERP::ErrorCodes::FAILURE; } pidFile << getpid( ) << std::endl; pidFile.close( ); // Create the final logger based on the configuration // file logger only here to get the right permissions _SMERP::LogBackend::instance().setLogfileLevel( config.logFileLogLevel ); _SMERP::LogBackend::instance().setLogfileName( config.logFile ); } // Block all signals for background thread. sigset_t new_mask; sigfillset( &new_mask ); sigset_t old_mask; pthread_sigmask( SIG_BLOCK, &new_mask, &old_mask ); LOG_NOTICE << "Starting server"; // Run server in background thread(s). _SMERP::ServerHandler handler( handlerConfig ); _SMERP::Network::server s( config.address, config.SSLaddress, handler, config.threads, config.maxConnections ); boost::thread t( boost::bind( &_SMERP::Network::server::run, &s )); // Restore previous signals. pthread_sigmask( SIG_SETMASK, &old_mask, 0 ); // Wait for signal indicating time to shut down. sigset_t wait_mask; sigemptyset( &wait_mask ); sigaddset( &wait_mask, SIGINT ); sigaddset( &wait_mask, SIGQUIT ); sigaddset( &wait_mask, SIGTERM ); pthread_sigmask( SIG_BLOCK, &wait_mask, 0 ); int sig = 0; sigwait( &wait_mask, &sig ); // Stop the server. LOG_INFO << "Stopping server"; s.stop(); t.join(); LOG_NOTICE << "Server stopped"; // Daemon stuff if( !config.foreground ) { (void)remove( config.pidFile.c_str( ) ); } } catch (std::exception& e) { // Aba: how to delete the pid file here? LOG_ERROR << "posixMain: exception: " << e.what() << "\n"; return _SMERP::ErrorCodes::FAILURE; } return _SMERP::ErrorCodes::OK; }
void Sigfillset(sigset_t *set) { if (sigfillset(set) < 0) unix_error("Sigfillset error"); return; }
int _sigaction(int sig, const struct sigaction * act, struct sigaction * oact) { int ret = 0; struct sigaction gact; /* Check if the signal number is out of range: */ if (sig < 1 || sig > NSIG) { /* Return an invalid argument: */ errno = EINVAL; ret = -1; } else { if (_thread_initial == NULL) _thread_init(); /* * Check if the existing signal action structure contents are * to be returned: */ if (oact != NULL) { /* Return the existing signal action contents: */ oact->sa_handler = _thread_sigact[sig - 1].sa_handler; oact->sa_mask = _thread_sigact[sig - 1].sa_mask; oact->sa_flags = _thread_sigact[sig - 1].sa_flags; } /* Check if a signal action was supplied: */ if (act != NULL) { /* Set the new signal handler: */ _thread_sigact[sig - 1].sa_mask = act->sa_mask; _thread_sigact[sig - 1].sa_flags = act->sa_flags; _thread_sigact[sig - 1].sa_handler = act->sa_handler; } /* * Check if the kernel needs to be advised of a change * in signal action: */ if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD && sig != SIGINFO) { /* * Ensure the signal handler cannot be interrupted * by other signals. Always request the POSIX signal * handler arguments. */ sigfillset(&gact.sa_mask); gact.sa_flags = SA_SIGINFO | SA_RESTART; /* * Check if the signal handler is being set to * the default or ignore handlers: */ if (act->sa_handler == SIG_DFL || act->sa_handler == SIG_IGN) /* Specify the built in handler: */ gact.sa_handler = act->sa_handler; else /* * Specify the thread kernel signal * handler: */ gact.sa_handler = (void (*) ()) _thread_sig_handler; /* Change the signal action in the kernel: */ if (__sys_sigaction(sig,&gact,NULL) != 0) ret = -1; } } /* Return the completion status: */ return (ret); }
int main(int argc, char *argv[]) { _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_udev_event_unref_ struct udev_event *event = NULL; _cleanup_udev_device_unref_ struct udev_device *dev = NULL; _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL; char syspath[UTIL_PATH_SIZE]; const char *devpath; const char *action; sigset_t mask, sigmask_orig; int err; err = fake_filesystems(); if (err < 0) return EXIT_FAILURE; udev = udev_new(); if (udev == NULL) return EXIT_FAILURE; log_debug("version %s", VERSION); mac_selinux_init("/dev"); sigprocmask(SIG_SETMASK, NULL, &sigmask_orig); action = argv[1]; if (action == NULL) { log_error("action missing"); goto out; } devpath = argv[2]; if (devpath == NULL) { log_error("devpath missing"); goto out; } rules = udev_rules_new(udev, 1); strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL); dev = udev_device_new_from_syspath(udev, syspath); if (dev == NULL) { log_debug("unknown device '%s'", devpath); goto out; } udev_device_set_action(dev, action); event = udev_event_new(dev); sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); if (event->fd_signal < 0) { fprintf(stderr, "error creating signalfd\n"); goto out; } /* do what devtmpfs usually provides us */ if (udev_device_get_devnode(dev) != NULL) { mode_t mode = 0600; if (streq(udev_device_get_subsystem(dev), "block")) mode |= S_IFBLK; else mode |= S_IFCHR; if (!streq(action, "remove")) { mkdir_parents_label(udev_device_get_devnode(dev), 0755); mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev)); } else { unlink(udev_device_get_devnode(dev)); rmdir_parents(udev_device_get_devnode(dev), "/"); } } udev_event_execute_rules(event, 3 * USEC_PER_SEC, USEC_PER_SEC, NULL, rules, &sigmask_orig); udev_event_execute_run(event, 3 * USEC_PER_SEC, USEC_PER_SEC, NULL); out: if (event != NULL && event->fd_signal >= 0) close(event->fd_signal); mac_selinux_finish(); return err ? EXIT_FAILURE : EXIT_SUCCESS; }
int _aio_init(thread_pool_attr_t *pool_attr) { static thread_pool_attr_t default_pool_attr = { NULL, _aio_block, _aio_unblock, _aio_handler, _aio_context_alloc, _aio_context_free, NULL, 3, 1, 8, 10 }; struct _aio_control_block *cb; struct _aio_context *ctp; struct _aio_prio_list *plist; sigset_t set, oset; int i; _mutex_lock(&_aio_init_mutex); if (_aio_cb) { _mutex_unlock(&_aio_init_mutex); return 0; } if ((cb = malloc(sizeof(*_aio_cb))) == NULL) { _mutex_unlock(&_aio_init_mutex); return -1; } memset(cb, 0, sizeof(*cb)); pthread_mutex_init(&cb->cb_mutex, 0); (void)pthread_cond_init(&cb->cb_cond, 0); if (pool_attr == NULL) { pool_attr = &default_pool_attr; } else { pool_attr->block_func = _aio_block; pool_attr->context_alloc = _aio_context_alloc; pool_attr->unblock_func = _aio_unblock; pool_attr->handler_func = _aio_handler; pool_attr->context_free = _aio_context_free; } pool_attr->handle = (void *)cb; /* prepare some priority list entries */ for (i = 0; i < _AIO_PRIO_LIST_LOW; i++) { plist = (struct _aio_prio_list *)malloc(sizeof(*plist)); if (!plist) { goto err_ret; } plist->next = cb->cb_plist_free; cb->cb_plist_free = plist; } cb->cb_nfree = _AIO_PRIO_LIST_LOW; /* prepare the context */ cb->ct_free = NULL; for (i = 0; i < pool_attr->maximum; i++) { if ((ctp = malloc(sizeof(*ctp))) == NULL) { goto err_ret; } ctp->next = cb->ct_free; cb->ct_free = ctp; } cb->tp = thread_pool_create(pool_attr, 0); if (cb->tp == NULL) { goto err_ret; } /* we can hook _aio_cb now */ _aio_cb = cb; /* start the pool with all sigal blocked */ if (sigfillset(&set) != 0 || (errno = pthread_sigmask(SIG_BLOCK, &set, &oset)) != EOK) { goto err_ret; } if (thread_pool_start(cb->tp) != EOK) { pthread_sigmask(SIG_SETMASK, &oset, NULL); goto err_ret; } pthread_sigmask(SIG_SETMASK, &oset, NULL); _mutex_unlock(&_aio_init_mutex); return 0; err_ret: _mutex_lock(&cb->cb_mutex); if (cb->tp) { (void)thread_pool_destroy(cb->tp); } while ((plist = cb->cb_plist_free)) { cb->cb_plist_free = plist->next; free(plist); } while ((ctp = cb->ct_free)) { cb->ct_free = ctp->next; free(ctp); } pthread_cond_destroy(&cb->cb_cond); pthread_mutex_destroy(&cb->cb_mutex); free(cb); _mutex_unlock(&_aio_init_mutex); return -1; }
void Subprocess::spawnInternal( std::unique_ptr<const char*[]> argv, const char* executable, Options& options, const std::vector<std::string>* env, int errFd) { // Parent work, pre-fork: create pipes std::vector<int> childFds; // Close all of the childFds as we leave this scope SCOPE_EXIT { // These are only pipes, closing them shouldn't fail for (int cfd : childFds) { CHECK_ERR(::close(cfd)); } }; int r; for (auto& p : options.fdActions_) { if (p.second == PIPE_IN || p.second == PIPE_OUT) { int fds[2]; // We're setting both ends of the pipe as close-on-exec. The child // doesn't need to reset the flag on its end, as we always dup2() the fd, // and dup2() fds don't share the close-on-exec flag. #if FOLLY_HAVE_PIPE2 // If possible, set close-on-exec atomically. Otherwise, a concurrent // Subprocess invocation can fork() between "pipe" and "fnctl", // causing FDs to leak. r = ::pipe2(fds, O_CLOEXEC); checkUnixError(r, "pipe2"); #else r = ::pipe(fds); checkUnixError(r, "pipe"); r = fcntl(fds[0], F_SETFD, FD_CLOEXEC); checkUnixError(r, "set FD_CLOEXEC"); r = fcntl(fds[1], F_SETFD, FD_CLOEXEC); checkUnixError(r, "set FD_CLOEXEC"); #endif pipes_.emplace_back(); Pipe& pipe = pipes_.back(); pipe.direction = p.second; int cfd; if (p.second == PIPE_IN) { // Child gets reading end pipe.pipe = folly::File(fds[1], /*owns_fd=*/ true); cfd = fds[0]; } else { pipe.pipe = folly::File(fds[0], /*owns_fd=*/ true); cfd = fds[1]; } p.second = cfd; // ensure it gets dup2()ed pipe.childFd = p.first; childFds.push_back(cfd); } } // This should already be sorted, as options.fdActions_ is DCHECK(std::is_sorted(pipes_.begin(), pipes_.end())); // Note that the const casts below are legit, per // http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html char** argVec = const_cast<char**>(argv.get()); // Set up environment std::unique_ptr<const char*[]> envHolder; char** envVec; if (env) { envHolder = cloneStrings(*env); envVec = const_cast<char**>(envHolder.get()); } else { envVec = environ; } // Block all signals around vfork; see http://ewontfix.com/7/. // // As the child may run in the same address space as the parent until // the actual execve() system call, any (custom) signal handlers that // the parent has might alter parent's memory if invoked in the child, // with undefined results. So we block all signals in the parent before // vfork(), which will cause them to be blocked in the child as well (we // rely on the fact that Linux, just like all sane implementations, only // clones the calling thread). Then, in the child, we reset all signals // to their default dispositions (while still blocked), and unblock them // (so the exec()ed process inherits the parent's signal mask) // // The parent also unblocks all signals as soon as vfork() returns. sigset_t allBlocked; r = sigfillset(&allBlocked); checkUnixError(r, "sigfillset"); sigset_t oldSignals; r = pthread_sigmask(SIG_SETMASK, &allBlocked, &oldSignals); checkPosixError(r, "pthread_sigmask"); SCOPE_EXIT { // Restore signal mask r = pthread_sigmask(SIG_SETMASK, &oldSignals, nullptr); CHECK_EQ(r, 0) << "pthread_sigmask: " << errnoStr(r); // shouldn't fail }; // Call c_str() here, as it's not necessarily safe after fork. const char* childDir = options.childDir_.empty() ? nullptr : options.childDir_.c_str(); pid_t pid = vfork(); if (pid == 0) { int errnoValue = prepareChild(options, &oldSignals, childDir); if (errnoValue != 0) { childError(errFd, kChildFailure, errnoValue); } errnoValue = runChild(executable, argVec, envVec, options); // If we get here, exec() failed. childError(errFd, kExecFailure, errnoValue); } // In parent. Make sure vfork() succeeded. checkUnixError(pid, errno, "vfork"); // Child is alive. We have to be very careful about throwing after this // point. We are inside the constructor, so if we throw the Subprocess // object will have never existed, and the destructor will never be called. // // We should only throw if we got an error via the errFd, and we know the // child has exited and can be immediately waited for. In all other cases, // we have no way of cleaning up the child. pid_ = pid; returnCode_ = ProcessReturnCode(RV_RUNNING); }
/* Helper: set the signal handler for evsignal to handler in base, so that * we can restore the original handler when we clear the current one. */ int _evsig_set_handler(struct event_base *base, int evsignal, void (__cdecl *handler)(int)) { #ifdef _EVENT_HAVE_SIGACTION struct sigaction sa; #else ev_sighandler_t sh; #endif struct evsig_info *sig = &base->sig; void *p; /* * resize saved signal handler array up to the highest signal number. * a dynamic array is used to keep footprint on the low side. */ if (evsignal >= sig->sh_old_max) { int new_max = evsignal + 1; event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing", __func__, evsignal, sig->sh_old_max)); p = mm_realloc(sig->sh_old, new_max * sizeof(*sig->sh_old)); if (p == NULL) { event_warn("realloc"); return (-1); } memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old), 0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old)); sig->sh_old_max = new_max; sig->sh_old = p; } /* allocate space for previous handler out of dynamic array */ sig->sh_old[evsignal] = mm_malloc(sizeof *sig->sh_old[evsignal]); if (sig->sh_old[evsignal] == NULL) { event_warn("malloc"); return (-1); } /* save previous handler and setup new handler */ #ifdef _EVENT_HAVE_SIGACTION memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; sa.sa_flags |= SA_RESTART; sigfillset(&sa.sa_mask); if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) { event_warn("sigaction"); mm_free(sig->sh_old[evsignal]); sig->sh_old[evsignal] = NULL; return (-1); } #else if ((sh = signal(evsignal, handler)) == SIG_ERR) { event_warn("signal"); mm_free(sig->sh_old[evsignal]); sig->sh_old[evsignal] = NULL; return (-1); } *sig->sh_old[evsignal] = sh; #endif return (0); }
static void spawn_pidone(int argc, char **argv, char **envp) { sigset_t set; if (getpid() != 1) { return; } sigfillset(&set); sigprocmask(SIG_BLOCK, &set, 0); main_pid = fork(); switch (main_pid) { case 0: sigprocmask(SIG_UNBLOCK, &set, NULL); setsid(); setpgid(0, 0); /* Child remains as pacemaker-remoted */ return; case -1: perror("fork"); } /* Parent becomes the reaper of zombie processes */ /* Safe to initialize logging now if needed */ #ifdef HAVE___PROGNAME /* Differentiate ourselves in the 'ps' output */ { char *p; int i, maxlen; char *LastArgv = NULL; const char *name = "pcmk-init"; for(i = 0; i < argc; i++) { if(!i || (LastArgv + 1 == argv[i])) LastArgv = argv[i] + strlen(argv[i]); } for(i = 0; envp[i] != NULL; i++) { if((LastArgv + 1) == envp[i]) { LastArgv = envp[i] + strlen(envp[i]); } } maxlen = (LastArgv - argv[0]) - 2; i = strlen(name); /* We can overwrite individual argv[] arguments */ snprintf(argv[0], maxlen, "%s", name); /* Now zero out everything else */ p = &argv[0][i]; while(p < LastArgv) *p++ = '\0'; argv[1] = NULL; } #endif /* HAVE___PROGNAME */ while (1) { int sig; size_t i; sigwait(&set, &sig); for (i = 0; i < DIMOF(sigmap); i++) { if (sigmap[i].sig == sig) { sigmap[i].handler(); break; } } } }
int main(int argc, char **argv) { char program_name[FILENAME_MAX_CHARS]; char config_file[FILENAME_MAX_CHARS]; int syslog; int loglevel; int logfacility; char c; int recoveryport; int error; int daemon_mode = 0; // init program_name and default config file strncpy(program_name, argv[0], FILENAME_MAX_CHARS); strncpy(config_file, DEFAULT_CONFIGFILE, FILENAME_MAX_CHARS); // init default log settings syslog = DEFAULT_USE_SYSLOG; loglevel = DEFAULT_LOG_LEVEL; logfacility = DEFAULT_LOG_FACILITY; // allow the user to set a special port for login recovery recoveryport = 0; //save start time for uptime calculation in status messages bgpmon_start_time = time(NULL); // parse command line while ((c = getopt (argc, argv, "dl:c:f:hsr:")) != -1) { switch (c) { case 'c': strncpy(config_file, optarg, FILENAME_MAX_CHARS); break; case 'l': loglevel = atoi(optarg); break; case 'f': logfacility = atoi(optarg); break; case 's': syslog = 1; break; case 'r': recoveryport = atoi(optarg); break; case 'd': daemon_mode = 1; break; case 'h': case '?': default : usage( argv[0] ); break; } } // if optind is less than the number of arguments from the command line (argc), then there // is something in the argument string that isn't preceded by valid switch (-c, -l, etc) if(optind<argc) { usage(argv[0]); } // initilaze log module if (init_log (program_name, syslog, loglevel, logfacility) ) { fprintf (stderr, "Failed to initialize log functions!\n"); exit(1); } #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized log module."); #endif log_msg("BGPmon starting up\n"); /* Turn into daemon if daemon_mode is set. */ if (daemon_mode){ godaemon(RUN_DIR,PID_FILE); } char scratchdir[FILENAME_MAX_CHARS]; sprintf(scratchdir,"%s/%s",RUN_DIR,"bgpmon"); // initialize login interface if (initLoginControlSettings(config_file, scratchdir, recoveryport) ) { log_fatal("Unable to initialize login interface"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized login module."); #endif // initialize acl if(initACLSettings()) { log_fatal("Unable to initialize ACL settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized acl module."); #endif // initialize the queue information if (initQueueSettings() ) { log_fatal("Unable to initialize queue settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized queue settings."); #endif // initialize clients control settings if (initClientsControlSettings() ) { log_fatal("Unable to initialize client settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized client settings."); #endif // initialize clients control settings if (initMrtControlSettings() ) { log_fatal("Unable to initialize mrt settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized mrt settings."); #endif // initialize chains settings if (initChainsSettings() ) { log_fatal("Unable to initialize chain settings"); }; // initialize the periodic settings if (initPeriodicSettings() ) { log_fatal("Unable to initialize periodic settings"); }; #ifdef DEBUG debug (__FUNCTION__, "Successfully initialized periodic settings."); #endif // read in the configuration file and change // all relevant settings based on config file if (readConfigFile(config_file) ) { // if the configuration file is not readable, remove the // configuration file and backup a copy backupConfigFile(LoginSettings.configFile, LoginSettings.scratchDir); saveConfigFile(LoginSettings.configFile); log_err("Corrupt Configuration File Moved to %s. New configuration file written.", LoginSettings.scratchDir); } /* * Block signals in initial thread. New threads will * inherit this signal mask. All the signals will be handled * in a dedicated thread */ sigfillset ( &signalSet ); pthread_sigmask ( SIG_BLOCK, &signalSet, NULL ); // launch the signal handling thread #ifdef DEBUG debug(__FUNCTION__, "Creating signal thread..."); #endif pthread_t sighandlerThreadID; if ((error = pthread_create(&sighandlerThreadID, NULL, sigHandler, config_file)) > 0 ) log_fatal("Failed to create signal handler thread: %s\n", strerror(error)); #ifdef DEBUG debug(__FUNCTION__, "Created signal thread!"); #endif // create the system queues #ifdef DEBUG debug(__FUNCTION__, "Creating queues..."); #endif /*create the peer queue*/ peerQueue = createQueue(copyBMF, sizeOfBMF, PEER_QUEUE_NAME, strlen(PEER_QUEUE_NAME), FALSE); /*create the label queue*/ labeledQueue = createQueue(copyBMF, sizeOfBMF, LABEL_QUEUE_NAME, strlen(LABEL_QUEUE_NAME), FALSE); /*create the xml queue*/ xmlUQueue = createQueue(copyXML, sizeOfXML, XML_U_QUEUE_NAME, strlen(XML_U_QUEUE_NAME), TRUE); xmlRQueue = createQueue(copyXML, sizeOfXML, XML_R_QUEUE_NAME, strlen(XML_R_QUEUE_NAME), TRUE); #ifdef DEBUG debug(__FUNCTION__, "Created queues!"); #endif // launch the peering thread #ifdef DEBUG debug(__FUNCTION__, "Creating peering thread..."); #endif launchAllPeers(); #ifdef DEBUG debug(__FUNCTION__, "Created peering thread!"); #endif // launch the labeling thread #ifdef DEBUG debug(__FUNCTION__, "Creating labeling thread..."); #endif launchLabelingThread(); #ifdef DEBUG debug(__FUNCTION__, "Created labeling thread!"); #endif // launch the xml thread #ifdef DEBUG debug(__FUNCTION__, "Creating xml thread..."); #endif launchXMLThread(); #ifdef DEBUG debug(__FUNCTION__, "Created xml thread!"); #endif // launch the clients control thread #ifdef DEBUG debug(__FUNCTION__, "Creating clients control thread..."); #endif launchClientsControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created clients control thread!"); #endif // launch the mrt control thread #ifdef DEBUG debug(__FUNCTION__, "Creating mrt control thread..."); #endif launchMrtControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created mrt control thread!"); #endif // launch the configured chains thread #ifdef DEBUG debug(__FUNCTION__, "Creating threads for each configured chain..."); #endif launchAllChainsThreads(); #ifdef DEBUG debug(__FUNCTION__, "Created threads for each configured chain!"); #endif // launch the login thread #ifdef DEBUG debug(__FUNCTION__, "Creating login thread..."); #endif launchLoginControlThread(); #ifdef DEBUG debug(__FUNCTION__, "Created login thread!"); #endif // launch the periodic thread #ifdef DEBUG debug(__FUNCTION__, "Creating periodic thread..."); #endif LaunchPeriodicThreads(); #ifdef DEBUG debug(__FUNCTION__, "Created periodic thread!"); #endif // write BGPMON_START message into the Peer Queue BMF bmf = createBMF(0, BMF_TYPE_BGPMON_START); QueueWriter qw = createQueueWriter(peerQueue); writeQueue(qw, bmf); destroyQueueWriter(qw); // periodically check on the state of each thread time_t threadtime; time_t currenttime; char currenttime_extended[64]; memset(currenttime_extended, 0, 64); char threadtime_extended[64]; memset(threadtime_extended, 0, 64); struct tm * current_tm = NULL; struct tm * thread_tm = NULL; int *chainIDs; long *clientIDs; long *mrtIDs; int clientcount, chaincount, mrtcount, i; while ( TRUE ) { // get the current running time to compare the threads // last exection time to currenttime = time(NULL); sleep(THREAD_CHECK_INTERVAL); current_tm = localtime(¤ttime); strftime(currenttime_extended, sizeof(currenttime_extended), "%Y-%m-%dT%H:%M:%SZ", current_tm); // CLI MODULE // check the cli listener threadtime = getLoginControlLastAction(); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("CLI Module is idle: current time = %s, last thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // check the individual cli threads for updates int clicount = 0; long * cliIDs = NULL; clicount = getActiveCliIds(&cliIDs); if(clicount != -1) { for ( i=0; i<clicount; i++) { threadtime = getCliLastAction(cliIDs[i]); if ( difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Cli %d is idle: current time = %s, last cli %d thread time = %s", cliIDs[i], currenttime_extended, cliIDs[i], threadtime_extended); } } free(cliIDs); } // CLIENTS MODULE // Clients Module threadtime = getClientsControlLastAction(); thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Clients Module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // UPDATE clients clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_UPDATA); if(clientcount != -1) { for (i = 0; i < clientcount; i++) { threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_UPDATA); if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Updates Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended); } } free(clientIDs); } // RIB clients clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_RIB); if(clientcount != -1) { for (i = 0; i < clientcount; i++) { threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_RIB); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("RIB Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended); } } free(clientIDs); } // PEER MODULE for (i=0; i < MAX_SESSION_IDS; i++) { if( Sessions[i] != NULL && getSessionState(Sessions[i]->sessionID) == stateEstablished) { threadtime = getSessionLastActionTime(i); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Peering session %d is idle: current time = %s, last client %d thread time = %s",Sessions[i]->sessionID, currenttime_extended, Sessions[i]->sessionID, threadtime_extended); //closeBgpmon(config_file); } } } // LABELING MODULE threadtime = getLabelThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Labeling module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // XML MODULE threadtime = getXMLThreadLastAction(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("XML module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // QUAGGA MODULE // mrt listener threadtime = getMrtControlLastAction(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("MRT module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // mrt connections mrtcount = getActiveMrtsIDs(&mrtIDs); if(mrtcount != -1) { for (i = 0; i < mrtcount; i++) { threadtime = getMrtLastAction(mrtIDs[i]); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("MRT client %d is idle: current time = %s, last client %d thread time = %s",mrtIDs[i], currenttime_extended, mrtIDs[i], threadtime_extended); } } free(mrtIDs); } // CHAIN MODULE chaincount = getActiveChainsIDs(&chainIDs); if(chaincount != -1) { for (i = 0; i < chaincount; i++) { threadtime = getChainLastAction(chainIDs[i]); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("BGPmon chain %ld is idle: current time = %s, last client %ld thread time = %s", chainIDs[i], currenttime_extended, chainIDs[i], threadtime_extended); } } free(chainIDs); } // PERIODIC MODULE // route refresh threadtime = getPeriodicRouteRefreshThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Route Refresh module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } // status message threadtime = getPeriodicStatusMessageThreadLastActionTime(); if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) { thread_tm = localtime(&threadtime); strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm); log_warning("Status Messages module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended); //closeBgpmon(config_file); } } // should never get here log_err( "main: unexpectedly finished"); return(0); }
ufw_sk *ufw_socket(int proto, int opts){ ufw_sk *sk; struct node *cur; struct linger lg = { 0, 0 }; struct timeval now; char filename[100]; int on = 1; int fd; dump_t *dp = NULL; struct sigaction handler; if(proto != IPPROTO_TCP && proto != IPPROTO_UDP){ errno = EINVAL; if(opts & FATAL)die("proto"); return NULL; } fd = socket(PF_INET, SOCK_RAW, proto); if(fd < 0){ if(opts & FATAL)die("socket"); return NULL; } setsockopt(fd, SOL_SOCKET, SO_LINGER, &lg, sizeof(lg)); setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)); setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)); if(fcntl(fd, F_SETOWN, getpid()) < 0){ if(opts & FATAL)die("fcntl"); return NULL; } if(fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC) < 0){ if(opts & FATAL)die("fcntl"); return NULL; } if(fcntl(fd, F_SETSIG, SIGIO) < 0){ if(opts & FATAL)die("fcntl"); return NULL; } if(opts & DUMP_AUTONAME){ gettimeofday(&now, NULL); snprintf(filename, 100, "/tmp/%d.%06d.pcap", (int)now.tv_sec, (int)now.tv_usec); dp = dump_open(filename, "w"); if(!dp){ if(opts & FATAL)die("%s", filename); return NULL; } } cur = malloc(sizeof(struct node) + sizeof(ufw_sk)); if(!cur){ if(opts & FATAL)die("malloc"); return NULL; } sk = (void *)cur + sizeof(struct node); cur->data = sk; cur->next = ufwsk_list; cur->prev = NULL; ufwsk_list = cur; sk->fd = fd; sk->opts = opts; sk->ttl = IPDEFTTL; sk->proto = proto; sk->saddr = sk->daddr = 0; sk->sport = sk->dport = 0; sk->window = TCP_MAXWIN; sk->first_packet.tv_sec = 0; sk->first_packet.tv_usec = 0; sk->limit_packet = 0; sk->limit_packet_flags = 0; sk->limit_byte = 0; sk->received = 0; sk->dump = dp; if(!(opts & SIGIO_MANUAL) && !is_ufw_sigio_handler){ is_ufw_sigio_handler = 1; handler.sa_sigaction = ufw_sigio_handler; sigfillset(&handler.sa_mask); handler.sa_flags = SA_SIGINFO; sigaction(SIGIO, &handler, NULL); } return sk; }
static void trap_default_signals(void) { static const int core_signals[] = { SIGQUIT, SIGILL, #ifdef SIGEMT SIGEMT, #endif SIGFPE, SIGBUS, SIGSEGV, #ifdef SIGSYS SIGSYS, #endif #ifdef SIGXCPU SIGXCPU, #endif #ifdef SIGXFSZ SIGXFSZ, #endif }; static const int exit_signals[] = { SIGHUP, SIGINT, SIGALRM, SIGTERM, SIGUSR1, SIGUSR2, #ifdef SIGPOLL SIGPOLL, #endif #ifdef SIGVTALRM SIGVTALRM, #endif #ifdef SIGSTKFLT SIGSTKFLT, #endif }; static const int ignore_signals[] = { SIGPIPE, }; static const struct { const int *sigs; u_int nsigs; void (*handler)(int signo #ifdef SA_SIGINFO , siginfo_t *info, void *context #endif ); } sigmap[] = { { core_signals, array_size(core_signals), core_handler}, { exit_signals, array_size(exit_signals), exit_handler}, { ignore_signals, array_size(ignore_signals), NULL}, }; u_int i; for (i = 0; i < array_size(sigmap); i++) { u_int j; for (j = 0; j < sigmap[i].nsigs; j++) { struct sigaction oact; if ((sigaction(sigmap[i].sigs[j],NULL,&oact) == 0) && (oact.sa_handler == SIG_DFL)) { struct sigaction act; sigfillset (&act.sa_mask); if (sigmap[i].handler == NULL) { act.sa_handler = SIG_IGN; act.sa_flags = 0; } else { #ifdef SA_SIGINFO /* Request extra arguments to signal handler. */ act.sa_sigaction = sigmap[i].handler; act.sa_flags = SA_SIGINFO; #else act.sa_handler = sigmap[i].handler; act.sa_flags = 0; #endif } if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0) zlog_warn("Unable to set signal handler for signal %d: %s", sigmap[i].sigs[j],safe_strerror(errno)); } } } }
/* * child_fn() - Inside container */ int child_fn(void *arg) { pid_t pid, ppid; sigset_t newset; struct sigaction sa; char buf[5]; /* Setup pipe read and write ends */ pid = getpid(); ppid = getppid(); if (pid != CHILD_PID || ppid != PARENT_PID) { printf("cinit: pidns was not created properly\n"); exit(1); } /* Setup pipes to communicate with parent */ close(cinit_parent[0]); close(parent_cinit[1]); /* Block SIGUSR1 signal */ sigemptyset(&newset); sigaddset(&newset, SIGUSR1); if (sigprocmask(SIG_BLOCK, &newset, 0) == -1) { perror("cinit: sigprocmask() failed"); exit(1); } tst_resm(TINFO, "cinit: blocked SIGUSR1"); /* Let parent to queue SIGUSR1 in pending */ if (write(cinit_parent[1], "c:go", 5) != 5) { perror("cinit: pipe is broken to write"); exit(1); } /* Check if parent has queued up SIGUSR1 */ read(parent_cinit[0], buf, 5); if (strcmp(buf, "p:go") != 0) { printf("cinit: parent did not respond!\n"); exit(1); } /* Now redefine handler for SIGUSR1 */ sa.sa_flags = SA_SIGINFO; sigfillset(&sa.sa_mask); sa.sa_sigaction = child_signal_handler; if (sigaction(SIGUSR1, &sa, NULL) == -1) { perror("cinit: sigaction failed"); exit(1); } /* Unblock traffic on SIGUSR1 queue */ tst_resm(TINFO, "cinit: unblocking SIGUSR1"); sigprocmask(SIG_UNBLOCK, &newset, 0); /* Check if new handler is called */ if (broken == 1) { printf("cinit: broken flag didn't change\n"); exit(1); } /* Cleanup and exit */ close(cinit_parent[1]); close(parent_cinit[0]); exit(0); }
int main() { int cnt = 0; int rc; pthread_t child_thread; struct sigaction act; /* Set up main thread to handle SIGALRM */ act.sa_flags = 0; act.sa_handler = sig_handler; sigfillset(&act.sa_mask); sigaction(SIGALRM, &act, 0); printf("main: Initialize barrier with count = 2\n"); if (pthread_barrier_init(&barrier, NULL, 2) != 0) { printf("main: Error at pthread_barrier_init()\n"); return PTS_UNRESOLVED; } printf("main: create child thread\n"); thread_state = NOT_CREATED_THREAD; if (pthread_create(&child_thread, NULL, fn_chld, NULL) != 0) { printf("main: Error at pthread_create()\n"); return PTS_UNRESOLVED; } /* Expect the child to block*/ cnt = 0; do{ sleep(1); }while (thread_state !=EXITING_THREAD && cnt++ < 2); if (thread_state == EXITING_THREAD) { /* child thread did not block */ printf("Test FAILED: child thread did not block on " "pthread_barrier_wait()\n"); exit(PTS_FAIL); } else if (thread_state != ENTERED_THREAD) { printf("Unexpected thread state\n"); exit(PTS_UNRESOLVED); } /* Just in case main gets in a blocked state, send me a SIGALRM after 2 secs */ alarm(2); printf("main: reinitilize barrier while thread is blocking on it\n"); rc = pthread_barrier_init(&barrier, NULL, 2); if (rc == EBUSY) { printf("main: pthread_barrier_init() correctly got EBUSY"); printf("Test PASSED\n"); } else { printf("main: got return code: %d, %s\n", rc, strerror(rc)); printf("Test PASSED: Note*: Expected EBUSY, but standard says 'may' fail.\n"); } /* Cancel thread in case it is still blocked */ pthread_cancel(child_thread); return PTS_PASS; }
static FILE * safe_popen(char *cmd) { int p[2], fd, argc; pid_t pid; char *argv[SAFE_POPEN_MAXARGS + 1]; FILE *fp; static char blank[] = " \t"; static struct sigaction newact; if (pipe(p) < 0) return 0; fp = fdopen(p[0], "r"); if (fp == 0) { close(p[0]); close(p[1]); return 0; } /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */ newact.sa_handler = SIG_DFL; newact.sa_flags = 0; sigfillset(&newact.sa_mask); sigaction (SIGCHLD, &newact, &oldact); pid = fork(); switch (pid) { int ndesc; case -1: fclose(fp); /* this closes p[0], the fd associated with fp */ close(p[1]); sigaction (SIGCHLD, &oldact, NULL); return 0; case 0: /* dup write-side of pipe to stderr and stdout */ if (p[1] != 1) dup2(p[1], 1); if (p[1] != 2) dup2(p[1], 2); /* * close the other file descriptors, except stdin which we * try reassociating with /dev/null, first (bug 174993) */ if (!freopen("/dev/null", "r", stdin)) close(0); ndesc = getdtablesize(); for (fd = PR_MIN(65536, ndesc); --fd > 2; close(fd)); /* clean up environment in the child process */ putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"); putenv("SHELL=/bin/sh"); putenv("IFS= \t"); /* * The caller may have passed us a string that is in text * space. It may be illegal to modify the string */ cmd = strdup(cmd); /* format argv */ argv[0] = strtok(cmd, blank); argc = 1; while ((argv[argc] = strtok(0, blank)) != 0) { if (++argc == SAFE_POPEN_MAXARGS) { argv[argc] = 0; break; } } /* and away we go */ execvp(argv[0], argv); exit(127); break; default: close(p[1]); break; } /* non-zero means there's a cmd running */ safe_popen_pid = pid; return fp; }
void setsignal(int signo) { int action; char *t, tsig; struct sigaction act; if ((t = trap[signo]) == NULL) action = S_DFL; else if (*t != '\0') action = S_CATCH; else action = S_IGN; if (rootshell && action == S_DFL) { switch (signo) { case SIGINT: if (iflag || minusc || sflag == 0) action = S_CATCH; break; case SIGQUIT: #ifdef DEBUG if (debug) break; #endif /* FALLTHROUGH */ case SIGTERM: if (iflag) action = S_IGN; break; #if JOBS case SIGTSTP: case SIGTTOU: if (mflag) action = S_IGN; break; #endif } } if (signo == SIGCHLD) action = S_CATCH; t = &sigmode[signo - 1]; tsig = *t; if (tsig == 0) { /* * current setting unknown */ if (sigaction(signo, 0, &act) == -1) { /* * Pretend it worked; maybe we should give a warning * here, but other shells don't. We don't alter * sigmode, so that we retry every time. */ return; } if (act.sa_handler == SIG_IGN) { if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) { tsig = S_IGN; /* don't hard ignore these */ } else tsig = S_HARD_IGN; } else { tsig = S_RESET; /* force to be set */ } } if (tsig == S_HARD_IGN || tsig == action) return; switch (action) { case S_CATCH: act.sa_handler = onsig; break; case S_IGN: act.sa_handler = SIG_IGN; break; default: act.sa_handler = SIG_DFL; } *t = action; act.sa_flags = 0; sigfillset(&act.sa_mask); sigaction(signo, &act, 0); }
/* * Thread for handling command line attacks (TERM_TTY) * Use global variable struct term_tty *tty_tmp */ void * th_tty_peer(void *args) { int fail; time_t this_time; struct cl_args *arguments; struct term_tty *tty; struct term_node *term_node=NULL; sigset_t mask; terms->work_state = RUNNING; write_log(0, "\n th_tty_peer thread = %d...\n",(int)pthread_self()); sigfillset(&mask); if (pthread_sigmask(SIG_BLOCK, &mask,NULL)) { thread_error("th_tty_peer pthread_sigmask()",errno); th_tty_peer_exit(NULL); } if (pthread_mutex_lock(&terms->mutex) != 0) { thread_error("th_tty_peer pthread_mutex_lock",errno); th_tty_peer_exit(NULL); } fail = term_add_node(&term_node, TERM_TTY, (int)NULL, pthread_self()); if (fail == -1) { if (pthread_mutex_unlock(&terms->mutex) != 0) thread_error("th_tty_peer pthread_mutex_unlock",errno); th_tty_peer_exit(term_node); } if (term_node == NULL) { write_log(1,"Ouch!! No more than %d %s accepted!!\n", term_type[TERM_TTY].max, term_type[TERM_TTY].name); if (pthread_mutex_unlock(&terms->mutex) != 0) thread_error("th_tty_peer pthread_mutex_unlock",errno); th_tty_peer_exit(term_node); } tty = term_node->specific; memcpy(tty,tty_tmp,sizeof(struct term_tty)); this_time = time(NULL); #ifdef HAVE_CTIME_R #ifdef SOLARIS ctime_r(&this_time,term_node->since, sizeof(term_node->since)); #else ctime_r(&this_time,term_node->since); #endif #else pthread_mutex_lock(&mutex_ctime); strncpy(term_node->since, ctime(&this_time), sizeof(term_node->since)); pthread_mutex_unlock(&mutex_ctime); #endif /* Just to remove the cr+lf...*/ term_node->since[sizeof(term_node->since)-2] = 0; /* This is a tty so, man... ;) */ strncpy(term_node->from_ip, "127.0.0.1", sizeof(term_node->from_ip)); /* Parse config file */ if (strlen(tty_tmp->config_file)) if (parser_read_config_file(tty_tmp, term_node) < 0) { write_log(0, "Error reading configuration file\n"); th_tty_peer_exit(term_node); } if (init_attribs(term_node) < 0) { if (pthread_mutex_unlock(&terms->mutex) != 0) thread_error("th_tty_peer pthread_mutex_unlock",errno); th_tty_peer_exit(term_node); } arguments = args; /* In command line mode we initialize the values by default */ if (protocols[arguments->proto_index].init_attribs) { fail = (*protocols[arguments->proto_index].init_attribs) (term_node); } else write_log(0, "Warning, proto %d has no init_attribs function!!\n", arguments->proto_index); /* Choose a parser */ fail = parser_cl_proto(term_node, arguments->count, arguments->argv_tmp, arguments->proto_index); if (pthread_mutex_unlock(&terms->mutex) != 0) thread_error("th_tty_peer pthread_mutex_unlock",errno); if (fail < 0) { write_log(0, "Error when parsing...\n"); th_tty_peer_exit(term_node); } write_log(0, "Entering command line mode...\n"); /* Execute attack... */ doloop(term_node, arguments->proto_index); th_tty_peer_exit(term_node); return(NULL); }
void afp_over_dsi_sighandlers(AFPObj *obj) { DSI *dsi = (DSI *) obj->dsi; struct sigaction action; memset(&action, 0, sizeof(action)); sigfillset(&action.sa_mask); action.sa_flags = SA_RESTART; /* install SIGHUP */ action.sa_handler = afp_dsi_reload; if ( sigaction( SIGHUP, &action, NULL ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* install SIGURG */ action.sa_handler = afp_dsi_transfer_session; if ( sigaction( SIGURG, &action, NULL ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* install SIGTERM */ action.sa_handler = afp_dsi_die; if ( sigaction( SIGTERM, &action, NULL ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* install SIGQUIT */ action.sa_handler = ipc_reconnect_handler; if ( sigaction(SIGQUIT, &action, NULL ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* SIGUSR2 - server message support */ action.sa_handler = afp_dsi_getmesg; if ( sigaction( SIGUSR2, &action, NULL) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* SIGUSR1 - set down in 5 minutes */ action.sa_handler = afp_dsi_timedown; action.sa_flags = SA_RESTART; if ( sigaction( SIGUSR1, &action, NULL) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } /* SIGINT - enable max_debug LOGging to /tmp/afpd.PID.XXXXXX */ action.sa_handler = afp_dsi_debug; if ( sigaction( SIGINT, &action, NULL) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(EXITERR_SYS); } #ifndef DEBUGGING /* SIGALRM - tickle handler */ action.sa_handler = alarm_handler; if ((sigaction(SIGALRM, &action, NULL) < 0) || (setitimer(ITIMER_REAL, &dsi->timer, NULL) < 0)) { afp_dsi_die(EXITERR_SYS); } #endif /* DEBUGGING */ }
void *clamukoth(void *arg) { struct thrarg *tharg = (struct thrarg *) arg; sigset_t sigset; struct sigaction act; int eventcnt = 1, extinfo; char err[128]; struct ClamAuthEvent event; /* ignore all signals except SIGUSR1 */ sigfillset(&sigset); sigdelset(&sigset, SIGUSR1); /* The behavior of a process is undefined after it ignores a * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ sigdelset(&sigset, SIGFPE); sigdelset(&sigset, SIGILL); sigdelset(&sigset, SIGSEGV); #ifdef SIGBUS sigdelset(&sigset, SIGBUS); #endif pthread_sigmask(SIG_SETMASK, &sigset, NULL); memset(&act, 0, sizeof(struct sigaction)); act.sa_handler = cauth_exit; sigfillset(&(act.sa_mask)); sigaction(SIGUSR1, &act, NULL); sigaction(SIGSEGV, &act, NULL); extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled; cauth_fd = open("/dev/clamauth", O_RDONLY); if(cauth_fd == -1) { logg("!ClamAuth: Can't open /dev/clamauth\n"); if(errno == ENOENT) logg("!ClamAuth: Please make sure ClamAuth.kext is loaded\n"); else if(errno == EACCES) logg("!ClamAuth: This application requires root privileges\n"); else logg("!ClamAuth: /dev/clamauth: %s\n", cli_strerror(errno, err, sizeof(err))); return NULL; } while(1) { if(read(cauth_fd, &event, sizeof(event)) > 0) { if(eventcnt == 1) { if(event.action != SUPPORTED_PROTOCOL) { logg("!ClamAuth: Protocol version mismatch (tool: %d, driver: %d)\n", SUPPORTED_PROTOCOL, event.action); close(cauth_fd); return NULL; } if(strncmp(event.path, "ClamAuth", 8)) { logg("!ClamAuth: Invalid version event\n"); close(cauth_fd); return NULL; } logg("ClamAuth: Driver version: %s, protocol version: %d\n", &event.path[9], event.action); } else { cauth_scanfile(event.path, extinfo, tharg); } eventcnt++; } else { if(errno == ENODEV) { printf("^ClamAuth: ClamAuth module deactivated, terminating\n"); close(cauth_fd); return NULL; } } usleep(200); } }
int main(int argc, char **argv) { int ch; int error = 0; extern char *__progname; while ((ch = getopt(argc, argv, "abcdDfijkKlmnqrstuv:")) != -1) switch (ch) { case 'a': /* print all commands */ aflag = 1; break; case 'b': /* sort by per-call user/system time average */ bflag = 1; sa_cmp = cmp_avgusrsys; break; case 'c': /* print percentage total time */ cflag = 1; break; case 'd': /* sort by averge number of disk I/O ops */ dflag = 1; sa_cmp = cmp_avgdkio; break; case 'D': /* print and sort by total disk I/O ops */ Dflag = 1; sa_cmp = cmp_dkio; break; case 'f': /* force no interactive threshold comprison */ fflag = 1; break; case 'i': /* do not read in summary file */ iflag = 1; break; case 'j': /* instead of total minutes, give sec/call */ jflag = 1; break; case 'k': /* sort by cpu-time average memory usage */ kflag = 1; sa_cmp = cmp_avgcpumem; break; case 'K': /* print and sort by cpu-storage integral */ sa_cmp = cmp_cpumem; Kflag = 1; break; case 'l': /* separate system and user time */ lflag = 1; break; case 'm': /* print procs and time per-user */ mflag = 1; break; case 'n': /* sort by number of calls */ sa_cmp = cmp_calls; break; case 'q': /* quiet; error messages only */ qflag = 1; break; case 'r': /* reverse order of sort */ rflag = 1; break; case 's': /* merge accounting file into summaries */ sflag = 1; break; case 't': /* report ratio of user and system times */ tflag = 1; break; case 'u': /* first, print uid and command name */ uflag = 1; break; case 'v': /* cull junk */ vflag = 1; cutoff = atoi(optarg); break; case '?': default: (void)fprintf(stderr, "usage: %s [-abcDdfijKklmnqrstu] [-v cutoff]" " [file ...]\n", __progname); exit(1); } argc -= optind; argv += optind; /* various argument checking */ if (fflag && !vflag) errx(1, "only one of -f requires -v"); if (fflag && aflag) errx(1, "only one of -a and -v may be specified"); /* XXX need more argument checking */ if (!uflag) { /* initialize tables */ if ((sflag || (!mflag && !qflag)) && pacct_init() != 0) errx(1, "process accounting initialization failed"); if ((sflag || (mflag && !qflag)) && usracct_init() != 0) errx(1, "user accounting initialization failed"); } if (argc == 0) { argc = dfltargc; argv = dfltargv; } /* for each file specified */ for (; argc > 0; argc--, argv++) { int fd; /* * load the accounting data from the file. * if it fails, go on to the next file. */ fd = acct_load(argv[0], sflag); if (fd < 0) continue; if (!uflag && sflag) { #ifndef DEBUG sigset_t nmask, omask; int unmask = 1; /* * block most signals so we aren't interrupted during * the update. */ if (sigfillset(&nmask) == -1) { warn("sigfillset"); unmask = 0; error = 1; } if (unmask && (sigprocmask(SIG_BLOCK, &nmask, &omask) == -1)) { warn("couldn't set signal mask "); unmask = 0; error = 1; } #endif /* DEBUG */ /* * truncate the accounting data file ASAP, to avoid * losing data. don't worry about errors in updating * the saved stats; better to underbill than overbill, * but we want every accounting record intact. */ if (ftruncate(fd, 0) == -1) { warn("couldn't truncate %s", *argv); error = 1; } /* * update saved user and process accounting data. * note errors for later. */ if (pacct_update() != 0 || usracct_update() != 0) error = 1; #ifndef DEBUG /* * restore signals */ if (unmask && (sigprocmask(SIG_SETMASK, &omask, NULL) == -1)) { warn("couldn't restore signal mask"); error = 1; } #endif /* DEBUG */ } /* * close the opened accounting file */ if (close(fd) == -1) { warn("close %s", *argv); error = 1; } } if (!uflag && !qflag) { /* print any results we may have obtained. */ if (!mflag) pacct_print(); else usracct_print(); } if (!uflag) { /* finally, deallocate databases */ if (sflag || (!mflag && !qflag)) pacct_destroy(); if (sflag || (mflag && !qflag)) usracct_destroy(); } exit(error); }