/*Program entrance*/ int main(int argc, char** argv) { key_t ipckey = ftok("/",999); int shmid = shmget(ipckey,sizeof(struct tag),IPC_CREAT |0660); strTag = (struct tag *)shmat(shmid,NULL,0); strTag->str = (char *)malloc(10); printf("malloc : %lx\n",(unsigned long)strTag->str); pid_t pid = fork(); if(pid == 0) { create_base(); } if(pid > 0 ) { signal(SIGCHLD,sig_chld); struct event_base *base = event_base_new(); struct timeval tv = {1,0}; struct event sig; struct event sig1; // struct event timeout; // evtimer_assign(&timeout,base,timerout,&timeout); // evtimer_add(&timeout,&tv); evsignal_assign(&sig,base,SIGINT,sig_act,(void *)&sig); evsignal_add(&sig,NULL); evsignal_assign(&sig1,base,SIGUSR1,sig_act2,(void *)base); evsignal_add(&sig1,NULL); event_base_dispatch(base); event_base_free(base); shmdt(strTag); shmctl(shmid,IPC_RMID,NULL); } return 0; }
void run(char *conf_file) { struct running rr; struct event *sig1_ev,*sig2_ev,*sig_hup; evthread_use_pthreads(); setup_running(&rr); register_interface_types(&rr); register_source_types(&rr); run_config(&rr,conf_file); start_stats_timer(&rr); ref_release(&(rr.ic_running)); event_add(sq_consumer(rr.sq),0); event_add(si_consumer(rr.si),0); sq_release(rr.sq); evsignal_add(sig1_ev=evsignal_new(rr.eb,SIGINT,user_quit,&rr),0); evsignal_add(sig2_ev=evsignal_new(rr.eb,SIGTERM,user_quit,&rr),0); evsignal_add(sig_hup=evsignal_new(rr.eb,SIGHUP,hupev,&rr),0); rr.sigkill_timer = event_new(rr.eb,-1,EV_PERSIST,sigkill_self,&rr); log_info(("Starting event loop")); event_base_loop(rr.eb,0); log_info(("Event loop finished")); event_del(sig1_ev); event_del(sig2_ev); event_del(sig_hup); event_free(sig1_ev); event_free(sig2_ev); event_free(sig_hup); closedown(&rr); log_info(("Bye!")); config_finished(); }
static void levent_init(struct lldpd *cfg) { /* Setup libevent */ log_debug("event", "initialize libevent"); event_set_log_callback(levent_log_cb); if (!(cfg->g_base = event_base_new())) fatalx("unable to create a new libevent base"); log_info("event", "libevent %s initialized with %s method", event_get_version(), event_base_get_method(cfg->g_base)); /* Setup SNMP */ #ifdef USE_SNMP if (cfg->g_snmp) { agent_init(cfg, cfg->g_snmp_agentx); cfg->g_snmp_timeout = evtimer_new(cfg->g_base, levent_snmp_timeout, cfg); if (!cfg->g_snmp_timeout) fatalx("unable to setup timeout function for SNMP"); if ((cfg->g_snmp_fds = malloc(sizeof(struct ev_l))) == NULL) fatalx("unable to allocate memory for SNMP events"); TAILQ_INIT(levent_snmp_fds(cfg)); } #endif /* Setup loop that will run every X seconds. */ log_debug("event", "register loop timer"); if (!(cfg->g_main_loop = event_new(cfg->g_base, -1, 0, levent_update_and_send, cfg))) fatalx("unable to setup main timer"); event_active(cfg->g_main_loop, EV_TIMEOUT, 1); /* Setup unix socket */ log_debug("event", "register Unix socket"); TAILQ_INIT(&lldpd_clients); evutil_make_socket_nonblocking(cfg->g_ctl); if ((cfg->g_ctl_event = event_new(cfg->g_base, cfg->g_ctl, EV_READ|EV_PERSIST, levent_ctl_accept, cfg)) == NULL) fatalx("unable to setup control socket event"); event_add(cfg->g_ctl_event, NULL); /* Signals */ log_debug("event", "register signals"); signal(SIGHUP, SIG_IGN); evsignal_add(evsignal_new(cfg->g_base, SIGUSR1, levent_dump, cfg->g_base), NULL); evsignal_add(evsignal_new(cfg->g_base, SIGINT, levent_stop, cfg->g_base), NULL); evsignal_add(evsignal_new(cfg->g_base, SIGTERM, levent_stop, cfg->g_base), NULL); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; /* * x信号的原理 * 1 设置信号处理函数,保存原来的信号处理函数到event的ev_base->sh_old中去 * 2 如果是首次添加信号,那么需要为所有信号追加一个信号事件来源自event->ev_base->ev_signal * 同时设置event->ev_base->ev_signal->ev_signal_added,表示信号回调事件已经设置了 * 3 同时把事件追加到event->ev_base->ev_signal->evsigevents[signno]链表中去 */ if (ev->ev_events & EV_SIGNAL) //如果是加入的信号 return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ //如果说当前的epoll中已经满足不了新加入的句柄 if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; //如果事件之前是可读 if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } //如果事件之前是可写 if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } //新加入事件设置的是可读事件 if (ev->ev_events & EV_READ) events |= EPOLLIN; //新加入事件设置的是可写事件 if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
int main(int argc, char const *argv[]) { struct event* sig; struct evlearner* lea; struct event_base* base; if (argc != 2) { printf("Usage: %s config\n", argv[0]); exit(1); } base = event_base_new(); lea = evlearner_init(argv[1], deliver, NULL, base); if (lea == NULL) { printf("Could not start the learner!\n"); exit(1); } sig = evsignal_new(base, SIGINT, handle_sigint, base); evsignal_add(sig, NULL); event_base_dispatch(base); event_free(sig); evlearner_free(lea); event_base_free(base); return 0; }
int main (int argc, char const *argv[]) { struct event* sig; struct event_base* base; struct evproposer* prop; if (argc != 3) { printf("Usage: %s id config\n", argv[0]); exit(1); } base = event_base_new(); sig = evsignal_new(base, SIGINT, handle_sigint, base); evsignal_add(sig, NULL); prop = evproposer_init(atoi(argv[1]), argv[2], base); if (prop == NULL) { printf("Could not start the proposer!\n"); exit(1); } event_base_dispatch(base); event_free(sig); evproposer_free(prop); event_base_free(base); return 0; }
int main(int argc, const char* argv[]) { int id; struct event* sig; struct evacceptor* acc; struct event_base* base; if(argc != 3){ printf("Usage %s id config\n", argv[0]); return 0; } /*构建libevent base*/ base = event_base_new(); /*读取acceptor id,全局唯一*/ id = atoi(argv[1]); /*创建一个acceptor 的事件响应器*/ acc = evacceptor_init(id, argv[2], base); if(acc == NULL){ printf("Could not start the acceptor\n"); return 0; } sig = evsignal_new(base, SIGINT, handle_sigint, base); evsignal_add(sig, NULL); event_base_dispatch(base); event_free(sig); evacceptor_free(acc); event_base_free(base); return 1; }
bool Master::StartMaster(int argc, char *argv[]) { if (0 != conf_para.InitPara(argc, argv)) return false; std::cout << "Start Master" << std::endl; if (!m_worker.Init(this)) { std::cerr<< "Master: Worker::Init()" << std::endl; return false; } nums_of_child = conf_para.MaxWorker; //创建一定数量的worker while (nums_of_child > 0) { switch (fork()) { case -1: std::cerr<< "Master: StartMaster(): fork()" << std::endl; return false; case 0: m_worker.Run(); return true; default: --nums_of_child; break; } } m_base = event_base_new(); m_exit_event = evsignal_new(m_base, SIGINT, Master::MasterExitSignal, m_base); m_chld_event = evsignal_new(m_base, SIGCHLD, Master::MasterChldSignal, this); evsignal_add(m_exit_event, NULL); evsignal_add(m_chld_event, NULL); event_base_dispatch(m_base); return true; }
int main(int argc, char **argv) { struct event_base *base; struct evconnlistener *listener; struct sockaddr_in sin; struct event *evstop; int port = 9876; if (argc > 1) { port = atoi(argv[1]); } if (port<=0 || port>65535) { puts("Invalid port"); return 1; } signal(SIGPIPE, SIG_IGN); base = event_base_new(); if (!base) { puts("Couldn't open event base"); return 1; } evstop = evsignal_new(base, SIGHUP, signal_cb, base); evsignal_add(evstop, NULL); /* Clear the sockaddr before using it, in case there are extra * * platform-specific fields that can mess us up. */ memset(&sin, 0, sizeof(sin)); /* This is an INET address */ sin.sin_family = AF_INET; /* Listen on 0.0.0.0 */ sin.sin_addr.s_addr = htonl(0); /* Listen on the given port. */ sin.sin_port = htons(port); listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&sin, sizeof(sin)); if (!listener) { perror("Couldn't create listener"); return 1; } event_base_dispatch(base); evconnlistener_free(listener); event_free(evstop); event_base_free(base); return 0; }
static int devpoll_add(void *arg, struct event *ev) { struct devpollop *devpollop = arg; struct evdevpoll *evdp; int fd, events; if (ev->ev_events & OPAL_EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= devpollop->nfds) { /* Extend the file descriptor array as necessary */ if (devpoll_recalc(ev->ev_base, devpollop, fd) == -1) return (-1); } evdp = &devpollop->fds[fd]; /* * It's not necessary to OR the existing read/write events that we * are currently interested in with the new event we are adding. * The /dev/poll driver ORs any new events with the existing events * that it has cached for the fd. */ events = 0; if (ev->ev_events & OPAL_EV_READ) { if (evdp->evread && evdp->evread != ev) { /* There is already a different read event registered */ return(-1); } events |= POLLIN; } if (ev->ev_events & OPAL_EV_WRITE) { if (evdp->evwrite && evdp->evwrite != ev) { /* There is already a different write event registered */ return(-1); } events |= POLLOUT; } if (devpoll_queue(devpollop, fd, events) != 0) return(-1); /* Update events responsible */ if (ev->ev_events & OPAL_EV_READ) evdp->evread = ev; if (ev->ev_events & OPAL_EV_WRITE) evdp->evwrite = ev; return (0); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; //signal 的添加部分,直接调用signal添加函数 if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; //fd总是系统中空闲的最小fd,判断fds是否够,不够扩大 if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } //fds 和 events数组的索引是一致的都是fd evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; //若相应的fd已经添加了相应的event //再次添加回覆盖evepoll中的event指针 if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.fd = fd; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
int main() { struct event_base *eb; struct event *ev1, *ev2; pthread_t pid; /*init event_base*/ eb = event_base_new(); assert(eb); ev1 = evsignal_new(eb, SIGUSR1, signal_handler, (void*)0x1); assert(ev1); assert(evsignal_add(ev1, NULL) == 0); ev2 = evsignal_new(eb, SIGUSR2, signal_handler, (void*)0x2); assert(ev2); assert(evsignal_add(ev2, NULL) == 0); assert(pthread_create(&pid, NULL, emit_signal, NULL) == 0); /*start loop*/ assert(event_base_loop(eb, EVLOOP_ONCE) == 0); assert(pthread_join(pid, NULL) == 0); assert(evsignal_del(ev1) == 0); assert(evsignal_del(ev2) == 0); event_free(ev1); event_free(ev2); /*destroy event_base*/ event_base_free(eb); return 0; }
int add_signal(int signum, struct event *event) { if (!event) { event = evsignal_new(base, signum, cb_signal, NULL); if (!event) { log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, "%s %d: evsignal_new failed[%d]", __FUNCTION__, __LINE__, errno); return (-1); } event->ev_arg = event; } else { evsignal_assign(event, base, signum, event->ev_callback, NULL); } return evsignal_add(event, NULL); }
int main(int argc, char **argv) { struct event_base *base; struct evconnlistener *listener; struct sockaddr_in sin; struct event *evstop; int port = 9876; if (argc > 1) { port = atoi(argv[1]); } if (port<=0 || port>65535) { puts("Invalid port"); return 1; } signal(SIGPIPE, SIG_IGN); base = event_base_new(); if (!base) { puts("Couldn't open event base"); return 1; } evstop = evsignal_new(base, SIGHUP, signal_cb, base); evsignal_add(evstop, NULL); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0); sin.sin_port = htons(port); listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&sin, sizeof(sin)); if (!listener) { perror("Couldn't create listener"); return 1; } event_base_dispatch(base); evconnlistener_free(listener); event_free(evstop); event_base_free(base); return 0; }
static void logged_in(sp_session *session, sp_error error) { if (error != SP_ERROR_OK) { fprintf(stderr, "%s\n", sp_error_message(error)); exit_status = EXIT_FAILURE; logged_out(session); return; } struct state *state = sp_session_userdata(session); state->session = session; evsignal_add(state->sigint, NULL); sp_playlistcontainer *pc = sp_session_playlistcontainer(session); sp_playlistcontainer_add_callbacks(pc, &playlistcontainer_callbacks, session); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.fd = fd; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(&epollop->evsigmask, ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; // NOTE: 以fd作为下标 的一个指针,指向数组, op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; // NOTE: 这里作为一个指针 epev.events = events; // NOTE 疑问, epev是局部变量,可以直接传指针? 应该是没问题,内核复制一份 if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; // 在这里真正复制了 对应的事件 返回的时候就能看到 if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
static void create_base() { signal(SIGINT,sig_int); // strTag->pid = getpid(); struct event_base *base = event_base_new(); struct timeval tv = {5,0}; struct event sig; struct event timeout; evtimer_assign(&timeout,base,timerout1,&timeout); evtimer_add(&timeout,&tv); evsignal_assign(&sig,base,SIGUSR2,sig_act1,&sig); evsignal_add(&sig,NULL); event_base_dispatch(base); printf("child break loopbase!!\n"); event_base_free(base); sleep(5); }
static int select_add(void *arg, struct event *ev) { struct selectop *sop = arg; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); check_selectop(sop); /* * Keep track of the highest fd, so that we can calculate the size * of the fd_sets for select(2) */ if (sop->event_fds < ev->ev_fd) { size_t fdsz = sop->event_fdsz; if (fdsz < sizeof(fd_mask)) fdsz = sizeof(fd_mask); while (fdsz < (howmany(ev->ev_fd + 1, NFDBITS) * sizeof(fd_mask))) fdsz *= 2; if (fdsz != sop->event_fdsz) { if (select_resize(sop, fdsz)) { check_selectop(sop); return (-1); } } sop->event_fds = ev->ev_fd; } if (ev->ev_events & EV_READ) { FD_SET(ev->ev_fd, sop->event_readset_in); sop->event_r_by_fd[ev->ev_fd] = ev; } if (ev->ev_events & EV_WRITE) { FD_SET(ev->ev_fd, sop->event_writeset_in); sop->event_w_by_fd[ev->ev_fd] = ev; } check_selectop(sop); return (0); }
static int evport_add (void *arg, struct event *ev) { struct evport_data *evpd = arg; struct fd_info *fdi; int factor; check_evportop (evpd); /* * Delegate, if it's not ours to handle. */ if (ev->ev_events & EV_SIGNAL) return (evsignal_add (ev) ); /* * If necessary, grow the file descriptor info table */ factor = 1; while (ev->ev_fd >= factor * evpd->ed_nevents) factor *= 2; if (factor > 1) { if (-1 == grow (evpd, factor) ) { return (-1); } } fdi = &evpd->ed_fds[ev->ev_fd]; if (ev->ev_events & EV_READ) fdi->fdi_revt = ev; if (ev->ev_events & EV_WRITE) fdi->fdi_wevt = ev; return reassociate (evpd, fdi, ev->ev_fd); }
void logged_in(sp_session *session, sp_error error) { struct state *state = sp_session_userdata(session); if (error != SP_ERROR_OK) { syslog(LOG_CRIT, "Error logging in to Spotify: %s", sp_error_message(error)); state->exit_status = EXIT_FAILURE; logged_out(session); return; } state->session = session; evsignal_add(state->sigint, NULL); sp_playlistcontainer *pc = sp_session_playlistcontainer(session); sp_playlistcontainer_add_callbacks(pc, &playlistcontainer_callbacks, session); }
/* Terminate gracefully on SIGTERM */ void sigterm_cb(int fd, short event, void * arg) { evbase_t * evbase = (evbase_t *)arg; struct timeval tv = { .tv_usec = 100000, .tv_sec = 0 }; /* 100 ms */ event_base_loopexit(evbase, &tv); } void init_thread_cb(evhtp_t * htp, evthr_t * thr, void * arg) { static int aux = 0; printf("Spinning up a thread: %d\n", ++aux); evthr_set_aux(thr, &aux); } int main(int argc, char ** argv) { struct event *ev_sigterm; evbase_t * evbase = event_base_new(); evhtp_t * evhtp = evhtp_new(evbase, NULL); evhtp_set_gencb(evhtp, frontend_cb, NULL); #ifndef EVHTP_DISABLE_SSL evhtp_ssl_cfg_t scfg1 = { 0 }; scfg1.pemfile = "./server.pem"; scfg1.privfile = "./server.pem"; evhtp_ssl_init(evhtp, &scfg1); #endif evhtp_use_threads(evhtp, init_thread_cb, 8, NULL); #ifndef WIN32 ev_sigterm = evsignal_new(evbase, SIGTERM, sigterm_cb, evbase); evsignal_add(ev_sigterm, NULL); #endif evhtp_bind_socket(evhtp, "0.0.0.0", 8081, 1024); event_base_loop(evbase, 0); printf("Clean exit\n"); return 0; }
LibeventServer::LibeventServer() { base_ = event_base_new(); // Create our event base if (!base_) { throw ConnectionException("Couldn't open event base"); } // Add hang up signal event ev_stop_ = evsignal_new(base_, SIGHUP, ControlCallback::Signal_Callback, base_); evsignal_add(ev_stop_, NULL); // Add timeout event to check server's start/close flag every one second struct timeval one_seconds = {1, 0}; ev_timeout_ = event_new(base_, -1, EV_TIMEOUT | EV_PERSIST, ControlCallback::ServerControl_Callback, this); event_add(ev_timeout_, &one_seconds); // a master thread is responsible for coordinating worker threads. master_thread_ = std::make_shared<LibeventMasterThread>(CONNECTION_THREAD_COUNT, base_); port_ = FLAGS_port; max_connections_ = FLAGS_max_connections; private_key_file_ = FLAGS_private_key_file; certificate_file_ = FLAGS_certificate_file; // For logging purposes // event_enable_debug_mode(); // event_set_log_callback(LogCallback); // Commented because it's not in the libevent version we're using // When we upgrade this should be uncommented // event_enable_debug_logging(EVENT_DBG_ALL); // Ignore the broken pipe signal // We don't want to exit on write when the client disconnects signal(SIGPIPE, SIG_IGN); }
static void lgtd_setup_signal_handling(void) { for (int i = 0; i != LGTD_ARRAY_SIZE(lgtd_signals); i++) { lgtd_signal_evs[i] = evsignal_new( lgtd_ev_base, lgtd_signals[i], lgtd_signal_event_callback, // event_self_cbarg() would make things cleaner, but this was // unfortunately added in libevent 2.1 which hasn't been released // as of 2016: (void *)(intptr_t)i // cast twice for -Wint-to-void-pointer-cast ); if (!lgtd_signal_evs[i] || evsignal_add(lgtd_signal_evs[i], NULL)) { lgtd_err(1, "can't configure signal handling"); } } struct sigaction act = { .sa_handler = SIG_IGN }; if (sigaction(SIGPIPE, &act, NULL)) { lgtd_err(1, "can't configure signal handling"); } }
int main(int argc, char **argv) { struct context ctx = {0}; struct event *signal_int; struct evhttp_bound_socket *handle; char listen_addr[256]; if (argc != 2) { printf("usage: statsrv STATS\n"); return -1; } if (stats_cl_create(&ctx.cl) != S_OK) { printf("Failed to allocate stats counter list\n"); return ERROR_FAIL; } if (stats_sample_create(&ctx.sample) != S_OK) { printf("Failed to allocate stats sample\n"); return ERROR_FAIL; } if (stats_sample_create(&ctx.prev_sample) != S_OK) { printf("Failed to allocate stats sample\n"); return ERROR_FAIL; } ctx.stats = open_stats(argv[1]); if (!ctx.stats) { printf("Failed to open stats %s\n", argv[1]); return ERROR_FAIL; } ctx.base = event_base_new(); if (!ctx.base) { printf("Could not allocate event base\n"); return 1; } /* add a handler for SIGINT */ signal_int = evsignal_new(ctx.base, SIGINT, sigint_cb, event_self_cbarg()); evsignal_add(signal_int,0); /* Create a new evhttp object to handle requests. */ ctx.http = evhttp_new(ctx.base); if (!ctx.http) { printf("could not create evhttp.\n"); return ERROR_FAIL; } evhttp_set_gencb(ctx.http, http_request_cb, &ctx); /* Now we tell the evhttp what port to listen on */ handle = evhttp_bind_socket_with_handle(ctx.http, "0.0.0.0", 8080); if (!handle) { printf("couldn't bind to http port %d.\n", (int)8080); return ERROR_FAIL; } if (http_get_address(handle, listen_addr, sizeof(listen_addr)) == S_OK) printf("http: listening at %s\n", listen_addr); event_base_dispatch(ctx.base); event_free(signal_int); #if 0 start_time = current_time(); while (!signal_received) { err = stats_get_sample(stats,cl,sample); if (err != S_OK) { printf("Error %08x (%s) getting sample\n",err,error_message(err)); } clear(); sample_time = TIME_DELTA_TO_NANOS(start_time, sample->sample_time); mvprintw(0,0,"SAMPLE @ %6lld.%03llds SEQ:%d\n", sample_time / 1000000000ll, (sample->sample_time % 1000000000ll) / 1000000ll, sample->sample_seq_no); n = 1; maxy = getmaxy(stdscr); col = 0; for (j = 0; j < cl->cl_count; j++) { counter_get_key(cl->cl_ctr[j],counter_name,MAX_COUNTER_KEY_LENGTH+1); mvprintw(n,col+0,"%s", counter_name); mvprintw(n,col+29,"%15lld", stats_sample_get_value(sample,j)); mvprintw(n,col+46,"%15lld", stats_sample_get_delta(sample,prev_sample,j)); if (++n == maxy) { col += 66; n = 1; } } refresh(); tmp = prev_sample; prev_sample = sample; sample = tmp; FD_ZERO(&fds); FD_SET(0,&fds); now = current_time(); tv.tv_sec = 0; tv.tv_usec = 1000000 - (now % 1000000000) / 1000; ret = select(1, &fds, NULL, NULL, &tv); if (ret == 1) { ch = getch(); if (ch == 'c' || ch == 'C') { stats_reset_counters(stats); } } } close_screen(); #endif if (ctx.base) event_base_free(ctx.base); if (ctx.http) evhttp_free(ctx.http); if (ctx.stats) { stats_close(ctx.stats); stats_free(ctx.stats); } if (ctx.cl) stats_cl_free(ctx.cl); if (ctx.sample) stats_sample_free(ctx.sample); if (ctx.prev_sample) stats_sample_free(ctx.prev_sample); return 0; }
static int poll_add(void *arg, struct event *ev) { struct pollop *pop = arg; struct pollfd *pfd = NULL; int i; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); if (!(ev->ev_events & (EV_READ|EV_WRITE))) return (0); poll_check_ok(pop); if (pop->nfds + 1 >= pop->event_count) { struct pollfd *tmp_event_set; struct event **tmp_event_r_back; struct event **tmp_event_w_back; int tmp_event_count; if (pop->event_count < 32) tmp_event_count = 32; else tmp_event_count = pop->event_count * 2; /* We need more file descriptors */ tmp_event_set = realloc(pop->event_set, tmp_event_count * sizeof(struct pollfd)); if (tmp_event_set == NULL) { event_warn("realloc"); return (-1); } pop->event_set = tmp_event_set; tmp_event_r_back = realloc(pop->event_r_back, tmp_event_count * sizeof(struct event *)); if (tmp_event_r_back == NULL) { /* event_set overallocated; that's okay. */ event_warn("realloc"); return (-1); } pop->event_r_back = tmp_event_r_back; tmp_event_w_back = realloc(pop->event_w_back, tmp_event_count * sizeof(struct event *)); if (tmp_event_w_back == NULL) { /* event_set and event_r_back overallocated; that's * okay. */ event_warn("realloc"); return (-1); } pop->event_w_back = tmp_event_w_back; pop->event_count = tmp_event_count; } if (ev->ev_fd >= pop->fd_count) { int *tmp_idxplus1_by_fd; int new_count; if (pop->fd_count < 32) new_count = 32; else new_count = pop->fd_count * 2; while (new_count <= ev->ev_fd) new_count *= 2; tmp_idxplus1_by_fd = realloc(pop->idxplus1_by_fd, new_count * sizeof(int)); if (tmp_idxplus1_by_fd == NULL) { event_warn("realloc"); return (-1); } pop->idxplus1_by_fd = tmp_idxplus1_by_fd; memset(pop->idxplus1_by_fd + pop->fd_count, 0, sizeof(int)*(new_count - pop->fd_count)); pop->fd_count = new_count; } i = pop->idxplus1_by_fd[ev->ev_fd] - 1; if (i >= 0) { pfd = &pop->event_set[i]; } else { i = pop->nfds++; pfd = &pop->event_set[i]; pfd->events = 0; pfd->fd = ev->ev_fd; pop->event_w_back[i] = pop->event_r_back[i] = NULL; pop->idxplus1_by_fd[ev->ev_fd] = i + 1; } pfd->revents = 0; if (ev->ev_events & EV_WRITE) { pfd->events |= POLLOUT; pop->event_w_back[i] = ev; } if (ev->ev_events & EV_READ) { pfd->events |= POLLIN; pop->event_r_back[i] = ev; } poll_check_ok(pop); return (0); }
int main(int argc, char** argv) { /* Set the CWD */ char *home = getenv("HOME"); if (!home) { printf("Failed to load data directory\n"); return EXIT_FAILURE; } char *datadir = malloc(strlen(home) + 10); snprintf(datadir, strlen(home) + 10, "%s/.bitpeer", home); if (chdir(datadir) < 0) { if (mkdir(datadir, 0777) < 0) { printf("Failed to create data directory.\n"); return EXIT_FAILURE; } if (chdir(datadir) < 0) { printf("Failed to chdir\n"); return EXIT_FAILURE; } } free(datadir); /* For safety we do these protocol struct assertions */ assert(sizeof(bp_proto_message_s) == 24); assert(sizeof(bp_proto_net_addr_s) == 26); assert(sizeof(bp_proto_net_addr_full_s) == 30); assert(sizeof(bp_proto_version_s) == 80); assert(sizeof(bp_proto_inv_s) == 36); assert(sizeof(bp_btcblock_header_s) == 80); /* Set the settings */ bp_program_s program; memset(&program, 0, sizeof(program)); program.addrpool_size = 20480; program.min_connections = 8; program.max_connections = 4096; program.reindex_blocks = 0; program.relay_transactions = 1; program.relay_blocks = 1; program.txpool_size = 1024; program.blocks_per_getblocks = 500; /* Interpret the command line */ if (argc < 2) { printf("Invalid command line arguments.\n"); printf("Usage: bitpeer [listen_port] [public_ip] -n [seed_node]\n"); printf("public_ip and seed_node may optionally contain a port number.\n"); return EXIT_FAILURE; } unsigned short listen_port = atoi(argv[1]); if (listen_port == 0) { printf("Invalid port number specified. Valid ports go from 1 to 65535.\n"); return EXIT_FAILURE; } struct sockaddr_in6 sockaddr; int sockaddr_len = sizeof(struct sockaddr_in6); if (evutil_parse_sockaddr_port(argv[2], (struct sockaddr*)&sockaddr, &sockaddr_len) < 0) { printf("Invalid public_ip specified\n"); return EXIT_FAILURE; } if (sockaddr.sin6_family == AF_INET) { sockaddr = bp_in4to6((struct sockaddr_in*)&sockaddr); sockaddr_len = sizeof(struct sockaddr_in6); } if (sockaddr.sin6_port == 0) { sockaddr.sin6_port = ntohs(listen_port); } int nodecount = 0; struct sockaddr_in6 *nodeaddrs = NULL; int *nodelens = NULL; int *nodeperm = NULL; /* Now interpret the optional arguments */ // Quick preprocessor macro to go to the next argv #define NEXT_I() {i++; if (i >= argc) { printf("Argument for %s missing\n", argv[i-1]); return EXIT_FAILURE; }} for (int i = 3; i < argc; i++) { if (strcmp(argv[i], "--reindex") == 0) { program.reindex_blocks = 1; } else if (strcmp(argv[i], "--addnode") == 0 || strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--addpnode") == 0 || strcmp(argv[i], "-p") == 0) { NEXT_I(); nodeaddrs = realloc(nodeaddrs, (nodecount+1) * sizeof(struct sockaddr_in6)); nodelens = realloc(nodelens, (nodecount+1) * sizeof(int)); nodeperm = realloc(nodeperm, (nodecount+1) * sizeof(int)); nodelens[nodecount] = sizeof(struct sockaddr_in6); nodeperm[nodecount] = 0; if (strcmp(argv[i-1], "--addpnode") == 0 || strcmp(argv[i-1], "-p") == 0) { printf("Adding a permanent node\n"); nodeperm[nodecount] = 1; } struct sockaddr_in6 *addr = &nodeaddrs[nodecount]; memset(addr, 0, sizeof(struct sockaddr_in6)); if (evutil_parse_sockaddr_port(argv[i], (struct sockaddr*)addr, nodelens+nodecount) < 0) { printf("Invalid node address specified: %s %d\n", argv[i], nodelens[nodecount]); return EXIT_FAILURE; } if (addr->sin6_family == AF_INET) { *addr = bp_in4to6((struct sockaddr_in*)addr); nodelens[nodecount] = sizeof(struct sockaddr_in6); } assert(addr->sin6_family == AF_INET6); if (addr->sin6_port == 0) addr->sin6_port = ntohs(8333); nodecount += 1; } else if (strcmp(argv[i], "--txpool") == 0) { NEXT_I(); program.txpool_size = atoi(argv[i]); if (program.txpool_size <= 0) { printf("Invalid argument for %s\n", argv[i-1]); return EXIT_FAILURE; } } else if (strcmp(argv[i], "--addrpool") == 0) { NEXT_I(); program.addrpool_size = atoi(argv[i]); if (program.addrpool_size <= 0) { printf("Invalid argument for %s\n", argv[i-1]); return EXIT_FAILURE; } } else if (strcmp(argv[i], "--getblocks-limit") == 0) { NEXT_I(); program.blocks_per_getblocks = atoi(argv[i]); if (program.blocks_per_getblocks == 0) { printf("Invalid argument for %s\n", argv[i-1]); return EXIT_FAILURE; } } else if (strcmp(argv[i], "--no-tx") == 0) { program.relay_transactions = 0; } else if (strcmp(argv[i], "--no-blocks") == 0) { program.relay_blocks = 0; } else if (strcmp(argv[i], "--minconn") == 0) { NEXT_I(); program.min_connections = atoi(argv[i]); } else if (strcmp(argv[i], "--maxconn") == 0) { NEXT_I(); program.max_connections = atoi(argv[i]); if (program.max_connections <= 0) { printf("Invalid argument for %s\n", argv[i-1]); return EXIT_FAILURE; } } else if (strcmp(argv[i], "--evdebug") == 0) { #ifdef EVENT_DBG_ALL event_enable_debug_logging(EVENT_DBG_ALL); #endif event_set_log_callback(log_cb); event_enable_debug_mode(); } else { printf("Unknown argument '%s'\n", argv[i]); return EXIT_FAILURE; } } /* Ignore SIGPIPE */ struct sigaction act; act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); /* Create the main loop */ bp_program_init(&program); program.eventbase = event_base_new(); /* Set up the signal handler */ struct event *signal_event = evsignal_new(program.eventbase, SIGINT, signal_cb, &program); evsignal_add(signal_event, NULL); /* Create a server */ bp_server_s server; program.server = &server; bp_server_init(&server, &program, (char*)&sockaddr.sin6_addr, ntohs(sockaddr.sin6_port)); if (bp_server_listen(&server, listen_port) < 0) { return EXIT_FAILURE; } /* We need to connect to one initial node in order to seed everything. We will not do this initial discovery ourselves. */ for (int i = 0; i < nodecount; i++) { bp_connection_s *seed_connection = malloc(sizeof(bp_connection_s)); int status = bp_connection_connect(seed_connection, &server, &nodeaddrs[i], nodelens[i]); if (status < 0) { printf("Connecting failed\n"); } seed_connection->is_seed = 1; seed_connection->is_permanent = nodeperm[i]; } free(nodeaddrs); free(nodelens); free(nodeperm); /* Run the loop */ event_base_loop(program.eventbase, 0); printf("Entering clean shutdown state\n"); /* It would appear that our loop ended, so clean up */ event_free(signal_event); bp_server_deinit(&server); bp_program_deinit(&program); event_base_free(program.eventbase); return EXIT_SUCCESS; }
int add_signal(lz_event_base_t base, int signal, signal_fn callb, void *arg){ event *ev = evsignal_new((struct event_base *)base, signal, callb, arg); signals.push_back(ev); return evsignal_add(ev, NULL); }
int main(int argc, char **argv) { int error; app_subsys **ss; int exit_signals[2] = {SIGTERM, SIGINT}; struct event terminators[2]; struct event dumper; bool conftest = false; int opt; int i; red_srand(); while ((opt = getopt(argc, argv, "h?vtc:p:")) != -1) { switch (opt) { case 't': conftest = true; break; case 'c': confname = optarg; break; case 'p': pidfile = optarg; break; case 'v': puts(redsocks_version); return EXIT_SUCCESS; default: printf( "Usage: %s [-?hvt] [-c config] [-p pidfile]\n" " -h, -? this message\n" " -v print version\n" " -t test config syntax\n" " -p write pid to pidfile\n", argv[0]); return (opt == '?' || opt == 'h') ? EXIT_SUCCESS : EXIT_FAILURE; } } FILE *f = fopen(confname, "r"); if (!f) { perror("Unable to open config file"); return EXIT_FAILURE; } parser_context* parser = parser_start(f, NULL); if (!parser) { perror("Not enough memory for parser"); return EXIT_FAILURE; } FOREACH(ss, subsystems) if ((*ss)->conf_section) parser_add_section(parser, (*ss)->conf_section); error = parser_run(parser); parser_stop(parser); fclose(f); if (error) return EXIT_FAILURE; if (conftest) return EXIT_SUCCESS; // Initialize global event base g_event_base = event_base_new(); if (!g_event_base) return EXIT_FAILURE; memset(&dumper, 0, sizeof(dumper)); memset(terminators, 0, sizeof(terminators)); FOREACH(ss, subsystems) { if ((*ss)->init) { error = (*ss)->init(); if (error) goto shutdown; } } if (pidfile) { f = fopen(pidfile, "w"); if (!f) { perror("Unable to open pidfile for write"); return EXIT_FAILURE; } fprintf(f, "%d\n", getpid()); fclose(f); } assert(SIZEOF_ARRAY(exit_signals) == SIZEOF_ARRAY(terminators)); for (i = 0; i < SIZEOF_ARRAY(exit_signals); i++) { evsignal_assign(&terminators[i], get_event_base(), exit_signals[i], terminate, NULL); if (evsignal_add(&terminators[i], NULL) != 0) { log_errno(LOG_ERR, "signal_add"); goto shutdown; } } evsignal_assign(&dumper, get_event_base(), SIGUSR1, dump_handler, NULL); if (evsignal_add(&dumper, NULL) != 0) { log_errno(LOG_ERR, "evsignal_add"); goto shutdown; } log_error(LOG_NOTICE, "redsocks started"); event_base_dispatch(g_event_base); log_error(LOG_NOTICE, "redsocks goes down"); shutdown: if (evsignal_initialized(&dumper)) { if (evsignal_del(&dumper) != 0) log_errno(LOG_WARNING, "signal_del"); memset(&dumper, 0, sizeof(dumper)); } for (i = 0; i < SIZEOF_ARRAY(exit_signals); i++) { if (evsignal_initialized(&terminators[i])) { if (evsignal_del(&terminators[i]) != 0) log_errno(LOG_WARNING, "signal_del"); memset(&terminators[i], 0, sizeof(terminators[i])); } } for (--ss; ss >= subsystems; ss--) if ((*ss)->fini) (*ss)->fini(); if (g_event_base) event_base_free(g_event_base); return !error ? EXIT_SUCCESS : EXIT_FAILURE; }