int main(int argc, char* argv[]) { struct connection conn; iopoll_fd fds[2]; int selfpipe; int i; msg_debug_init(); testmode = getenv("TESTMODE") != 0; if ((shell_argv = malloc((argc + 3) * sizeof *argv)) == 0) die_oom(111); for (i = 1; i < argc; ++i) shell_argv[i-1] = argv[i]; for (; i < argc + 4; ++i) shell_argv[i-1] = 0; shell_argc = argc - 1; if ((path = getenv("PATH")) == 0) die1(111, "No PATH is set"); if ((devnull = open("/dev/null", O_RDWR)) == -1) die1sys(111, "Could not open \"/dev/null\""); if (!nonblock_on(0)) die1sys(111, "Could not set non-blocking status"); if ((selfpipe = selfpipe_init()) == -1) die1sys(111, "Could not create self-pipe"); init_slots(); connection_init(&conn, 0, 0); fds[0].fd = 0; fds[0].events = IOPOLL_READ; fds[1].fd = selfpipe; fds[1].events = IOPOLL_READ; for (;;) { if (iopoll_restart(fds, 2, -1) == -1) die1sys(111, "Poll failed"); if (fds[0].revents) if (connection_read(&conn, handle_packet) <= 0) break; if (fds[1].revents) { read(selfpipe, &i, 1); handle_child(WNOHANG); } } msg1("Waiting for remaining slots to complete"); while (slots_used > 0) handle_child(0); return 0; }
//***************************************************************************** //***************************************************************************** int bevt_client_init(void) { random_name(&bevt_client_g.rid[0], 8); bevt_client_g.sfd = selfpipe_init() ; if (bevt_client_g.sfd < 0) strerr_diefu1sys(111, "selfpipe_init") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGCHLD) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } BEVT_DEBUG_LOG_INFO("rid(%s)", (long long int)bevt_client_g.rid); if(bevt_client_start_relay(0)<0) return -1; return (errno=0,0); }
int main(int argc, char **argv) { int status; int idx; int active_last = 0; int active = 0; struct redir_t *redir; int keep_going = 1; int reload_config = 0; uint8_t hwaddr[6]; struct ifreq ifr; int selfpipe; int fd = socket(AF_INET, SOCK_DGRAM, 0); options_init(); chilli_signals(&keep_going, &reload_config); process_options(argc, argv, 1); safe_strncpy(ifr.ifr_name, _options.dhcpif, sizeof(ifr.ifr_name)); #ifdef SIOCGIFHWADDR if (ioctl(fd, SIOCGIFHWADDR, (caddr_t)&ifr) == 0) { memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, PKT_ETH_ALEN); } else { log_err(errno, "could not get MAC address"); return -1; } #endif close(fd); /* create an instance of redir */ if (redir_new(&redir, &_options.uamlisten, _options.uamport, #ifdef ENABLE_UAMUIPORT _options.uamuiport #else 0 #endif )) { log_err(0, "Failed to create redir"); return -1; } if (redir_listen(redir)) { log_err(0, "Failed to create redir listen"); return -1; } redir_set(redir, hwaddr, (_options.debug)); redir_set_cb_getstate(redir, sock_redir_getstate); redir->cb_handle_url = redir_handle_url; if (net_select_init(&sctx)) log_err(errno, "select init"); selfpipe = selfpipe_init(); /* epoll */ net_select_addfd(&sctx, selfpipe, SELECT_READ); net_select_addfd(&sctx, redir->fd[0], SELECT_READ); net_select_addfd(&sctx, redir->fd[1], SELECT_READ); if (_options.gid && setgid(_options.gid)) { log_err(errno, "setgid(%d) failed while running with gid = %d\n", _options.gid, getgid()); } if (_options.uid && setuid(_options.uid)) { log_err(errno, "setuid(%d) failed while running with uid = %d\n", _options.uid, getuid()); } while (keep_going) { /* select/poll */ net_select_zero(&sctx); net_select_fd(&sctx, selfpipe, SELECT_READ); net_select_fd(&sctx, redir->fd[0], SELECT_READ); net_select_fd(&sctx, redir->fd[1], SELECT_READ); active = 0; if (reload_config) { reload_options(argc, argv); reload_config = 0; redir_set(redir, hwaddr, _options.debug); } for (idx=0; idx < max_requests; idx++) { conn_select_fd(&requests[idx].conn, &sctx); if (requests[idx].inuse && requests[idx].socket_fd) { time_t now = mainclock_tick(); int fd = requests[idx].socket_fd; int timeout = 60; if (now - requests[idx].last_active > timeout) { log_dbg("timeout connection %d", idx); redir_conn_finish(&requests[idx].conn, &requests[idx]); } else { int evt = SELECT_READ; timeout = 0; if (conn_write_remaining(&requests[idx].conn)) evt |= SELECT_WRITE; net_select_fd(&sctx, fd, evt); active++; } #if(_debug_ > 1) if (_options.debug) { struct sockaddr_in address; socklen_t addrlen = sizeof(address); if (getpeername(fd, (struct sockaddr *)&address, &addrlen) >= 0) { char line[512]; safe_snprintf(line, sizeof(line), "#%d (%d) %d connection from %s %d", timeout ? -1 : active, fd, (int) requests[idx].last_active, inet_ntoa(address.sin_addr), ntohs(address.sin_port)); if (requests[idx].conn.sock) { addrlen = sizeof(address); if (getpeername(requests[idx].conn.sock, (struct sockaddr *)&address, &addrlen) >= 0) { safe_snprintf(line+strlen(line), sizeof(line)-strlen(line), " to %s %d", inet_ntoa(address.sin_addr), ntohs(address.sin_port)); } } if (timeout) { safe_snprintf(line+strlen(line), sizeof(line)-strlen(line), " (timeout)"); } log_dbg("%s", line); } } #endif } } if (active != active_last) { log_dbg("active connections: %d", active); active_last = active; } status = net_select(&sctx); #if defined(USING_POLL) && defined(HAVE_SYS_EPOLL_H) && (_debug_ > 1) if (_options.debug && status > 0) { int i; log_dbg("epoll %d", status); for (i=0; i < status; i++) { log_dbg("epoll fd %d %d", sctx.events[i].data.fd, sctx.events[i].events); } } #endif switch (status) { case -1: log_err(errno, "select() returned -1!"); break; default: if (status > 0) { if (net_select_read_fd(&sctx, selfpipe)==1) { chilli_handle_signal(0, 0); } if (redir->fd[0]) if (net_select_read_fd(&sctx, redir->fd[0])==1 && redir_accept2(redir, 0) < 0) log_err(0, "redir_accept() failed!"); if (redir->fd[1]) if (net_select_read_fd(&sctx, redir->fd[1])==1 && redir_accept2(redir, 1) < 0) log_err(0, "redir_accept() failed!"); for (idx=0; idx < max_requests; idx++) { /* * Update remote connections with activity */ conn_select_update(&requests[idx].conn, &sctx); /* * Check client connections with activity */ if (requests[idx].inuse && requests[idx].socket_fd) { int fd = requests[idx].socket_fd; #ifdef HAVE_SSL if (requests[idx].sslcon) { if (openssl_check_accept(requests[idx].sslcon, 0) < 0) { log_dbg("ssl error %d", errno); redir_conn_finish(&requests[idx].conn, &requests[idx]); continue; } } #endif switch (net_select_write_fd(&sctx, fd)) { case 1: log_dbg("client writeable"); redir_cli_rewrite(&requests[idx], &requests[idx].conn); break; } switch (net_select_read_fd(&sctx, fd)) { case -1: log_dbg("EXCEPTION"); redir_conn_finish(&requests[idx].conn, &requests[idx]); break; case 1: { if (requests[idx].proxy) { char b[PKT_MAX_LEN]; int r; #ifdef HAVE_SSL if (requests[idx].sslcon) { /* log_dbg("proxy_read_ssl"); */ r = openssl_read(requests[idx].sslcon, b, sizeof(b)-1, 0); } else #endif r = safe_read(fd, b, sizeof(b)-1); /* log_dbg("proxy_read: %d %d", fd, r); */ if (r <= 0) { log_dbg("recv %d %d %d", r, requests[idx].conn.read_buf->slen - requests[idx].conn.read_pos, errno); if (!(r == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))) { if (redir_cli_rewrite(&requests[idx], &requests[idx].conn) == 0) { log_dbg("done reading and writing"); redir_conn_finish(&requests[idx].conn, &requests[idx]); } } } else if (r > 0) { int w; requests[idx].last_active = mainclock_tick(); w = net_write(requests[idx].conn.sock, b, r); /* log_dbg("proxy_write: %d", w); */ if (r != w) { log_err(errno, "problem writing what we read from client"); redir_conn_finish(&requests[idx].conn, &requests[idx]); } } } else { #ifdef HAVE_SSL go_again: #endif switch (redir_main(redir, fd, fd, &requests[idx].conn.peer, &requests[idx].baddr, requests[idx].uiidx, &requests[idx])) { case 1: /*log_dbg("redir cont'ed");*/ #ifdef HAVE_SSL if (requests[idx].sslcon && openssl_pending(requests[idx].sslcon) > 0) { log_dbg("ssl_pending, trying again"); goto go_again; } #endif break; case -1: log_dbg("redir error"); default: log_dbg("redir completed"); redir_conn_finish(&requests[idx].conn, &requests[idx]); break; } } } break; } } } } break; } } redir_free(redir); child_killall(SIGKILL); selfpipe_finish(); return 0; }
int main (int argc, char const *const *argv) { tain_t deadline ; int sfd ; PROG = "bevt_relayd" ; if (argc < 2) strerr_dieusage(100, USAGE) ; if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ; if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; sfd = selfpipe_init() ; if (sfd < 0) strerr_diefu1sys(111, "selfpipe_init") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGCHLD) ; sigaddset(&set, SIGTERM) ; sigaddset(&set, SIGQUIT) ; sigaddset(&set, SIGHUP) ; sigaddset(&set, SIGABRT) ; sigaddset(&set, SIGINT) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } if(bevt_relay_db_init(argv[1])<0) strerr_diefu1sys(111, "db init failed") ; tain_now_g() ; tain_addsec_g(&deadline, 2) ; if (!skaclient_server_01x_init_g(BEVT_RELAY_BANNER1, BEVT_RELAY_BANNER1_LEN, BEVT_RELAY_BANNER2, BEVT_RELAY_BANNER2_LEN, &deadline)) strerr_diefu1sys(111, "sync with client") ; for (;;) { register unsigned int n = 0 ; iopause_fd x[6 + n] ; int r ; if(mfd<0) handle_connect_central(); tain_add_g(&deadline, &tain_infinite_relative) ; x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ; x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (unixmessage_sender_isempty(unixmessage_sender_1) ? 0 : IOPAUSE_WRITE ) ; x[2].fd = sfd ; x[2].events = IOPAUSE_READ ; x[3].fd = bozclient_sfd(¢ral_client_g); x[3].events = IOPAUSE_READ ; x[4].fd = bozclient_sfd(¢ral_client_g); x[4].events = (bozclient_siswritable(¢ral_client_g) ? IOPAUSE_WRITE : 0) ; x[5].fd = unixmessage_sender_fd(unixmessage_sender_x) ; x[5].events = (unixmessage_sender_isempty(unixmessage_sender_x) ? 0 : IOPAUSE_WRITE) ; r = iopause_g(x, 5 + n, &deadline) ; if (r < 0) { cleanup() ; strerr_diefu1sys(111, "iopause") ; } /* client closed */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; /* client is sync reading */ if (x[1].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush sync out") ; } } /* client is async rzading */ if (x[5].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_x) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush async out") ; } } /* signals arrived */ if (x[2].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ; /* main socket read or close */ if (x[3].revents & IOPAUSE_READ) { handle_close_central(); continue; } /* main socket close */ if (x[4].revents & IOPAUSE_WRITE) { bozclient_flush(¢ral_client_g); } /* main socket close */ if (x[5].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_x) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush stdout") ; } } /* client is sync writing */ if (!unixmessage_receiver_isempty(unixmessage_receiver_0) || x[0].revents & IOPAUSE_READ) { if (unixmessage_handle(unixmessage_receiver_0, &bevt_relay_parse_prot_cmd, 0) < 0) { if (errno == EPIPE) break ; /* normal exit */ cleanup() ; strerr_diefu1sys(111, "handle messages from client") ; } } } cleanup() ; return 0 ; }
int main (int argc, char const **argv, char const *const *envp) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; tain_t deadline, tto ; ftrigr_t a = FTRIGR_ZERO ; int argc1 ; unsigned int i = 0 ; char or = 0 ; PROG = "s6-ftrig-listen" ; { unsigned int t = 0 ; for (;;) { register int opt = subgetopt(argc, argv, "aot:") ; if (opt == -1) break ; switch (opt) { case 'a' : or = 0 ; break ; case 'o' : or = 1 ; break ; case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ; default : dieusage() ; } } if (t) tain_from_millisecs(&tto, t) ; else tto = tain_infinite_relative ; argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; } if (argc < 4) dieusage() ; argc1 = el_semicolon(argv) ; if (!argc1 || (argc1 & 1) || (argc == argc1 + 1)) dieusage() ; if (argc1 >= argc) strerr_dief1x(100, "unterminated fifodir+regex block") ; tain_now_g() ; tain_add_g(&deadline, &tto) ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ; if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ; x[1].fd = ftrigr_fd(&a) ; { int pid = 0 ; unsigned int idlen = argc1 >> 1 ; uint16 ids[idlen] ; for (; i < idlen ; i++) { ids[i] = ftrigr_subscribe_g(&a, argv[i<<1], argv[(i<<1)+1], 0, &deadline) ; if (!ids[i]) strerr_diefu4sys(111, "subscribe to ", argv[i<<1], " with regexp ", argv[(i<<1)+1]) ; } pid = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ; if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ; for (;;) { register int r ; i = 0 ; while (i < idlen) { char dummy ; r = ftrigr_check(&a, ids[i], &dummy) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ; else if (!r) i++ ; else if (or) idlen = 0 ; else ids[i] = ids[--idlen] ; } if (!idlen) break ; r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) { errno = ETIMEDOUT ; strerr_diefu1sys(1, "get expected event") ; } if (x[0].revents & IOPAUSE_READ) handle_signals() ; if (x[1].revents & IOPAUSE_READ) { if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; } } } return 0 ; }
int main(int argc, char **argv) { struct radius_packet_t radius_pack; struct in_addr radiuslisten; struct timeval timeout; int maxfd = 0; fd_set fdread; fd_set fdwrite; fd_set fdexcep; ssize_t status; int keep_going = 1; int reload_config = 1; int selfpipe; options_init(); selfpipe = selfpipe_init(); chilli_signals(&keep_going, &reload_config); process_options(argc, argv, 1); radiuslisten.s_addr = htonl(INADDR_ANY); memset(&server, 0, sizeof(server)); if (!(server.env = initssl_cli())) { syslog(LOG_ERR, "Failed to create ssl environment"); return -1; } if (radius_new(&server.radius_auth, &radiuslisten, _options.radiusauthport ? _options.radiusauthport : RADIUS_AUTHPORT, 0, 0)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } if (radius_new(&server.radius_acct, &radiuslisten, _options.radiusacctport ? _options.radiusacctport : RADIUS_ACCTPORT, 0, 0)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } if (_options.coaport) { if (radius_new(&server.radius_cli, &radiuslisten, 0, 0, 0) || radius_init_q(server.radius_cli, 8)) { syslog(LOG_ERR, "Failed to create radius"); return -1; } radius_set(server.radius_cli, 0, 0); radius_set_cb_auth_conf(server.radius_cli, cb_radius_auth_conf); } radius_set(server.radius_auth, 0, 0); radius_set(server.radius_acct, 0, 0); if (_options.gid && setgid(_options.gid)) { syslog(LOG_ERR, "%d setgid(%d) failed while running with gid = %d\n", errno, _options.gid, getgid()); } if (_options.uid && setuid(_options.uid)) { syslog(LOG_ERR, "%d setuid(%d) failed while running with uid = %d\n", errno, _options.uid, getuid()); } while (keep_going) { if (reload_config) { reload_options(argc, argv); reload_config = 0; } FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); FD_SET(selfpipe, &fdread); FD_SET(server.radius_auth->fd, &fdread); FD_SET(server.radius_acct->fd, &fdread); if (server.radius_auth->fd > maxfd) maxfd = server.radius_auth->fd; if (server.radius_acct->fd > maxfd) maxfd = server.radius_acct->fd; if (server.conn.sock) { FD_SET(server.conn.sock, &fdread); if (server.conn.sock > maxfd) maxfd = server.conn.sock; } if (server.radius_cli) { FD_SET(server.radius_cli->fd, &fdread); if (server.radius_cli->fd > maxfd) maxfd = server.radius_cli->fd; } timeout.tv_sec = 1; timeout.tv_usec = 0; status = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); switch (status) { case -1: if (errno != EINTR) syslog(LOG_ERR, "%s: select() returned -1!", strerror(errno)); break; case 0: default: if (status > 0) { struct sockaddr_in addr; socklen_t fromlen = sizeof(addr); if (FD_ISSET(selfpipe, &fdread)) { chilli_handle_signal(0, 0); } if (FD_ISSET(server.radius_auth->fd, &fdread)) { /* * ---> Authentication */ if ((status = recvfrom(server.radius_auth->fd, &radius_pack, sizeof(radius_pack), 0, (struct sockaddr *) &addr, &fromlen)) <= 0) { syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno)); return -1; } memcpy(&server.auth_peer, &addr, sizeof(addr)); process_radius(&radius_pack, status); } if (FD_ISSET(server.radius_acct->fd, &fdread)) { /* * ---> Accounting */ syslog(LOG_DEBUG, "received accounting"); if ((status = recvfrom(server.radius_acct->fd, &radius_pack, sizeof(radius_pack), 0, (struct sockaddr *) &addr, &fromlen)) <= 0) { syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno)); return -1; } memcpy(&server.acct_peer, &addr, sizeof(addr)); process_radius(&radius_pack, status); } if (server.radius_cli) { if (FD_ISSET(server.radius_cli->fd, &fdread)) { radius_decaps(server.radius_cli, 0); } } if (server.conn.sock) { if (FD_ISSET(server.conn.sock, &fdread)) { process_radius_reply(); } } } break; } } selfpipe_finish(); return 0; }
int main (int argc, char const *const *argv) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; PROG = "s6-svscan" ; { subgetopt_t l = SUBGETOPT_ZERO ; unsigned int t = 5000 ; for (;;) { register int opt = subgetopt_r(argc, argv, "t:c:", &l) ; if (opt == -1) break ; switch (opt) { case 't' : if (uint0_scan(l.arg, &t)) break ; case 'c' : if (uint0_scan(l.arg, &max)) break ; default : strerr_dieusage(100, USAGE) ; } } argc -= l.ind ; argv += l.ind ; if (t) tain_from_millisecs(&defaulttimeout, t) ; else defaulttimeout = tain_infinite_relative ; if (max < 2) max = 2 ; } /* Init phase. If something fails here, we can die, because it means that something is seriously wrong with the system, and we can't run correctly anyway. */ if (argc && (chdir(argv[0]) < 0)) strerr_diefu1sys(111, "chdir") ; x[1].fd = s6_supervise_lock(S6_SVSCAN_CTLDIR) ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGCHLD) ; sigaddset(&set, SIGALRM) ; sigaddset(&set, SIGTERM) ; sigaddset(&set, SIGHUP) ; sigaddset(&set, SIGQUIT) ; sigaddset(&set, SIGABRT) ; sigaddset(&set, SIGINT) ; sigaddset(&set, SIGUSR1) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } { struct svinfo_s blob[max] ; /* careful with that stack, Eugene */ services = blob ; tain_now_g() ; /* Loop phase. From now on, we must not die. Temporize on recoverable errors, and panic on serious ones. */ while (cont) { int r ; tain_add_g(&deadline, &defaulttimeout) ; reap() ; scan() ; killthem() ; r = iopause_g(x, 2, &deadline) ; if (r < 0) panic("iopause") ; else if (!r) wantscan = 1 ; else { if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) { errno = EIO ; panic("check internal pipes") ; } if (x[0].revents & IOPAUSE_READ) handle_signals() ; if (x[1].revents & IOPAUSE_READ) handle_control(x[1].fd) ; } } /* Finish phase. */ selfpipe_finish() ; killthem() ; reap() ; } { char const *eargv[3] = { FINISH_PROG, finish_arg, 0 } ; execve(eargv[0], (char **)eargv, (char *const *)environ) ; } panicnosp("exec finish script " FINISH_PROG) ; }
int main (int argc, char const *const *argv, char const *const *envp) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; struct taia deadline, tto ; ftrigr_t a = FTRIGR_ZERO ; int pid ; uint16 id ; PROG = "s6-ftrig-listen1" ; { unsigned int t = 0 ; for (;;) { register int opt = subgetopt(argc, argv, "t:") ; if (opt == -1) break ; switch (opt) { case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ; default : strerr_dieusage(100, USAGE) ; } } if (t) taia_from_millisecs(&tto, t) ; else tto = infinitetto ; argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; } if (argc < 3) strerr_dieusage(100, USAGE) ; taia_now_g() ; taia_add_g(&deadline, &tto) ; if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ; id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ; if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ; x[1].fd = ftrigr_fd(&a) ; pid = fork() ; switch (pid) { case -1 : strerr_diefu1sys(111, "fork") ; case 0 : { PROG = "s6-ftrig-listen1 (child)" ; pathexec_run(argv[2], argv+2, envp) ; strerr_dieexec(111, argv[2]) ; } } for (;;) { char dummy ; register int r = ftrigr_check(&a, id, &dummy) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ; if (r) break ; r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) { errno = ETIMEDOUT ; strerr_diefu1sys(1, "get expected event") ; } if (x[0].revents & IOPAUSE_READ) handle_signals() ; if (x[1].revents & IOPAUSE_READ) { if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; } } return 0 ; }
int main (int argc, char const *const *argv) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; PROG = "s6-supervise" ; if (argc < 2) strerr_dieusage(100, USAGE) ; if (chdir(argv[1]) < 0) strerr_diefu2sys(111, "chdir to ", argv[1]) ; { register unsigned int proglen = str_len(PROG) ; register unsigned int namelen = str_len(argv[1]) ; char progname[proglen + namelen + 2] ; byte_copy(progname, proglen, PROG) ; progname[proglen] = ' ' ; byte_copy(progname + proglen + 1, namelen + 1, argv[1]) ; PROG = progname ; if (!fd_sanitize()) strerr_diefu1sys(111, "sanitize stdin and stdout") ; x[1].fd = s6_supervise_lock(S6_SUPERVISE_CTLDIR) ; if (!ftrigw_fifodir_make(S6_SUPERVISE_EVENTDIR, getegid(), 0)) strerr_diefu2sys(111, "mkfifodir ", S6_SUPERVISE_EVENTDIR) ; x[0].fd = selfpipe_init() ; if (x[0].fd == -1) strerr_diefu1sys(111, "init selfpipe") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGTERM) ; sigaddset(&set, SIGHUP) ; sigaddset(&set, SIGQUIT) ; sigaddset(&set, SIGCHLD) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } if (!ftrigw_clean(S6_SUPERVISE_EVENTDIR)) strerr_warnwu2sys("ftrigw_clean ", S6_SUPERVISE_EVENTDIR) ; { struct stat st ; if (stat("down", &st) == -1) { if (errno != ENOENT) strerr_diefu1sys(111, "stat down") ; } else status.flagwantup = 0 ; if (stat("nosetsid", &st) == -1) { if (errno != ENOENT) strerr_diefu1sys(111, "stat nosetsid") ; } else flagsetsid = 0 ; } tain_now_g() ; settimeout(0) ; tain_copynow(&status.stamp) ; announce() ; ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "s", 1) ; while (cont) { register int r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) (*actions[state][V_TIMEOUT])() ; else { if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) strerr_diefu1x(111, "iopause: trouble with pipes") ; if (x[0].revents & IOPAUSE_READ) handle_signals() ; else if (x[1].revents & IOPAUSE_READ) handle_control(x[1].fd) ; } } ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "x", 1) ; } return 0 ; }