void signal_init(void) { #ifndef WIN32 // Ensure a clean slate by unblocking all signals. For example, if SIGCHLD is // blocked, libuv may hang after spawning a subprocess on Linux. #5230 sigset_t mask; sigemptyset(&mask); if (pthread_sigmask(SIG_SETMASK, &mask, NULL) != 0) { ELOG("Could not unblock signals, nvim might behave strangely."); } #endif signal_watcher_init(&main_loop, &spipe, NULL); signal_watcher_init(&main_loop, &shup, NULL); signal_watcher_init(&main_loop, &squit, NULL); signal_watcher_init(&main_loop, &sterm, NULL); #ifdef SIGPIPE signal_watcher_start(&spipe, on_signal, SIGPIPE); #endif signal_watcher_start(&shup, on_signal, SIGHUP); #ifdef SIGQUIT signal_watcher_start(&squit, on_signal, SIGQUIT); #endif signal_watcher_start(&sterm, on_signal, SIGTERM); #ifdef SIGPWR signal_watcher_init(&main_loop, &spwr, NULL); signal_watcher_start(&spwr, on_signal, SIGPWR); #endif }
void signal_init(void) { signal_watcher_init(&loop, &spipe, NULL); signal_watcher_init(&loop, &shup, NULL); signal_watcher_init(&loop, &squit, NULL); signal_watcher_init(&loop, &sterm, NULL); signal_watcher_start(&spipe, on_signal, SIGPIPE); signal_watcher_start(&shup, on_signal, SIGHUP); signal_watcher_start(&squit, on_signal, SIGQUIT); signal_watcher_start(&sterm, on_signal, SIGTERM); #ifdef SIGPWR signal_watcher_init(&loop, &spwr, NULL); signal_watcher_start(&spwr, on_signal, SIGPWR); #endif }
static int signal_os_watch(lua_State *T, int sig) { struct sigwatcher *s; if (sigismember(&signal_sigset, sig)) goto out; /* already watched */ s = lem_xmalloc(sizeof(struct sigwatcher)); signal_watcher_init(s, sig); ev_set_priority(&s->w, EV_MAXPRI); ev_signal_start(LEM_ &s->w); ev_unref(LEM); /* watcher shouldn't keep loop alive */ sigaddset(&signal_sigset, sig); pthread_sigmask(SIG_UNBLOCK, &signal_sigset, NULL); s->next = signal_watchers; signal_watchers = s; out: lua_pushboolean(T, 1); return 1; }
int main( int i_argc, char **pp_argv ) { const char *psz_network_name = "DVBlast - http://www.videolan.org/projects/dvblast.html"; const char *psz_provider_name = NULL; char *psz_dup_config = NULL; struct sched_param param; int i_error; int c; int b_enable_syslog = 0; struct ev_signal sigint_watcher, sigterm_watcher, sighup_watcher; struct ev_timer quit_watcher; print_fh = stdout; if ( i_argc == 1 ) usage(); /* * The only short options left are: 489 * Use them wisely. */ static const struct option long_options[] = { { "config-file", required_argument, NULL, 'c' }, { "remote-socket", required_argument, NULL, 'r' }, { "ttl", required_argument, NULL, 't' }, { "rtp-output", required_argument, NULL, 'o' }, { "priority", required_argument, NULL, 'i' }, { "adapter", required_argument, NULL, 'a' }, { "frontend-number", required_argument, NULL, 'n' }, { "delsys", required_argument, NULL, '5' }, { "dvb-plp-id", required_argument, NULL, '9' }, { "frequency", required_argument, NULL, 'f' }, { "fec-inner", required_argument, NULL, 'F' }, { "rolloff", required_argument, NULL, 'R' }, { "symbol-rate", required_argument, NULL, 's' }, { "diseqc", required_argument, NULL, 'S' }, { "uncommitted", required_argument, NULL, 'k' }, { "voltage", required_argument, NULL, 'v' }, { "force-pulse", no_argument, NULL, 'p' }, { "bandwidth", required_argument, NULL, 'b' }, { "inversion", required_argument, NULL, 'I' }, { "modulation", required_argument, NULL, 'm' }, { "pilot", required_argument, NULL, 'P' }, { "multistream-id", required_argument, NULL, '1' }, { "fec-lp", required_argument, NULL, 'K' }, { "guard", required_argument, NULL, 'G' }, { "hierarchy", required_argument, NULL, 'H' }, { "transmission", required_argument, NULL, 'X' }, { "lock-timeout", required_argument, NULL, 'O' }, { "budget-mode", no_argument, NULL, 'u' }, { "select-pmts", no_argument, NULL, 'w' }, { "udp", no_argument, NULL, 'U' }, { "unique-ts-id", no_argument, NULL, 'T' }, { "latency", required_argument, NULL, 'L' }, { "retention", required_argument, NULL, 'E' }, { "duplicate", required_argument, NULL, 'd' }, { "passthrough", no_argument, NULL, '3' }, { "rtp-input", required_argument, NULL, 'D' }, { "asi-adapter", required_argument, NULL, 'A' }, { "any-type", no_argument, NULL, 'z' }, { "dvb-compliance", no_argument, NULL, 'C' }, { "emm-passthrough", no_argument, NULL, 'W' }, { "ecm-passthrough", no_argument, NULL, 'Y' }, { "epg-passthrough", no_argument, NULL, 'e' }, { "network-name", no_argument, NULL, 'M' }, { "network-id", no_argument, NULL, 'N' }, { "system-charset", required_argument, NULL, 'j' }, { "dvb-charset", required_argument, NULL, 'J' }, { "provider-name", required_argument, NULL, 'B' }, { "logger", no_argument, NULL, 'l' }, { "logger-ident", required_argument, NULL, 'g' }, { "print", required_argument, NULL, 'x' }, { "quit-timeout", required_argument, NULL, 'Q' }, { "print-period", required_argument, NULL, '6' }, { "es-timeout", required_argument, NULL, '7' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "mrtg-file", required_argument, NULL, 'Z' }, { "ca-number", required_argument, NULL, 'y' }, { "pidmap", required_argument, NULL, '0' }, { "dvr-buf-size", required_argument, NULL, '2' }, { 0, 0, 0, 0 } }; while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:5:f:F:R:s:S:k:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:3D:A:lg:zCWYeM:N:j:J:B:x:Q:6:7:hVZ:y:0:1:2:9:", long_options, NULL)) != -1 ) { switch ( c ) { case 'q': if ( optarg ) { if ( *optarg == 'q' ) /* e.g. -qqq */ { i_verbose--; while ( *optarg == 'q' ) { i_verbose--; optarg++; } } else { i_verbose -= atoi( optarg ); /* e.g. -q2 */ } } else { i_verbose--; /* -q */ } break; case 'c': psz_conf_file = optarg; /* * When configuration file is used it is reasonable to assume that * services may be added/removed. If b_select_pmts is not set dvblast * is unable to start streaming newly added services in the config. */ b_select_pmts = 1; break; case 'r': psz_srv_socket = optarg; break; case 't': i_ttl_global = strtol( optarg, NULL, 0 ); break; case 'o': { struct in_addr maddr; if ( !inet_aton( optarg, &maddr ) ) usage(); memcpy( pi_ssrc_global, &maddr.s_addr, 4 * sizeof(uint8_t) ); break; } case 'i': i_priority = strtol( optarg, NULL, 0 ); break; case 'a': i_adapter = strtol( optarg, NULL, 0 ); break; case 'n': i_fenum = strtol( optarg, NULL, 0 ); break; case 'y': i_canum = strtol( optarg, NULL, 0 ); break; case '5': psz_delsys = optarg; break; case '9': dvb_plp_id = strtol( optarg, NULL, 0 ); break; case 'f': if (optarg && optarg[0] != '-') i_frequency = strtol( optarg, NULL, 0 ); if ( pf_Open != NULL ) usage(); #ifdef HAVE_DVB_SUPPORT pf_Open = dvb_Open; pf_Reset = dvb_Reset; pf_SetFilter = dvb_SetFilter; pf_UnsetFilter = dvb_UnsetFilter; #else msg_Err( NULL, "DVBlast is compiled without DVB support."); exit(1); #endif break; case 'F': i_fec = strtol( optarg, NULL, 0 ); break; case 'R': i_rolloff = strtol( optarg, NULL, 0 ); break; case 's': i_srate = strtol( optarg, NULL, 0 ); break; case 'S': i_satnum = strtol( optarg, NULL, 16 ); break; case 'k': i_uncommitted = strtol( optarg, NULL, 16 ); break; case 'v': i_voltage = strtol( optarg, NULL, 0 ); break; case 'p': b_tone = 1; break; case 'b': i_bandwidth = strtol( optarg, NULL, 0 ); break; case 'I': i_inversion = strtol( optarg, NULL, 0 ); break; case 'm': psz_modulation = optarg; break; case 'P': i_pilot = strtol( optarg, NULL, 0 ); break; case '1': i_mis = strtol( optarg, NULL, 0 ); break; case 'K': i_fec_lp = strtol( optarg, NULL, 0 ); break; case 'G': i_guard = strtol( optarg, NULL, 0 ); break; case 'X': i_transmission = strtol( optarg, NULL, 0 ); break; case 'O': i_frontend_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case 'H': i_hierarchy = strtol( optarg, NULL, 0 ); break; case 'u': b_budget_mode = 1; break; case 'w': b_select_pmts = !b_select_pmts; break; case 'U': b_udp_global = true; break; case 'L': i_latency_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'E': i_retention_global = strtoll( optarg, NULL, 0 ) * 1000; break; case 'd': psz_dup_config = optarg; break; case '3': b_passthrough = true; print_fh = stderr; break; case 'D': psz_udp_src = optarg; if ( pf_Open != NULL ) usage(); pf_Open = udp_Open; pf_Reset = udp_Reset; pf_SetFilter = udp_SetFilter; pf_UnsetFilter = udp_UnsetFilter; break; case 'A': #ifdef HAVE_ASI_SUPPORT if ( pf_Open != NULL ) usage(); if ( strncmp(optarg, "deltacast:", 10) == 0) { #ifdef HAVE_ASI_DELTACAST_SUPPORT i_asi_adapter = strtol( optarg+10, NULL, 0 ); pf_Open = asi_deltacast_Open; pf_Reset = asi_deltacast_Reset; pf_SetFilter = asi_deltacast_SetFilter; pf_UnsetFilter = asi_deltacast_UnsetFilter; #else msg_Err( NULL, "DVBlast is compiled without Deltacast ASI support."); exit(1); #endif } else { i_asi_adapter = strtol( optarg, NULL, 0 ); pf_Open = asi_Open; pf_Reset = asi_Reset; pf_SetFilter = asi_SetFilter; pf_UnsetFilter = asi_UnsetFilter; } #else msg_Err( NULL, "DVBlast is compiled without ASI support."); exit(1); #endif break; case 'z': b_any_type = 1; break; case 'C': b_dvb_global = true; break; case 'W': b_enable_emm = true; break; case 'Y': b_enable_ecm = true; break; case 'e': b_epg_global = true; break; case 'M': psz_network_name = optarg; break; case 'N': i_network_id = strtoul( optarg, NULL, 0 ); break; case 'T': b_random_tsid = 1; break; case 'j': psz_native_charset = optarg; break; case 'J': psz_dvb_charset = optarg; break; case 'B': psz_provider_name = optarg; break; case 'l': b_enable_syslog = 1; break; case 'g': psz_syslog_ident = optarg; break; case 'x': b_print_enabled = true; if ( !strcmp(optarg, "text") ) i_print_type = PRINT_TEXT; else if ( !strcmp(optarg, "xml") ) i_print_type = PRINT_XML; else { b_print_enabled = false; msg_Warn( NULL, "unrecognized print type %s", optarg ); } break; case 'Q': i_quit_timeout_duration = strtoll( optarg, NULL, 0 ) * 1000; break; case '6': i_print_period = strtoll( optarg, NULL, 0 ) * 1000; break; case '7': i_es_timeout = strtoll( optarg, NULL, 0 ) * 1000; break; case 'V': DisplayVersion(); exit(0); break; case 'Z': psz_mrtg_file = optarg; break; case '0': { /* We expect a comma separated list of numbers. Put them into the pi_newpids array as they appear */ char *str1; char *saveptr = NULL; char *tok = NULL; int i, i_newpid; for (i = 0, str1 = optarg; i < N_MAP_PIDS; i++, str1 = NULL) { tok = strtok_r(str1, ",", &saveptr); if ( !tok ) break; i_newpid = strtoul(tok, NULL, 0); if ( !i_newpid ) { msg_Err( NULL, "Invalid pidmap string" ); usage(); } pi_newpids[i] = i_newpid; } b_do_remap = true; break; } #ifdef HAVE_DVB_SUPPORT case '2': i_dvr_buffer_size = strtol( optarg, NULL, 0 ); if (!i_dvr_buffer_size) usage(); // it exits /* roundup to packet size */ i_dvr_buffer_size += TS_SIZE - 1; i_dvr_buffer_size /= TS_SIZE; i_dvr_buffer_size *= TS_SIZE; break; #endif case 'h': default: usage(); } } if ( optind < i_argc || pf_Open == NULL ) usage(); if ( b_enable_syslog ) msg_Connect( psz_syslog_ident ? psz_syslog_ident : pp_argv[0] ); if ( b_print_enabled ) { /* Make std* line-buffered */ setvbuf(print_fh, NULL, _IOLBF, 0); } if ( i_verbose ) DisplayVersion(); msg_Warn( NULL, "restarting" ); switch (i_print_type) { case PRINT_XML: fprintf(print_fh, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); fprintf(print_fh, "<TS>\n"); break; default: break; } if ( b_udp_global ) { msg_Warn( NULL, "raw UDP output is deprecated. Please consider using RTP." ); msg_Warn( NULL, "for DVB-IP compliance you should use RTP." ); } if ( b_epg_global && !b_dvb_global ) { msg_Dbg( NULL, "turning on DVB compliance, required by EPG information" ); b_dvb_global = true; } if ((event_loop = ev_default_loop(0)) == NULL) { msg_Err( NULL, "unable to initialize libev" ); exit(EXIT_FAILURE); } memset( &output_dup, 0, sizeof(output_dup) ); if ( psz_dup_config != NULL ) { output_config_t config; config_Defaults( &config ); if ( !config_ParseHost( &config, psz_dup_config ) ) msg_Err( NULL, "Invalid target address for -d switch" ); else { output_Init( &output_dup, &config ); output_Change( &output_dup, &config ); } config_Free( &config ); } config_strdvb( &network_name, psz_network_name ); config_strdvb( &provider_name, psz_provider_name ); /* Set signal handlers */ signal_watcher_init(&sigint_watcher, event_loop, sighandler, SIGINT); signal_watcher_init(&sigterm_watcher, event_loop, sighandler, SIGTERM); signal_watcher_init(&sighup_watcher, event_loop, sighandler, SIGHUP); srand( time(NULL) * getpid() ); demux_Open(); // init the mrtg logfile mrtgInit(psz_mrtg_file); if ( i_priority > 0 ) { memset( ¶m, 0, sizeof(struct sched_param) ); param.sched_priority = i_priority; if ( (i_error = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m )) ) { msg_Warn( NULL, "couldn't set thread priority: %s", strerror(i_error) ); } } config_ReadFile(); if ( psz_srv_socket != NULL ) comm_Open(); if ( i_quit_timeout_duration ) { ev_timer_init(&quit_watcher, quit_cb, i_quit_timeout_duration / 1000000., 0); ev_timer_start(event_loop, &quit_watcher); } outputs_Init(); ev_run(event_loop, 0); mrtgClose(); outputs_Close( i_nb_outputs ); demux_Close(); dvb_string_clean( &network_name ); dvb_string_clean( &provider_name ); if ( conf_iconv != (iconv_t)-1 ) iconv_close( conf_iconv ); switch (i_print_type) { case PRINT_XML: fprintf(print_fh, "</TS>\n"); break; default: break; } if ( b_enable_syslog ) msg_Disconnect(); comm_Close(); block_Vacuum(); return EXIT_SUCCESS; }