/* This stays around for as long as the initial process in the app does * and when that exits it exits, propagating the exit status. We do this * by having pid 1 in the sandbox detect this exit and tell the monitor * the exit status via a eventfd. We also track the exit of the sandbox * pid 1 via a signalfd for SIGCHLD, and exit with an error in this case. * This is to catch e.g. problems during setup. */ static void monitor_child (int event_fd) { int res; uint64_t val; ssize_t s; int signal_fd; sigset_t mask; struct pollfd fds[2]; int num_fds; struct signalfd_siginfo fdsi; int dont_close[] = { event_fd, -1 }; /* Close all extra fds in the monitoring process. Any passed in fds have been passed on to the child anyway. */ fdwalk (proc_fd, close_extra_fds, dont_close); sigemptyset (&mask); sigaddset (&mask, SIGCHLD); signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); if (signal_fd == -1) die_with_error ("Can't create signalfd"); num_fds = 1; fds[0].fd = signal_fd; fds[0].events = POLLIN; if (event_fd != -1) { fds[1].fd = event_fd; fds[1].events = POLLIN; num_fds++; } while (1) { fds[0].revents = fds[1].revents = 0; res = poll (fds, num_fds, -1); if (res == -1 && errno != EINTR) die_with_error ("poll"); /* Always read from the eventfd first, if pid 2 died then pid 1 often * dies too, and we could race, reporting that first and we'd lose * the real exit status. */ if (event_fd != -1) { s = read (event_fd, &val, 8); if (s == -1 && errno != EINTR && errno != EAGAIN) die_with_error ("read eventfd"); else if (s == 8) exit ((int)val - 1); } s = read (signal_fd, &fdsi, sizeof (struct signalfd_siginfo)); if (s == -1 && errno != EINTR && errno != EAGAIN) die_with_error ("read signalfd"); else if (s == sizeof(struct signalfd_siginfo)) { if (fdsi.ssi_signo != SIGCHLD) die ("Read unexpected signal\n"); exit (fdsi.ssi_status); } } }
void* audio_write_start(void *arg) { int idle = 1; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int len; sigset_t sigs; demux_attr_t *attr; video_info_t *vi; signal(SIGURG, sighandler); sigemptyset(&sigs); sigaddset(&sigs, SIGURG); pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); pthread_mutex_lock(&mutex); printf("audio write thread started (pid %d)\n", getpid()); pthread_cond_wait(&video_cond, &mutex); while (1) { while (seeking || jumping) pthread_cond_wait(&video_cond, &mutex); while (!video_playing) { pcm_decoded = 0; empty_ac3(); if ( !(idle) ) { sem_post(&write_threads_idle_sem); idle = 1; printf("audio write thread sleeping...\n"); } pthread_cond_wait(&video_cond, &mutex); } if ( idle ) { sem_wait(&write_threads_idle_sem); idle = 0; printf("audio write thread running\n"); } if (running_replaytv) { attr = demux_get_attr(handle); vi = &attr->video.stats.info.video; if (attr->audio.type != audio_type) { // JBH: FIX ME: This code never gets hit audio_type = attr->audio.type; switch (audio_type) { case AUDIO_MODE_AC3: case AUDIO_MODE_PCM: audio_output = AV_AUDIO_PCM; printf("switch to PCM audio\n"); break; default: av_set_audio_type(audio_type); audio_output = AV_AUDIO_MPEG; printf("switch to MPEG audio\n"); break; } av_set_audio_output(audio_output); } } switch (audio_type) { case AUDIO_MODE_MPEG1_PES: case AUDIO_MODE_MPEG2_PES: case AUDIO_MODE_ES: if (jit_mode == 0) { if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0) pthread_cond_broadcast(&video_cond); else pthread_cond_wait(&video_cond, &mutex); } else { int flags, duration; len=DEMUX_JIT_WRITE_AUDIO(handle, fd_audio, get_cur_vid_stc(),jit_mode, &flags,&duration); if(flags & 4) { /*4 is the same as 1 followed by 2*/ flags = (flags | 1 | 2) & ~4; } if(flags & 1) { av_pause_video(); } if((flags & 2) && !paused) { if(duration <= 10) video_unpause_timer_callback(pause_widget); else mvpw_set_timer(pause_widget, video_unpause_timer_callback, duration); } if(flags & 8) { usleep(duration*1000); } if(len > 0) pthread_cond_broadcast(&video_cond); else if(!(flags & 8)) pthread_cond_wait(&video_cond, &mutex); } break; case AUDIO_MODE_PCM: /* * XXX: PCM audio does not work yet */ pthread_cond_wait(&video_cond, &mutex); break; case AUDIO_MODE_AC3: if (audio_output_mode == AUD_OUTPUT_PASSTHRU ) { if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0) pthread_cond_broadcast(&video_cond); else pthread_cond_wait(&video_cond, &mutex); break; } if (ac3more == -1) ac3more = a52_decode_data(NULL, NULL, pcm_decoded); if (ac3more == 1) { ac3more = a52_decode_data(ac3buf, ac3buf + ac3len, pcm_decoded); if (ac3more == 1) { pthread_cond_wait(&video_cond, &mutex); break; } } if (ac3more == 0) { ac3len = demux_get_audio(handle, ac3buf, sizeof(ac3buf)); ac3more = 1; } if (ac3more == 0) pthread_cond_wait(&video_cond, &mutex); else pthread_cond_broadcast(&video_cond); pcm_decoded = 1; break; } } return NULL; }
int main(int argc, char *argv[]) { struct usb_serial_test *serial; unsigned size = 0; uint8_t fixed = 0; int if_num = 0; int alt_set = 0; uint8_t eprx = 0; uint8_t eptx = 0; int ret = 0; unsigned vid = 0; unsigned pid = 0; struct sigaction sa; sa.sa_handler = signal_exit; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGINT, &sa, NULL) == -1) printf("failed to handle signal\n"); (void) signal(SIGINT, signal_exit); while (ARRAY_SIZE(serial_opts)) { int optidx = 0; int opt; opt = getopt_long(argc, argv, "v:p:s:i:a:r:t:dhf", serial_opts, &optidx); if (opt < 0) break; switch (opt) { case 'v': vid = strtoul(optarg, NULL, 16); break; case 'p': pid = strtoul(optarg, NULL, 16); break; case 'r': eprx = strtol(optarg,NULL, 16); break; case 't': eptx = strtol(optarg, NULL, 16); break; case 'i': if_num = atoi(optarg); break; case 'a': alt_set = atoi(optarg); break; case 's': size = atoi(optarg); if (size == 0) { DBG("%s: can't do it with zero length buffer\n", __func__); ret = -EINVAL; goto err0; } break; case 'f': fixed = 1; break; case 'd': debug = 1; break; case 'h': /* FALLTHROUGH */ default: usage(argv[0]); return 1; } } if (!vid || !pid) { fprintf(stderr, "%s: missing arguments\n" "Try `%s --help' for more information\n", argv[0], argv[0]); return 1; } serial = malloc(sizeof(*serial)); if (!serial) { fprintf(stderr, "%s: unable to allocate memory\n", argv[0]); ret = -ENOMEM; goto err0; } memset(serial, 0x00, sizeof(*serial)); serial->size = size; serial->eprx = eprx; serial->eptx = eptx; serial->interface_num = if_num; serial->alt_setting = alt_set; serial->write_mintput = MIN_TPUT; serial->read_mintput = MIN_TPUT; ret = alloc_and_init_buffer(serial); if (ret < 0) { fprintf(stderr, "%s: failed to allocate buffers\n", argv[0]); goto err1; } serial->udevh = open_with_vid_pid(vid, pid); if (serial->udevh < 0) { fprintf(stderr, "%s: open failed %s\n", argv[0], strerror(errno)); goto err2; } /* get descriptors, find correct interface to claim and * set correct alternate setting */ ret = find_and_claim_interface(serial); if (ret < 0) { fprintf(stderr, "%s: unable to claim interface: %s\n", argv[0], strerror(errno)); goto err2; } if (!fixed) srandom(time(NULL)); printf("\n"); do { float transferred = 0; int i; unsigned n; char *unit = NULL; if (!fixed) { /* We want packet size to be in range [4 , serial->size], * as first four bytes are holding the packet size */ n = random() % (serial->size - 3) + 4; } else { n = size; } DBG("%s sending %d bytes\n", __func__, n); ret = do_test(serial, n); if (ret < 0) { fprintf(stderr, "%s: test failed: %s\n", argv[0], strerror(errno)); goto err3; } transferred = (float) serial->transferred; for (i = 0; i < ARRAY_SIZE(units); i++) { if (transferred > 1024.0) { transferred /= 1024.0; continue; } unit = units[i]; break; } if (debug == 0) { printf("[ V%04x P%04x Transferred %10.04f %sByte%s read %10.02f Mb/s write %10.02f Mb/s ]\n", vid, pid, transferred, unit, transferred > 1 ? "s" : "", serial->read_tput, serial->write_tput); printf("[ read min: %10.02f Mb/s - max: %10.02f Mb/s - avg: %10.02f Mb/s ]\n", serial->read_mintput, serial->read_maxtput, serial->read_avgtput); printf("[ write min: %10.02f Mb/s - max: %10.02f Mb/s - avg: %10.02f Mb/s ]\n", serial->write_mintput, serial->write_maxtput, serial->write_avgtput); printf("\033[3A"); fflush(stdout); } } while (alive); printf("\n\n\n"); release_interface(serial); close(serial->udevh); free(serial->rxbuf); free(serial->txbuf); free(serial); return 0; err3: release_interface(serial); err2: close(serial->udevh); free(serial->rxbuf); free(serial->txbuf); err1: free(serial); err0: return ret; }
int main(int argc, char **argv) { int ch; unsigned long i; int foreground, preserve; int error, pstat, status; int killsig = SIGTERM; pid_t pid, cpid; double first_kill; double second_kill; bool timedout = false; bool do_second_kill = false; bool child_done = false; struct sigaction signals; struct procctl_reaper_status info; struct procctl_reaper_kill killemall; int signums[] = { -1, SIGTERM, SIGINT, SIGHUP, SIGCHLD, SIGALRM, SIGQUIT, }; foreground = preserve = 0; second_kill = 0; const struct option longopts[] = { { "preserve-status", no_argument, &preserve, 1 }, { "foreground", no_argument, &foreground, 1 }, { "kill-after", required_argument, NULL, 'k'}, { "signal", required_argument, NULL, 's'}, { "help", no_argument, NULL, 'h'}, { NULL, 0, NULL, 0 } }; while ((ch = getopt_long(argc, argv, "+k:s:h", longopts, NULL)) != -1) { switch (ch) { case 'k': do_second_kill = true; second_kill = parse_duration(optarg); break; case 's': killsig = parse_signal(optarg); break; case 0: break; case 'h': default: usage(); break; } } argc -= optind; argv += optind; if (argc < 2) usage(); first_kill = parse_duration(argv[0]); argc--; argv++; if (!foreground) { /* Aquire a reaper */ if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1) err(EX_OSERR, "Fail to acquire the reaper"); } memset(&signals, 0, sizeof(signals)); sigemptyset(&signals.sa_mask); if (killsig != SIGKILL && killsig != SIGSTOP) signums[0] = killsig; for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++) sigaddset(&signals.sa_mask, signums[i]); signals.sa_handler = sig_handler; signals.sa_flags = SA_RESTART; for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++) if (signums[i] != -1 && signums[i] != 0 && sigaction(signums[i], &signals, NULL) == -1) err(EX_OSERR, "sigaction()"); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); pid = fork(); if (pid == -1) err(EX_OSERR, "fork()"); else if (pid == 0) { /* child process */ signal(SIGTTIN, SIG_DFL); signal(SIGTTOU, SIG_DFL); error = execvp(argv[0], argv); if (error == -1) { if (errno == ENOENT) err(127, "exec(%s)", argv[0]); else err(126, "exec(%s)", argv[0]); } } if (sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL) == -1) err(EX_OSERR, "sigprocmask()"); /* parent continues here */ set_interval(first_kill); for (;;) { sigemptyset(&signals.sa_mask); sigsuspend(&signals.sa_mask); if (sig_chld) { sig_chld = 0; while ((cpid = waitpid(-1, &status, WNOHANG)) != 0) { if (cpid < 0) { if (errno == EINTR) continue; else break; } else if (cpid == pid) { pstat = status; child_done = true; } } if (child_done) { if (foreground) { break; } else { procctl(P_PID, getpid(), PROC_REAP_STATUS, &info); if (info.rs_children == 0) break; } } } else if (sig_alrm) { sig_alrm = 0; timedout = true; if (!foreground) { killemall.rk_sig = killsig; killemall.rk_flags = 0; procctl(P_PID, getpid(), PROC_REAP_KILL, &killemall); } else kill(pid, killsig); if (do_second_kill) { set_interval(second_kill); second_kill = 0; sig_ign = killsig; killsig = SIGKILL; } else break; } else if (sig_term) { if (!foreground) { killemall.rk_sig = sig_term; killemall.rk_flags = 0; procctl(P_PID, getpid(), PROC_REAP_KILL, &killemall); } else kill(pid, sig_term); if (do_second_kill) { set_interval(second_kill); second_kill = 0; sig_ign = killsig; killsig = SIGKILL; } else break; } } while (!child_done && wait(&pstat) == -1) { if (errno != EINTR) err(EX_OSERR, "waitpid()"); } if (!foreground) procctl(P_PID, getpid(), PROC_REAP_RELEASE, NULL); if (WEXITSTATUS(pstat)) pstat = WEXITSTATUS(pstat); else if(WIFSIGNALED(pstat)) pstat = 128 + WTERMSIG(pstat); if (timedout && !preserve) pstat = EXIT_TIMEOUT; return (pstat); }
int main(int argc, char **argv) { int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; int rtn; rtn = shared_memory_attach(); mk_daemon(argc,argv); rtn = shared_memory_attach(); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, RAS_PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } if (!Daemon) printf("server: waiting for connections on port %s...\n",RAS_PORT); while(1) { // main accept() loop sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); if (!Daemon) printf("server: got connection from %s\n", s); if (!fork()) { // this is the child process close(sockfd); // child doesn't need the listener //if (send(new_fd, "Hello, world!\n", 13, 0) == -1) //perror("send"); //close(new_fd); Sockfd = new_fd; rtn = soc_listen(new_fd); exit(0); } close(new_fd); // parent doesn't need this } return (0); }
int main ( int argc, char **argv ) { extern QueueObject_t *IndexQ; struct sigaction sa; sigset_t sigmsk; uint32 count; GlobalAbort = false; /* Parse the command line options */ MainParseArgs( argc, argv ); mainThreadId = pthread_self(); /* * Setup the sigmasks for this thread (which is the parent to all others). * This will propogate to all children. */ sigfillset( &sigmsk ); sigdelset( &sigmsk, SIGUSR1 ); sigdelset( &sigmsk, SIGUSR2 ); sigdelset( &sigmsk, SIGINT ); sigdelset( &sigmsk, SIGSEGV ); sigdelset( &sigmsk, SIGILL ); sigdelset( &sigmsk, SIGFPE ); pthread_sigmask( SIG_SETMASK, &sigmsk, NULL ); /* Start up the Logging thread */ logging_initialize(FALSE); thread_register( &mainThreadId, "thread_main", NULL ); /* Setup signal handler for SIGUSR1 (toggles Debug) */ sa.sa_sigaction = (sigAction_t)logging_toggle_debug; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGUSR1, &sa, NULL ); /* Setup the exit handler */ atexit( MainDelayExit ); /* Setup signal handler for SIGINT (shut down cleanly) */ sa.sa_sigaction = signal_interrupt; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGINT, &sa, NULL ); /* Setup signal handlers that are to be propogated to all threads */ sa.sa_sigaction = signal_everyone; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGUSR2, &sa, NULL ); /* Setup signal handlers for SEGV, ILL, FPE */ sa.sa_sigaction = signal_death; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGSEGV, &sa, NULL ); sigaction( SIGILL, &sa, NULL ); sigaction( SIGFPE, &sa, NULL ); /* Print the startup log messages */ LogBanner(); /* Setup the CLucene indexer */ clucene_init(1); /* Setup the MySQL connection */ db_setup(); db_check_schema_main(); db_rebuild_clucene(); /* Wait for the clucene thread to finish emptying its queue */ while( (count = QueueUsed( IndexQ )) > 0 ) { LogPrint( LOG_INFO, "%d left", count ); sleep( 1 ); } GlobalAbort = TRUE; return(0); }
//---------------------------------------------------------------------- void Demonizer::startWithMonitoring(int(*startFunc)(void), int(*stopFunc)(void), int(*rereadCfgFun)(void)) { this->ms_startFunc = startFunc; this->ms_stopFunc = stopFunc; this->ms_rereadCfgFun = rereadCfgFun; int pid = 0; int status = 0; int need_start = 1; sigset_t sigset; siginfo_t siginfo; sigemptyset(&sigset); sigaddset(&sigset, SIGQUIT); sigaddset(&sigset, SIGINT); //sigaddset(&sigset, SIGTERM); //sigaddset(&sigset, SIGCHLD); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, NULL); for (; ;) { if (need_start) { pid = fork(); if (pid != 0) { sysLogger.log("Fork with pid=" + Logger::itos(pid)); if (SystemTools::checkRunningAndSavePID(getName() + "_worker", pid)) { sysLogger.log("worker daemon is already running"); exit(CHILD_NEED_TERMINATE); } } } need_start = 1; if (pid == -1) { sysLogger.log("Monitor: fork failed with " + std::string(strerror(errno))); } else if (!pid) { //we are child status = this->workProc(); exit(status); } else {// parent sigwaitinfo(&sigset, &siginfo); sysLogger.log("Monitor: wait status..."); if (siginfo.si_signo == SIGCHLD) { sysLogger.log("Monitor: got child status..."); wait(&status); sysLogger.log("Monitor: got exit status"); status = WEXITSTATUS(status); if (status == CHILD_NEED_TERMINATE) { sysLogger.log("Monitor: children stopped"); break; } else if (status == CHILD_NEED_RESTART) {// restart sysLogger.log("Monitor: children restart"); } } else if (siginfo.si_signo == SIGUSR1) {//reread config sysLogger.log("Monitor: resend signal to pid=" + Logger::itos(pid)); kill(pid, SIGUSR1); //resend signal need_start = 0; //don't restart } else { sysLogger.log("Monitor: signal " + std::string(strsignal(siginfo.si_signo))); //kill child kill(pid, SIGTERM); status = 0; break; } } } sysLogger.log("Monitor: stopped"); //delete pid file //unlink(calculateFilenameToStorePID(this->getName())); }
static unsigned char *bktr_device_init(struct video_dev *viddev, int width, int height, unsigned input, unsigned norm, unsigned long freq) { int dev_bktr = viddev->fd_device; struct sigaction act, old; //int dev_tunner = viddev->fd_tuner; /* to ensure that all device will be support the capture mode _TODO_ : Autodected the best capture mode . */ int dummy = 1; // int pixelformat = BSD_VIDFMT_I420; void *map; /* If we have choose the tuner is needed to setup the frequency. */ if ((viddev->tuner_device != NULL) && (input == BKTR_IN_TV)) { if (!freq) { MOTION_LOG(WRN, TYPE_VIDEO, NO_ERRNO, "%s: Not valid Frequency [%lu] for " "Source input [%i]", freq, input); return NULL; } else if (bktr_set_freq(viddev, freq) == -1) { MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Frequency [%lu] Source input [%i]", freq, input); return NULL; } } /* FIXME if we set as input tuner , we need to set option for tuner not for bktr */ if ((dummy = bktr_set_input_device(viddev, input)) == -1) { MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: set input [%d]", input); return NULL; } viddev->input = dummy; if ((dummy = bktr_set_input_format(viddev, norm)) == -1) { MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: set input format [%d]", norm); return NULL; } viddev->norm = dummy; if (bktr_set_geometry(viddev, width, height) == -1) { MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: set geometry [%d]x[%d]", width, height); return NULL; } if (freq) { MOTION_LOG(WRN, TYPE_VIDEO, NO_ERRNO, "%s: Frequency set (no implemented yet"); } /* * Set capture mode and capture buffers * That is the buffer size for capture images , * so is dependent of color space of input format / FIXME */ viddev->v4l_bufsize = (((width * height * 3 / 2)) * sizeof(unsigned char)); viddev->v4l_fmt = VIDEO_PALETTE_YUV420P; map = mmap((caddr_t)0, viddev->v4l_bufsize, PROT_READ|PROT_WRITE, MAP_SHARED, dev_bktr, (off_t)0); if (map == MAP_FAILED) { MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: mmap failed"); return NULL; } /* FIXME double buffer */ if (0) { viddev->v4l_maxbuffer = 2; viddev->v4l_buffers[0] = map; viddev->v4l_buffers[1] = (unsigned char *)map + 0; /* 0 is not valid just a test */ //viddev->v4l_buffers[1] = map+vid_buf.offsets[1]; } else { viddev->v4l_buffers[0] = map; viddev->v4l_maxbuffer = 1; } viddev->v4l_curbuffer = 0; /* Clear the buffer */ if (ioctl(dev_bktr, BT848SCBUF, &dummy) < 0) { MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: BT848SCBUF"); return NULL; } /* Signal handler to know when data is ready to be read() */ memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = catchsignal; sigaction(SIGUSR2, &act, &old); dummy = SIGUSR2; //viddev->capture_method = METEOR_CAP_CONTINOUS; //viddev->capture_method = METEOR_CAP_SINGLE; if ((viddev->capture_method == METEOR_CAP_CONTINOUS) && (ioctl(dev_bktr, METEORSSIGNAL, &dummy) < 0)) { MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: METEORSSIGNAL"); viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0) { MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: METEORCAPTUR using single method " "Error capturing"); MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: METEORCAPTUR using single method " "Error capturing"); } } else { if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0) { viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0) { MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: METEORCAPTUR using single method " "Error capturing"); } } } if (viddev->capture_method == METEOR_CAP_CONTINOUS) MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: METEORCAPTUR METEOR_CAP_CONTINOUS"); else MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: METEORCAPTUR METEOR_CAP_SINGLE"); // settle , sleep(1) replaced SLEEP(1, 0); /* FIXME */ switch (viddev->v4l_fmt) { case VIDEO_PALETTE_YUV420P: viddev->v4l_bufsize = (width * height * 3) / 2; break; case VIDEO_PALETTE_YUV422: viddev->v4l_bufsize = (width * height * 2); break; case VIDEO_PALETTE_RGB24: viddev->v4l_bufsize = (width * height * 3); break; case VIDEO_PALETTE_GREY: viddev->v4l_bufsize = width * height; break; } MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: HUE [%d]", bktr_get_hue(dev_bktr, &dummy)); MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: SATURATION [%d]", bktr_get_saturation(dev_bktr, &dummy)); MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: BRIGHTNESS [%d]", bktr_get_brightness(dev_bktr, &dummy)); MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: CONTRAST [%d]", bktr_get_contrast(dev_bktr, &dummy)); return map; }
static bool gfx_ctx_drm_egl_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { static const EGLint egl_attribs_gl[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE, }; static const EGLint egl_attribs_gles[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE, }; #ifdef EGL_KHR_create_context static const EGLint egl_attribs_gles3[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_NONE, }; #endif static const EGLint egl_attribs_vg[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE, }; const EGLint *attrib_ptr; EGLint major, minor, n, egl_attribs[16], *attr; float refresh_mod; int i, ret = 0; struct sigaction sa = {{0}}; struct drm_fb *fb = NULL; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*) driver->video_context_data; if (!drm) return false; sa.sa_handler = sighandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); switch (g_api) { case GFX_CTX_OPENGL_API: attrib_ptr = egl_attribs_gl; break; case GFX_CTX_OPENGL_ES_API: #ifdef EGL_KHR_create_context if (g_major >= 3) attrib_ptr = egl_attribs_gles3; else #endif attrib_ptr = egl_attribs_gles; break; case GFX_CTX_OPENVG_API: attrib_ptr = egl_attribs_vg; break; default: attrib_ptr = NULL; } /* If we use black frame insertion, * we fake a 60 Hz monitor for 120 Hz one, etc, so try to match that. */ refresh_mod = settings->video.black_frame_insertion ? 0.5f : 1.0f; /* Find desired video mode, and use that. * If not fullscreen, we get desired windowed size, * which is not appropriate. */ if ((width == 0 && height == 0) || !fullscreen) drm->g_drm_mode = &drm->g_connector->modes[0]; else { /* Try to match settings->video.refresh_rate as closely as possible. * Lower resolutions tend to have multiple supported * refresh rates as well. */ float minimum_fps_diff = 0.0f; /* Find best match. */ for (i = 0; i < drm->g_connector->count_modes; i++) { float diff; if (width != drm->g_connector->modes[i].hdisplay || height != drm->g_connector->modes[i].vdisplay) continue; diff = fabsf(refresh_mod * drm->g_connector->modes[i].vrefresh - settings->video.refresh_rate); if (!drm->g_drm_mode || diff < minimum_fps_diff) { drm->g_drm_mode = &drm->g_connector->modes[i]; minimum_fps_diff = diff; } } } if (!drm->g_drm_mode) { RARCH_ERR("[KMS/EGL]: Did not find suitable video mode for %u x %u.\n", width, height); goto error; } drm->g_fb_width = drm->g_drm_mode->hdisplay; drm->g_fb_height = drm->g_drm_mode->vdisplay; /* Create GBM surface. */ drm->g_gbm_surface = gbm_surface_create( drm->g_gbm_dev, drm->g_fb_width, drm->g_fb_height, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!drm->g_gbm_surface) { RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n"); goto error; } drm->g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)drm->g_gbm_dev); if (!drm->g_egl_dpy) { RARCH_ERR("[KMS/EGL]: Couldn't get EGL display.\n"); goto error; } if (!eglInitialize(drm->g_egl_dpy, &major, &minor)) goto error; if (!eglChooseConfig(drm->g_egl_dpy, attrib_ptr, &drm->g_egl_config, 1, &n) || n != 1) goto error; attr = egl_fill_attribs(egl_attribs); drm->g_egl_ctx = eglCreateContext(drm->g_egl_dpy, drm->g_egl_config, EGL_NO_CONTEXT, attr != egl_attribs ? egl_attribs : NULL); if (drm->g_egl_ctx == EGL_NO_CONTEXT) goto error; if (drm->g_use_hw_ctx) { drm->g_egl_hw_ctx = eglCreateContext(drm->g_egl_dpy, drm->g_egl_config, drm->g_egl_ctx, attr != egl_attribs ? egl_attribs : NULL); RARCH_LOG("[KMS/EGL]: Created shared context: %p.\n", (void*)drm->g_egl_hw_ctx); if (drm->g_egl_hw_ctx == EGL_NO_CONTEXT) goto error; } drm->g_egl_surf = eglCreateWindowSurface(drm->g_egl_dpy, drm->g_egl_config, (EGLNativeWindowType)drm->g_gbm_surface, NULL); if (!drm->g_egl_surf) goto error; if (!eglMakeCurrent(drm->g_egl_dpy, drm->g_egl_surf, drm->g_egl_surf, drm->g_egl_ctx)) goto error; glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(drm->g_egl_dpy, drm->g_egl_surf); drm->g_bo = gbm_surface_lock_front_buffer(drm->g_gbm_surface); fb = drm_fb_get_from_bo(drm, drm->g_bo); ret = drmModeSetCrtc(drm->g_drm_fd, drm->g_crtc_id, fb->fb_id, 0, 0, &drm->g_connector_id, 1, drm->g_drm_mode); if (ret < 0) goto error; return true; error: gfx_ctx_drm_egl_destroy_resources(drm); if (drm) free(drm); return false; }
/****************************************************************************** * * * Function: daemon_start * * * * Purpose: init process as daemon * * * * Parameters: allow_root - allow root permission for application * * * * Author: Alexei Vladishev * * * * Comments: it doesn't allow running under 'root' if allow_root is zero * * * ******************************************************************************/ int daemon_start(int allow_root) { pid_t pid; struct passwd *pwd; struct sigaction phan; char user[7] = "zabbix"; /* running as root ? */ if (0 == allow_root && (0 == getuid() || 0 == getgid())) { pwd = getpwnam(user); if (NULL == pwd) { zbx_error("user %s does not exist", user); zbx_error("Cannot run as root!"); exit(FAIL); } if (-1 == setgid(pwd->pw_gid)) { zbx_error("cannot setgid to %s: %s", user, zbx_strerror(errno)); exit(FAIL); } #ifdef HAVE_FUNCTION_INITGROUPS if (-1 == initgroups(user, pwd->pw_gid)) { zbx_error("cannot initgroups to %s: %s", user, zbx_strerror(errno)); exit(FAIL); } #endif if (-1 == setuid(pwd->pw_uid)) { zbx_error("cannot setuid to %s: %s", user, zbx_strerror(errno)); exit(FAIL); } #ifdef HAVE_FUNCTION_SETEUID if (-1 == setegid(pwd->pw_gid) || -1 == seteuid(pwd->pw_uid)) { zbx_error("cannot setegid or seteuid to %s: %s", user, zbx_strerror(errno)); exit(FAIL); } #endif } if (0 != (pid = zbx_fork())) exit(0); setsid(); signal(SIGHUP, SIG_IGN); if (0 != (pid = zbx_fork())) exit(0); /* this is to eliminate warning: ignoring return value of chdir */ if (-1 == chdir("/")) assert(0); umask(0002); redirect_std(CONFIG_LOG_FILE); #ifdef HAVE_SYS_RESOURCE_SETPRIORITY if (0 != setpriority(PRIO_PROCESS, 0, 5)) zbx_error("Unable to set process priority to 5. Leaving default."); #endif /*------------------------------------------------*/ if (FAIL == create_pid_file(CONFIG_PID_FILE)) exit(FAIL); parent_pid = (int)getpid(); phan.sa_sigaction = child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = SA_SIGINFO; sigaction(SIGINT, &phan, NULL); sigaction(SIGQUIT, &phan, NULL); sigaction(SIGTERM, &phan, NULL); sigaction(SIGPIPE, &phan, NULL); sigaction(SIGILL, &phan, NULL); sigaction(SIGFPE, &phan, NULL); sigaction(SIGSEGV, &phan, NULL); sigaction(SIGBUS, &phan, NULL); sigaction(SIGALRM, &phan, NULL); sigaction(SIGUSR1, &phan, NULL); /* Set SIGCHLD now to avoid race conditions when a child process is created before */ /* sigaction() is called. To avoid problems when scripts exit in zbx_execute() and */ /* other cases, SIGCHLD is set to SIG_IGN in zbx_child_fork(). */ phan.sa_sigaction = parent_signal_handler; sigaction(SIGCHLD, &phan, NULL); zbx_setproctitle("main process"); return MAIN_ZABBIX_ENTRY(); }
bool w_start_listener(const char *path) { pthread_t thr; pthread_attr_t attr; pthread_mutexattr_t mattr; struct sigaction sa; sigset_t sigset; #ifdef HAVE_LIBGIMLI_H volatile struct gimli_heartbeat *hb = NULL; #endif struct timeval tv; void *ignored; int n_clients = 0; listener_thread = pthread_self(); pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&w_client_lock, &mattr); pthread_mutexattr_destroy(&mattr); #ifdef HAVE_LIBGIMLI_H hb = gimli_heartbeat_attach(); #endif #if defined(HAVE_KQUEUE) || defined(HAVE_FSEVENTS) { struct rlimit limit; # ifndef __OpenBSD__ int mib[2] = { CTL_KERN, # ifdef KERN_MAXFILESPERPROC KERN_MAXFILESPERPROC # else KERN_MAXFILES # endif }; # endif int maxperproc; getrlimit(RLIMIT_NOFILE, &limit); # ifndef __OpenBSD__ size_t len; len = sizeof(maxperproc); sysctl(mib, 2, &maxperproc, &len, NULL, 0); w_log(W_LOG_ERR, "file limit is %" PRIu64 " kern.maxfilesperproc=%i\n", limit.rlim_cur, maxperproc); # else maxperproc = limit.rlim_max; w_log(W_LOG_ERR, "openfiles-cur is %" PRIu64 " openfiles-max=%i\n", limit.rlim_cur, maxperproc); # endif if (limit.rlim_cur != RLIM_INFINITY && maxperproc > 0 && limit.rlim_cur < (rlim_t)maxperproc) { limit.rlim_cur = maxperproc; if (setrlimit(RLIMIT_NOFILE, &limit)) { w_log(W_LOG_ERR, "failed to raise limit to %" PRIu64 " (%s).\n", limit.rlim_cur, strerror(errno)); } else { w_log(W_LOG_ERR, "raised file limit to %" PRIu64 "\n", limit.rlim_cur); } } getrlimit(RLIMIT_NOFILE, &limit); #ifndef HAVE_FSEVENTS if (limit.rlim_cur < 10240) { w_log(W_LOG_ERR, "Your file descriptor limit is very low (%" PRIu64 "), " "please consult the watchman docs on raising the limits\n", limit.rlim_cur); } #endif } #endif proc_pid = (int)getpid(); if (gettimeofday(&tv, NULL) == -1) { w_log(W_LOG_ERR, "gettimeofday failed: %s\n", strerror(errno)); return false; } proc_start_time = (uint64_t)tv.tv_sec; signal(SIGPIPE, SIG_IGN); /* allow SIGUSR1 and SIGCHLD to wake up a blocked thread, without restarting * syscalls */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = wakeme; sa.sa_flags = 0; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); // Block SIGCHLD everywhere sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, NULL); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); listener_fd = get_listener_socket(path); if (listener_fd == -1) { return false; } w_set_cloexec(listener_fd); if (pthread_create(&reaper_thread, NULL, child_reaper, NULL)) { w_log(W_LOG_FATAL, "pthread_create(reaper): %s\n", strerror(errno)); return false; } if (!clients) { clients = w_ht_new(2, &client_hash_funcs); } w_state_load(); #ifdef HAVE_LIBGIMLI_H if (hb) { gimli_heartbeat_set(hb, GIMLI_HB_RUNNING); } else { w_setup_signal_handlers(); } #else w_setup_signal_handlers(); #endif w_set_nonblock(listener_fd); // Now run the dispatch while (!stopping) { int client_fd; struct watchman_client *client; struct pollfd pfd; int bufsize; #ifdef HAVE_LIBGIMLI_H if (hb) { gimli_heartbeat_set(hb, GIMLI_HB_RUNNING); } #endif pfd.events = POLLIN; pfd.fd = listener_fd; if (poll(&pfd, 1, 10000) < 1 || (pfd.revents & POLLIN) == 0) { continue; } #ifdef HAVE_ACCEPT4 client_fd = accept4(listener_fd, NULL, 0, SOCK_CLOEXEC); #else client_fd = accept(listener_fd, NULL, 0); #endif if (client_fd == -1) { continue; } w_set_cloexec(client_fd); bufsize = WATCHMAN_IO_BUF_SIZE; setsockopt(client_fd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); client = calloc(1, sizeof(*client)); client->fd = client_fd; w_log(W_LOG_DBG, "accepted client %p fd=%d\n", client, client_fd); if (!w_json_buffer_init(&client->reader)) { // FIXME: error handling } if (!w_json_buffer_init(&client->writer)) { // FIXME: error handling } if (pipe(client->ping)) { // FIXME: error handling } client->subscriptions = w_ht_new(2, &subscription_hash_funcs); w_set_cloexec(client->ping[0]); w_set_nonblock(client->ping[0]); w_set_cloexec(client->ping[1]); w_set_nonblock(client->ping[1]); pthread_mutex_lock(&w_client_lock); w_ht_set(clients, client->fd, w_ht_ptr_val(client)); pthread_mutex_unlock(&w_client_lock); // Start a thread for the client. // We used to use libevent for this, but we have // a low volume of concurrent clients and the json // parse/encode APIs are not easily used in a non-blocking // server architecture. if (pthread_create(&thr, &attr, client_thread, client)) { // It didn't work out, sorry! pthread_mutex_lock(&w_client_lock); w_ht_del(clients, client->fd); pthread_mutex_unlock(&w_client_lock); } } pthread_attr_destroy(&attr); /* close out some resources to persuade valgrind to run clean */ close(listener_fd); listener_fd = -1; // Wait for clients, waking any sleeping clients up in the process do { w_ht_iter_t iter; pthread_mutex_lock(&w_client_lock); n_clients = w_ht_size(clients); if (w_ht_first(clients, &iter)) do { struct watchman_client *client = w_ht_val_ptr(iter.value); ignore_result(write(client->ping[1], "a", 1)); } while (w_ht_next(clients, &iter)); pthread_mutex_unlock(&w_client_lock); w_log(W_LOG_ERR, "waiting for %d clients to terminate\n", n_clients); usleep(2000); } while (n_clients > 0); w_root_free_watched_roots(); pthread_join(reaper_thread, &ignored); cfg_shutdown(); return true; }
int mainloop(char **arg) { static uint64_t ovfl_count; /* static to avoid setjmp issue */ struct pollfd pollfds[1]; sigset_t bmask; int go[2], ready[2]; size_t pgsz; size_t map_size = 0; pid_t pid; int status, ret; int i; char buf; if (pfm_initialize() != PFM_SUCCESS) errx(1, "libpfm initialization failed\n"); pgsz = sysconf(_SC_PAGESIZE); map_size = (options.mmap_pages+1)*pgsz; /* * does allocate fds */ ret = perf_setup_list_events(options.events, &fds, &num_fds); if (ret || !num_fds) errx(1, "cannot setup event list"); memset(pollfds, 0, sizeof(pollfds)); ret = pipe(ready); if (ret) err(1, "cannot create pipe ready"); ret = pipe(go); if (ret) err(1, "cannot create pipe go"); /* * Create the child task */ if ((pid=fork()) == -1) err(1, "cannot fork process\n"); if (pid == 0) { close(ready[0]); close(go[1]); /* * let the parent know we exist */ close(ready[1]); if (read(go[0], &buf, 1) == -1) err(1, "unable to read go_pipe"); exit(child(arg)); } close(ready[1]); close(go[0]); if (read(ready[0], &buf, 1) == -1) err(1, "unable to read child_ready_pipe"); close(ready[0]); fds[0].fd = -1; if (!fds[0].hw.sample_period) errx(1, "need to set sampling period or freq on first event, use :period= or :freq="); for(i=0; i < num_fds; i++) { if (i == 0) { fds[i].hw.disabled = 1; fds[i].hw.enable_on_exec = 1; /* start immediately */ } else fds[i].hw.disabled = 0; if (options.opt_inherit) fds[i].hw.inherit = 1; if (fds[i].hw.sample_period) { /* * set notification threshold to be halfway through the buffer */ fds[i].hw.wakeup_watermark = (options.mmap_pages*pgsz) / 2; fds[i].hw.watermark = 1; fds[i].hw.sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_READ|PERF_SAMPLE_TIME|PERF_SAMPLE_PERIOD; /* * if we have more than one event, then record event identifier to help with parsing */ if (num_fds > 1) fds[i].hw.sample_type |= PERF_SAMPLE_IDENTIFIER; fprintf(options.output_file,"%s period=%"PRIu64" freq=%d\n", fds[i].name, fds[i].hw.sample_period, fds[i].hw.freq); fds[i].hw.read_format = PERF_FORMAT_SCALE; if (fds[i].hw.freq) fds[i].hw.sample_type |= PERF_SAMPLE_PERIOD; if (options.mem_mode) fds[i].hw.sample_type |= PERF_SAMPLE_WEIGHT | PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_ADDR; if (options.branch_mode) { fds[i].hw.sample_type |= PERF_SAMPLE_BRANCH_STACK; fds[i].hw.branch_sample_type = PERF_SAMPLE_BRANCH_ANY; } } /* * we are grouping the events, so there may be a limit */ fds[i].fd = perf_event_open(&fds[i].hw, pid, options.cpu, fds[0].fd, 0); if (fds[i].fd == -1) { if (fds[i].hw.precise_ip) err(1, "cannot attach event %s: precise mode may not be supported", fds[i].name); err(1, "cannot attach event %s", fds[i].name); } } /* * kernel adds the header page to the size of the mmapped region */ fds[0].buf = mmap(NULL, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fds[0].fd, 0); if (fds[0].buf == MAP_FAILED) err(1, "cannot mmap buffer"); /* does not include header page */ fds[0].pgmsk = (options.mmap_pages*pgsz)-1; /* * send samples for all events to first event's buffer */ for (i = 1; i < num_fds; i++) { if (!fds[i].hw.sample_period) continue; ret = ioctl(fds[i].fd, PERF_EVENT_IOC_SET_OUTPUT, fds[0].fd); if (ret) err(1, "cannot redirect sampling output"); } if (num_fds > 1 && fds[0].fd > -1) { for(i = 0; i < num_fds; i++) { /* * read the event identifier using ioctl * new method replaced the trick with PERF_FORMAT_GROUP + PERF_FORMAT_ID + read() */ ret = ioctl(fds[i].fd, PERF_EVENT_IOC_ID, &fds[i].id); if (ret == -1) err(1, "cannot read ID"); fprintf(options.output_file,"ID %"PRIu64" %s\n", fds[i].id, fds[i].name); } } pollfds[0].fd = fds[0].fd; pollfds[0].events = POLLIN; for(i=0; i < num_fds; i++) { ret = ioctl(fds[i].fd, PERF_EVENT_IOC_ENABLE, 0); if (ret) err(1, "cannot enable event %s\n", fds[i].name); } signal(SIGCHLD, cld_handler); close(go[1]); if (setjmp(jbuf) == 1) goto terminate_session; sigemptyset(&bmask); sigaddset(&bmask, SIGCHLD); /* * core loop */ for(;;) { ret = poll(pollfds, 1, -1); if (ret < 0 && errno == EINTR) break; ovfl_count++; ret = sigprocmask(SIG_SETMASK, &bmask, NULL); if (ret) err(1, "setmask"); process_smpl_buf(&fds[0]); ret = sigprocmask(SIG_UNBLOCK, &bmask, NULL); if (ret) err(1, "unblock"); } terminate_session: /* * cleanup child */ wait4(pid, &status, 0, NULL); for(i=0; i < num_fds; i++) close(fds[i].fd); /* check for partial event buffer */ process_smpl_buf(&fds[0]); munmap(fds[0].buf, map_size); perf_free_fds(fds, num_fds); fprintf(options.output_file, "%"PRIu64" samples collected in %"PRIu64" poll events, %"PRIu64" lost samples\n", collected_samples, ovfl_count, lost_samples); /* free libpfm resources cleanly */ pfm_terminate(); fclose(options.output_file); return 0; }
static void run_monitored(char *executable, int argc, char **argv) { int pid; const char *t = getenv("KLEE_REPLAY_TIMEOUT"); if (!t) t = "10000000"; monitored_timeout = atoi(t); if (monitored_timeout==0) { fprintf(stderr, "ERROR: invalid timeout (%s)\n", t); _exit(1); } /* Kill monitored process(es) on SIGINT and SIGTERM */ signal(SIGINT, int_handler); signal(SIGTERM, int_handler); signal(SIGALRM, timeout_handler); pid = fork(); if (pid < 0) { perror("fork"); _exit(66); } else if (pid == 0) { /* This process actually executes the target program. * * Create a new process group for pid, and the process tree it may spawn. We * do this, because later on we might want to kill pid _and_ all processes * spawned by it and its descendants. */ setpgrp(); if (!rootdir) { execv(executable, argv); perror("execv"); _exit(66); } fprintf(stderr, "rootdir: %s\n", rootdir); const char *msg; if ((msg = "chdir", chdir(rootdir) == 0) && (msg = "chroot", chroot(rootdir) == 0)) { msg = "execv"; executable = strip_root_dir(executable, rootdir); argv[0] = strip_root_dir(argv[0], rootdir); execv(executable, argv); } perror(msg); _exit(66); } else { /* Parent process which monitors the child. */ int res, status; time_t start = time(0); sigset_t masked; sigemptyset(&masked); sigaddset(&masked, SIGALRM); monitored_pid = pid; alarm(monitored_timeout); do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); if (res < 0) { perror("waitpid"); _exit(66); } /* Just in case, kill the process group of pid. Since we called setpgrp() for pid, this will not kill us, or any of our ancestors */ kill(-pid, SIGKILL); process_status(status, time(0) - start, 0); } }
int main(int argc, char *argv[]) { struct sigaction sa; int fd, events, fnum; const int NOTIFY_SIG = SIGRTMIN; char *p; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageError(argv[0], NULL); /* Establish handler for notification signal */ sa.sa_sigaction = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; /* So handler gets siginfo_t arg. */ if (sigaction(NOTIFY_SIG, &sa, NULL) == -1) errExit("sigaction"); for (fnum = 1; fnum < argc; fnum++) { p = strchr(argv[fnum], ':'); /* Look for optional ':' */ if (p == NULL) { /* Default is all events + multishot */ events = DN_ACCESS | DN_ATTRIB | DN_CREATE | DN_DELETE | DN_MODIFY | DN_RENAME | DN_MULTISHOT; } else { /* ':' present, parse event chars */ *p = '\0'; /* Terminates directory component */ events = 0; for (p++; *p != '\0'; p++) { switch (*p) { case 'a': events |= DN_ACCESS; break; case 'A': events |= DN_ATTRIB; break; case 'c': events |= DN_CREATE; break; case 'd': events |= DN_DELETE; break; case 'm': events |= DN_MODIFY; break; case 'r': events |= DN_RENAME; break; case 'M': events |= DN_MULTISHOT; break; default: usageError(argv[0], "Bad event character\n"); } } } /* Obtain a file descriptor for the directory to be monitored */ fd = open(argv[fnum], O_RDONLY); if (fd == -1) errExit("open"); printf("opened '%s' as file descriptor %d\n", argv[fnum], fd); /* Use alternate signal instead of SIGIO for dnotify events */ if (fcntl(fd, F_SETSIG, NOTIFY_SIG) == -1) errExit("fcntl - F_SETSIG"); /* Enable directory change notifications */ if (fcntl(fd, F_NOTIFY, events) == -1) errExit("fcntl-F_NOTIFY"); printf("events: %o\n", (unsigned int) events); } for (;;) pause(); /* Wait for events */ }
int main(int argc, char **argv) { /*Main program */ int cellNum; /*Cell entry number */ int rc; /*Return value from U_CellGetLocalTokens */ time_t current_time; /*Current time of day */ time_t tokenExpireTime; /*When token expires */ char *expireString; /*Char string of expiration time */ char UserName[MAXKTCNAMELEN * 2 + 2]; /*Printable user name */ char *cellName; struct ktc_principal clientName; /* service name for ticket */ struct ktc_token token; /* the token we're printing */ struct ktc_setTokenData *tokenSet; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); #endif /* has no args ... support for help flag */ if (argc > 1) { /* syntax from AFS Com Ref Man p9-39 */ printf("Usage: tokens [-help]\n"); fflush(stdout); exit(0); } printf("\nTokens held by the Cache Manager:\n\n"); cellNum = 0; current_time = time(0); while (1) { rc = ktc_ListTokensEx(cellNum, &cellNum, &cellName); if (rc) { /* only error is now end of list */ printf(" --End of list--\n"); break; } else { /* get the ticket info itself */ rc = ktc_GetTokenEx(cellName, &tokenSet); if (rc) { printf ("tokens: failed to get token info for cell %s (code %d)\n", cellName, rc); continue; } rc = token_extractRxkad(tokenSet, &token, NULL, &clientName); if (rc == 0) { tokenExpireTime = token.endTime; strcpy(UserName, clientName.name); if (clientName.instance[0] != 0) { strcat(UserName, "."); strcat(UserName, clientName.instance); } if (UserName[0] == 0) printf("rxkad Tokens"); else if (strncmp(UserName, "AFS ID", 6) == 0) { printf("User's (%s) rxkad tokens", UserName); } else if (strncmp(UserName, "Unix UID", 8) == 0) { printf("RxkadTokens"); } else printf("User %s's rxkad tokens", UserName); printf(" for %s ", cellName); if (tokenExpireTime <= current_time) printf("[>> Expired <<]\n"); else { expireString = ctime(&tokenExpireTime); expireString += 4; /*Move past the day of week */ expireString[12] = '\0'; printf("[Expires %s]\n", expireString); } } token_FreeSet(&tokenSet); } } exit(0); } /*Main program */
CVMBool solarisSyncInit(void) { struct sigaction sa; sa.sa_handler = sigfunc1; /* interrupt wait */ sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); /* * but we allow interrupt-wait to be interrupted by a * set-owner request */ sigaction(SIGUSR2, &sa, NULL); sigemptyset(&CVMtargetGlobals->sigusr2Mask); sigaddset(&CVMtargetGlobals->sigusr2Mask, SIGUSR2); #if defined(CVM_JVMPI) || defined(CVM_JVMTI) sa.sa_handler = sigquitHandler; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); /* * mask SIGQUIT, so set-owner cannot be interrupted by an * interrupt-wait request */ sigaddset(&sa.sa_mask, SIGQUIT); sigaction(SIGQUIT, &sa, NULL); #endif #ifdef CVM_ADV_MUTEX_SET_OWNER /* Sanity check to make sure raw copy of locked mutex is safe */ { POSIXMutex test1, test2; memset(&test1, 0, sizeof test1); memset(&test2, 0, sizeof test2); if (!POSIXmutexInit(&test1)) { return CVM_FALSE; } else { CVMBool ok; if (!POSIXmutexInit(&test2)) { POSIXmutexDestroy(&test1); return CVM_FALSE; } ok = POSIXmutexTryLock(&test2); if (!ok) { fprintf(stderr, "trylock failed\n"); POSIXmutexDestroy(&test1); POSIXmutexDestroy(&test2); return CVM_FALSE; } ok = POSIXmutexTryLock(&test1); if (!ok) { fprintf(stderr, "trylock failed\n"); POSIXmutexDestroy(&test1); POSIXmutexUnlock(&test2); POSIXmutexDestroy(&test2); return CVM_FALSE; } ok = (memcmp(&test1, &test2, sizeof test1) == 0); POSIXmutexUnlock(&test1); POSIXmutexDestroy(&test1); POSIXmutexUnlock(&test2); POSIXmutexDestroy(&test2); if (!ok) { fprintf(stderr, "locked mutexes not identical\n"); return CVM_FALSE; } } } #endif #ifdef CVM_JIT return solarisJITSyncInitArch(); #else return CVM_TRUE; #endif }
//初始化事件处理函数 static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle) { ngx_uint_t m, i; ngx_event_t *rev, *wev; ngx_listening_t *ls; ngx_connection_t *c, *next, *old; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; ngx_event_module_t *module; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) { //使用锁机制 ngx_use_accept_mutex = 1; //是否获得accept互斥锁 ngx_accept_mutex_held = 0; //获取锁失败后,等待下次执行的时间 ngx_accept_mutex_delay = ecf->accept_mutex_delay; } else { ngx_use_accept_mutex = 0; } #if (NGX_WIN32) /* * disable accept mutex on win32 as it may cause deadlock if * grabbed by a process which can't accept connections */ ngx_use_accept_mutex = 0; #endif //初始化accept请求队列(使用accept锁) ngx_queue_init(&ngx_posted_accept_events); ngx_queue_init(&ngx_posted_events); if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { return NGX_ERROR; } //初始化事件驱动模块 for (m = 0; cycle->modules[m]; m++) { /*循环事件驱动模块,跳过模块类型为非NGX_EVENT_MODULE类型的模块*/ //调用event/modules/*.c if (cycle->modules[m]->type != NGX_EVENT_MODULE) { continue; } //如果非当前使用的模块则跳过( ngx_event_core_init_conf 定义) if (cycle->modules[m]->ctx_index != ecf->use) { continue; } module = cycle->modules[m]->ctx; //初始化事件驱动 if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) { /* fatal */ exit(2); } break; } #if !(NGX_WIN32) if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { struct sigaction sa; struct itimerval itv; ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = ngx_timer_signal_handler; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigaction(SIGALRM) failed"); return NGX_ERROR; } itv.it_interval.tv_sec = ngx_timer_resolution / 1000; itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000; itv.it_value.tv_sec = ngx_timer_resolution / 1000; itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setitimer() failed"); } } if (ngx_event_flags & NGX_USE_FD_EVENT) { struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, cycle->log); if (cycle->files == NULL) { return NGX_ERROR; } } #else if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { ngx_log_error(NGX_LOG_WARN, cycle->log, 0, "the \"timer_resolution\" directive is not supported " "with the configured event method, ignored"); ngx_timer_resolution = 0; } #endif //创建connections数组,保存连接信息 cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log); if (cycle->connections == NULL) { return NGX_ERROR; } c = cycle->connections; //创建读事件数组 cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->read_events == NULL) { return NGX_ERROR; } rev = cycle->read_events; for (i = 0; i < cycle->connection_n; i++) { rev[i].closed = 1; rev[i].instance = 1; } //创建写事件数组 cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->write_events == NULL) { return NGX_ERROR; } wev = cycle->write_events; for (i = 0; i < cycle->connection_n; i++) { wev[i].closed = 1; } i = cycle->connection_n; next = NULL; do { i--; c[i].data = next; c[i].read = &cycle->read_events[i]; c[i].write = &cycle->write_events[i]; c[i].fd = (ngx_socket_t) -1; next = &c[i]; } while (i); //初始化完成后,free_connections指向 cycle->connections第一个元素 cycle->free_connections = next; //设置剩余连接数 cycle->free_connection_n = cycle->connection_n; /* for each listening socket */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { #if (NGX_HAVE_REUSEPORT) if (ls[i].reuseport && ls[i].worker != ngx_worker) { continue; } #endif c = ngx_get_connection(ls[i].fd, cycle->log); if (c == NULL) { return NGX_ERROR; } c->type = ls[i].type; c->log = &ls[i].log; c->listening = &ls[i]; ls[i].connection = c; rev = c->read; rev->log = c->log; rev->accept = 1; #if (NGX_HAVE_DEFERRED_ACCEPT) rev->deferred_accept = ls[i].deferred_accept; #endif if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { if (ls[i].previous) { /* * delete the old accept events that were bound to * the old cycle read events array */ old = ls[i].previous->connection; if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) { return NGX_ERROR; } old->fd = (ngx_socket_t) -1; } } #if (NGX_WIN32) if (ngx_event_flags & NGX_USE_IOCP_EVENT) { ngx_iocp_conf_t *iocpcf; rev->handler = ngx_event_acceptex; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { return NGX_ERROR; } ls[i].log.handler = ngx_acceptex_log_error; iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex) == NGX_ERROR) { return NGX_ERROR; } } else { rev->handler = ngx_event_accept; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } } #else //设置回调函数 rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept : ngx_event_recvmsg; if (ngx_use_accept_mutex #if (NGX_HAVE_REUSEPORT) && !ls[i].reuseport #endif ) { continue; } //添加事件 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } #endif } return NGX_OK; }
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ main() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { #ifdef _WITH_BURST_2 int cb2_ret; #endif int current_toggle, exit_status = TRANSFER_SUCCESS, j, fd, status, loops, rest, blocksize, *wmo_counter, wmo_counter_fd = -1; #ifdef WITH_ARCHIVE_COPY_INFO unsigned int archived_copied = 0; #endif off_t no_of_bytes; time_t connected, #ifdef _WITH_BURST_2 diff_time, #endif end_transfer_time_file, start_transfer_time_file = 0, last_update_time, now; #ifdef _OUTPUT_LOG clock_t end_time = 0, start_time = 0; struct tms tmsdummy; #endif char *p_file_name_buffer, *buffer, fullname[MAX_PATH_LENGTH + 1], file_path[MAX_PATH_LENGTH]; clock_t clktck; struct stat stat_buf; struct job *p_db; #ifdef SA_FULLDUMP struct sigaction sact; #endif CHECK_FOR_VERSION(argc, argv); #ifdef SA_FULLDUMP /* * When dumping core sure we do a FULL core dump! */ sact.sa_handler = SIG_DFL; sact.sa_flags = SA_FULLDUMP; sigemptyset(&sact.sa_mask); if (sigaction(SIGSEGV, &sact, NULL) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "sigaction() error : %s", strerror(errno)); exit(INCORRECT); } #endif /* Do some cleanups when we exit. */ if (atexit(sf_wmo_exit) != 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not register exit function : %s", strerror(errno)); exit(INCORRECT); } /* Initialise variables. */ local_file_counter = 0; files_to_send = init_sf(argc, argv, file_path, WMO_FLAG); p_db = &db; if ((clktck = sysconf(_SC_CLK_TCK)) <= 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not get clock ticks per second : %s", strerror(errno)); exit(INCORRECT); } if (fsa->trl_per_process > 0) { if (fsa->trl_per_process < fsa->block_size) { blocksize = fsa->trl_per_process; } else { blocksize = fsa->block_size; } } else { blocksize = fsa->block_size; } if ((signal(SIGINT, sig_kill) == SIG_ERR) || (signal(SIGQUIT, sig_exit) == SIG_ERR) || (signal(SIGTERM, SIG_IGN) == SIG_ERR) || (signal(SIGSEGV, sig_segv) == SIG_ERR) || (signal(SIGBUS, sig_bus) == SIG_ERR) || (signal(SIGHUP, SIG_IGN) == SIG_ERR) || (signal(SIGPIPE, SIG_IGN) == SIG_ERR)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "signal() error : %s", strerror(errno)); exit(INCORRECT); } /* Now determine the real hostname. */ if (db.toggle_host == YES) { if (fsa->host_toggle == HOST_ONE) { (void)strcpy(db.hostname, fsa->real_hostname[HOST_TWO - 1]); current_toggle = HOST_TWO; } else { (void)strcpy(db.hostname, fsa->real_hostname[HOST_ONE - 1]); current_toggle = HOST_ONE; } } else { (void)strcpy(db.hostname, fsa->real_hostname[(int)(fsa->host_toggle - 1)]); current_toggle = (int)fsa->host_toggle; } /* Connect to remote WMO-server. */ #ifdef FTP_CTRL_KEEP_ALIVE_INTERVAL if (fsa->protocol_options & AFD_TCP_KEEPALIVE) { timeout_flag = transfer_timeout - 5; if (timeout_flag < MIN_KEEP_ALIVE_INTERVAL) { timeout_flag = MIN_KEEP_ALIVE_INTERVAL; } } #else timeout_flag = OFF; #endif if ((status = wmo_connect(db.hostname, db.port, db.sndbuf_size)) != SUCCESS) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "WMO connection to <%s> at port %d failed (%d).", db.hostname, db.port, status); exit(eval_timeout(CONNECT_ERROR)); } else { if (fsa->debug > NORMAL_MODE) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "Connected to port %d.", db.port); } } connected = time(NULL); /* Inform FSA that we have finished connecting and */ /* will now start to transfer data. */ if (gsf_check_fsa(p_db) != NEITHER) { #ifdef LOCK_DEBUG lock_region_w(fsa_fd, db.lock_offset + LOCK_CON, __FILE__, __LINE__); #else lock_region_w(fsa_fd, db.lock_offset + LOCK_CON); #endif fsa->job_status[(int)db.job_no].connect_status = WMO_ACTIVE; fsa->job_status[(int)db.job_no].no_of_files = files_to_send; fsa->connections += 1; #ifdef LOCK_DEBUG unlock_region(fsa_fd, db.lock_offset + LOCK_CON, __FILE__, __LINE__); #else unlock_region(fsa_fd, db.lock_offset + LOCK_CON); #endif } /* Allocate buffer to read data from the source file. */ if ((buffer = malloc(blocksize + 1 + 4 /* For bulletin end. */)) == NULL) { system_log(ERROR_SIGN, __FILE__, __LINE__, "malloc() error : %s", strerror(errno)); exit(ALLOC_ERROR); } if (db.special_flag & WITH_SEQUENCE_NUMBER) { char counter_file_name[MAX_FILENAME_LENGTH]; (void)snprintf(counter_file_name, MAX_FILENAME_LENGTH, "/%s.%d", db.host_alias, db.port); if ((wmo_counter_fd = open_counter_file(counter_file_name, &wmo_counter)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to open counter file `%s'.", counter_file_name); } } #ifdef _WITH_BURST_2 do { if (burst_2_counter > 0) { if (fsa->debug > NORMAL_MODE) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "WMO Bursting."); } } #endif /* Send all files. */ p_file_name_buffer = file_name_buffer; p_file_size_buffer = file_size_buffer; last_update_time = time(NULL); local_file_size = 0; for (files_send = 0; files_send < files_to_send; files_send++) { (void)snprintf(fullname, MAX_PATH_LENGTH + 1, "%s/%s", file_path, p_file_name_buffer); if (*p_file_size_buffer > 0) { int end_length = 0, header_length = 0, length_type_indicator = 10; if (gsf_check_fsa(p_db) != NEITHER) { fsa->job_status[(int)db.job_no].file_size_in_use = *p_file_size_buffer; (void)strcpy(fsa->job_status[(int)db.job_no].file_name_in_use, p_file_name_buffer); } /* Open local file. */ #ifdef O_LARGEFILE if ((fd = open(fullname, O_RDONLY | O_LARGEFILE)) == -1) #else if ((fd = open(fullname, O_RDONLY)) == -1) #endif { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Failed to open local file `%s' : %s", fullname, strerror(errno)); wmo_quit(); exit(OPEN_LOCAL_ERROR); } if (fsa->debug > NORMAL_MODE) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "Open local file `%s'", fullname); } #ifdef _OUTPUT_LOG if (db.output_log == YES) { start_time = times(&tmsdummy); } #endif /* * When the contents does not contain a bulletin header * it must be stored in the file name. */ if (db.special_flag & FILE_NAME_IS_HEADER) { int space_count; char *ptr = p_file_name_buffer; buffer[length_type_indicator] = 1; /* SOH */ buffer[length_type_indicator + 1] = '\015'; /* CR */ buffer[length_type_indicator + 2] = '\015'; /* CR */ buffer[length_type_indicator + 3] = '\012'; /* LF */ header_length = 4; space_count = 0; if (wmo_counter_fd > 0) { if (next_counter(wmo_counter_fd, wmo_counter, MAX_WMO_COUNTER) < 0) { close_counter_file(wmo_counter_fd, &wmo_counter); wmo_counter_fd = -1; wmo_counter = NULL; system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to get next WMO counter."); } else { if (*wmo_counter < 10) { buffer[length_type_indicator + header_length] = '0'; buffer[length_type_indicator + header_length + 1] = '0'; buffer[length_type_indicator + header_length + 2] = *wmo_counter + '0'; } else if (*wmo_counter < 100) { buffer[length_type_indicator + header_length] = '0'; buffer[length_type_indicator + header_length + 1] = (*wmo_counter / 10) + '0'; buffer[length_type_indicator + header_length + 2] = (*wmo_counter % 10) + '0'; } else if (*wmo_counter < 1000) { buffer[length_type_indicator + header_length] = ((*wmo_counter / 100) % 10) + '0'; buffer[length_type_indicator + header_length + 1] = ((*wmo_counter / 10) % 10) + '0'; buffer[length_type_indicator + header_length + 2] = (*wmo_counter % 10) + '0'; } buffer[length_type_indicator + header_length + 3] = '\015'; /* CR */ buffer[length_type_indicator + header_length + 4] = '\015'; /* CR */ buffer[length_type_indicator + header_length + 5] = '\012'; /* LF */ header_length += 6; } } /* if (wmo_counter_fd > 0) */ for (;;) { while ((*ptr != '_') && (*ptr != '-') && (*ptr != ' ') && (*ptr != '\0') && (*ptr != '.') && (*ptr != ';')) { buffer[length_type_indicator + header_length] = *ptr; header_length++; ptr++; } if ((*ptr == '\0') || (*ptr == '.') || (*ptr == ';')) { break; } else { if (space_count == 2) { if ((isalpha((int)(*(ptr + 1)))) && (isalpha((int)(*(ptr + 2)))) && (isalpha((int)(*(ptr + 3))))) { buffer[length_type_indicator + header_length] = ' '; buffer[length_type_indicator + header_length + 1] = *(ptr + 1); buffer[length_type_indicator + header_length + 2] = *(ptr + 2); buffer[length_type_indicator + header_length + 3] = *(ptr + 3); header_length += 4; } break; } else { buffer[length_type_indicator + header_length] = ' '; header_length++; ptr++; space_count++; } } } /* for (;;) */ buffer[length_type_indicator + header_length] = '\015'; /* CR */ buffer[length_type_indicator + header_length + 1] = '\015'; /* CR */ buffer[length_type_indicator + header_length + 2] = '\012'; /* LF */ header_length += 3; end_length = 4; } /* Read (local) and write (remote) file. */ no_of_bytes = 0; loops = (length_type_indicator + header_length + *p_file_size_buffer) / blocksize; rest = (length_type_indicator + header_length + *p_file_size_buffer) % blocksize; if ((db.special_flag & FILE_NAME_IS_HEADER) && (rest == 0)) { loops--; rest = blocksize; } /* Write length and type indicator. */ (void)snprintf(buffer, 9, "%08lu", (unsigned long)(*p_file_size_buffer + header_length + end_length)); if (db.transfer_mode == 'I') { buffer[length_type_indicator - 2] = 'B'; buffer[length_type_indicator - 1] = 'I'; } else if (db.transfer_mode == 'A') { buffer[length_type_indicator - 2] = 'A'; buffer[length_type_indicator - 1] = 'N'; } else { buffer[length_type_indicator - 2] = 'F'; buffer[length_type_indicator - 1] = 'X'; } if (fsa->trl_per_process > 0) { init_limit_transfer_rate(); } if (fsa->protocol_options & TIMEOUT_TRANSFER) { start_transfer_time_file = time(NULL); } for (;;) { for (j = 0; j < loops; j++) { #ifdef _SIMULATE_SLOW_TRANSFER (void)sleep(_SIMULATE_SLOW_TRANSFER); #endif if ((status = read(fd, (buffer + length_type_indicator + header_length), (blocksize - length_type_indicator - header_length))) != (blocksize - length_type_indicator - header_length)) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Could not read() local file `%s' : %s", fullname, strerror(errno)); wmo_quit(); exit(READ_LOCAL_ERROR); } if ((status = wmo_write(buffer, blocksize)) != SUCCESS) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Failed to write block from file `%s' to remote port %d [%d].", p_file_name_buffer, db.port, status); wmo_quit(); exit(eval_timeout(WRITE_REMOTE_ERROR)); } if (fsa->trl_per_process > 0) { limit_transfer_rate(blocksize, fsa->trl_per_process, clktck); } no_of_bytes += blocksize; if (gsf_check_fsa(p_db) != NEITHER) { fsa->job_status[(int)db.job_no].file_size_in_use_done = no_of_bytes; fsa->job_status[(int)db.job_no].file_size_done += blocksize; fsa->job_status[(int)db.job_no].bytes_send += blocksize; if (fsa->protocol_options & TIMEOUT_TRANSFER) { end_transfer_time_file = time(NULL); if (end_transfer_time_file < start_transfer_time_file) { start_transfer_time_file = end_transfer_time_file; } else { if ((end_transfer_time_file - start_transfer_time_file) > transfer_timeout) { trans_log(INFO_SIGN, __FILE__, __LINE__, NULL, NULL, #if SIZEOF_TIME_T == 4 "Transfer timeout reached for `%s' after %ld seconds.", #else "Transfer timeout reached for `%s' after %lld seconds.", #endif fsa->job_status[(int)db.job_no].file_name_in_use, (pri_time_t)(end_transfer_time_file - start_transfer_time_file)); wmo_quit(); exitflag = 0; exit(STILL_FILES_TO_SEND); } } } } if (length_type_indicator > 0) { length_type_indicator = 0; header_length = 0; } } /* for (j = 0; j < loops; j++) */ if (rest > 0) { if ((status = read(fd, (buffer + length_type_indicator + header_length), (rest - length_type_indicator - header_length))) != (rest - length_type_indicator - header_length)) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Could not read() local file `%s' : %s", fullname, strerror(errno)); wmo_quit(); exit(READ_LOCAL_ERROR); } if (end_length == 4) { buffer[rest] = '\015'; buffer[rest + 1] = '\015'; buffer[rest + 2] = '\012'; buffer[rest + 3] = 3; /* ETX */ } if ((status = wmo_write(buffer, rest + end_length)) != SUCCESS) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Failed to write rest of file to remote port %d [%d].", p_file_name_buffer, db.port, status); wmo_quit(); exit(eval_timeout(WRITE_REMOTE_ERROR)); } if (fsa->trl_per_process > 0) { limit_transfer_rate(rest + end_length, fsa->trl_per_process, clktck); } no_of_bytes += rest + end_length; if (gsf_check_fsa(p_db) != NEITHER) { fsa->job_status[(int)db.job_no].file_size_in_use_done = no_of_bytes; fsa->job_status[(int)db.job_no].file_size_done += rest; fsa->job_status[(int)db.job_no].bytes_send += rest; } } /* * Since there are always some users sending files to the * AFD not in dot notation, lets check here if this is really * the EOF. * If not lets continue so long until we hopefully have reached * the EOF. * NOTE: This is NOT a fool proof way. There must be a better * way! */ if (fstat(fd, &stat_buf) == -1) { (void)rec(transfer_log_fd, DEBUG_SIGN, "Hmmm. Failed to stat() `%s' : %s (%s %d)\n", fullname, strerror(errno), __FILE__, __LINE__); break; } else { if (stat_buf.st_size > *p_file_size_buffer) { char sign[LOG_SIGN_LENGTH]; if (db.special_flag & SILENT_NOT_LOCKED_FILE) { (void)memcpy(sign, DEBUG_SIGN, LOG_SIGN_LENGTH); } else { (void)memcpy(sign, WARN_SIGN, LOG_SIGN_LENGTH); } loops = (stat_buf.st_size - *p_file_size_buffer) / blocksize; rest = (stat_buf.st_size - *p_file_size_buffer) % blocksize; *p_file_size_buffer = stat_buf.st_size; /* * Give a warning in the receive log, so some action * can be taken against the originator. */ receive_log(sign, __FILE__, __LINE__, 0L, db.id.job, "File `%s' for host %s was DEFINITELY send without any locking. #%x", p_file_name_buffer, fsa->host_dsp_name, db.id.job); } else { break; } } } /* for (;;) */ if (db.special_flag & WMO_CHECK_ACKNOWLEDGE) { int ret; if ((ret = wmo_check_reply()) == INCORRECT) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Failed to receive reply from port %d for file %s.", db.port, p_file_name_buffer); wmo_quit(); exit(eval_timeout(CHECK_REPLY_ERROR)); } else if (ret == NEGATIV_ACKNOWLEDGE) { trans_log(ERROR_SIGN, __FILE__, __LINE__, NULL, NULL, "Received negative acknowledge from remote port %d for file %s.", db.port, p_file_name_buffer); } } #ifdef _OUTPUT_LOG if (db.output_log == YES) { end_time = times(&tmsdummy); } #endif /* Close local file. */ if (close(fd) == -1) { (void)rec(transfer_log_fd, WARN_SIGN, "%-*s[%d]: Failed to close() local file %s : %s (%s %d)\n", MAX_HOSTNAME_LENGTH, tr_hostname, (int)db.job_no, p_file_name_buffer, strerror(errno), __FILE__, __LINE__); /* * Since we usually do not send more then 100 files and * sf_wmo() will exit(), there is no point in stopping * the transmission. */ } } else { trans_log(INFO_SIGN, __FILE__, __LINE__, NULL, NULL, "File `%s' is of zero length, ignoring.", p_file_name_buffer); } /* Update FSA, one file transmitted. */ if (gsf_check_fsa(p_db) != NEITHER) { fsa->job_status[(int)db.job_no].file_name_in_use[0] = '\0'; fsa->job_status[(int)db.job_no].no_of_files_done++; fsa->job_status[(int)db.job_no].file_size_in_use = 0; fsa->job_status[(int)db.job_no].file_size_in_use_done = 0; local_file_size += *p_file_size_buffer; local_file_counter += 1; now = time(NULL); if (now >= (last_update_time + LOCK_INTERVAL_TIME)) { last_update_time = now; update_tfc(local_file_counter, local_file_size, p_file_size_buffer, files_to_send, files_send, now); local_file_size = 0; local_file_counter = 0; } } #ifdef _WITH_TRANS_EXEC if (db.special_flag & TRANS_EXEC) { trans_exec(file_path, fullname, p_file_name_buffer, clktck); } #endif #ifdef _OUTPUT_LOG if (db.output_log == YES) { if (ol_fd == -2) { # ifdef WITHOUT_FIFO_RW_SUPPORT output_log_fd(&ol_fd, &ol_readfd, &db.output_log); # else output_log_fd(&ol_fd, &db.output_log); # endif } if ((ol_fd > -1) && (ol_data == NULL)) { output_log_ptrs(&ol_retries, &ol_job_number, &ol_data, /* Pointer to buffer. */ &ol_file_name, &ol_file_name_length, &ol_archive_name_length, &ol_file_size, &ol_unl, &ol_size, &ol_transfer_time, &ol_output_type, db.host_alias, (current_toggle - 1), WMO, &db.output_log); } } #endif /* Now archive file if necessary. */ if ((db.archive_time > 0) && (p_db->archive_dir[0] != FAILED_TO_CREATE_ARCHIVE_DIR)) { #ifdef WITH_ARCHIVE_COPY_INFO int ret; #endif /* * By telling the function archive_file() that this * is the first time to archive a file for this job * (in struct p_db) it does not always have to check * whether the directory has been created or not. And * we ensure that we do not create duplicate names * when adding db.archive_time to msg_name. */ #ifdef WITH_ARCHIVE_COPY_INFO if ((ret = archive_file(file_path, p_file_name_buffer, p_db)) < 0) #else if (archive_file(file_path, p_file_name_buffer, p_db) < 0) #endif { if (fsa->debug > NORMAL_MODE) { trans_db_log(ERROR_SIGN, __FILE__, __LINE__, NULL, "Failed to archive file `%s'", p_file_name_buffer); } /* * NOTE: We _MUST_ delete the file we just send, * else the file directory will run full! */ if (unlink(fullname) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not unlink() local file `%s' after sending it successfully : %s", fullname, strerror(errno)); } #ifdef _OUTPUT_LOG if (db.output_log == YES) { (void)memcpy(ol_file_name, db.p_unique_name, db.unl); (void)strcpy(ol_file_name + db.unl, p_file_name_buffer); *ol_file_name_length = (unsigned short)strlen(ol_file_name); ol_file_name[*ol_file_name_length] = SEPARATOR_CHAR; ol_file_name[*ol_file_name_length + 1] = '\0'; (*ol_file_name_length)++; *ol_file_size = *p_file_size_buffer; *ol_job_number = fsa->job_status[(int)db.job_no].job_id; *ol_retries = db.retries; *ol_unl = db.unl; *ol_transfer_time = end_time - start_time; *ol_archive_name_length = 0; *ol_output_type = OT_NORMAL_DELIVERED + '0'; ol_real_size = *ol_file_name_length + ol_size; if (write(ol_fd, ol_data, ol_real_size) != ol_real_size) { system_log(ERROR_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); } } #endif } else { if (fsa->debug > NORMAL_MODE) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "Archived file `%s'", p_file_name_buffer); } #ifdef WITH_ARCHIVE_COPY_INFO if (ret == DATA_COPIED) { archived_copied++; } #endif #ifdef _OUTPUT_LOG if (db.output_log == YES) { (void)memcpy(ol_file_name, db.p_unique_name, db.unl); (void)strcpy(ol_file_name + db.unl, p_file_name_buffer); *ol_file_name_length = (unsigned short)strlen(ol_file_name); ol_file_name[*ol_file_name_length] = SEPARATOR_CHAR; ol_file_name[*ol_file_name_length + 1] = '\0'; (*ol_file_name_length)++; (void)strcpy(&ol_file_name[*ol_file_name_length + 1], &db.archive_dir[db.archive_offset]); *ol_file_size = *p_file_size_buffer; *ol_job_number = fsa->job_status[(int)db.job_no].job_id; *ol_retries = db.retries; *ol_unl = db.unl; *ol_transfer_time = end_time - start_time; *ol_archive_name_length = (unsigned short)strlen(&ol_file_name[*ol_file_name_length + 1]); *ol_output_type = OT_NORMAL_DELIVERED + '0'; ol_real_size = *ol_file_name_length + *ol_archive_name_length + 1 + ol_size; if (write(ol_fd, ol_data, ol_real_size) != ol_real_size) { system_log(ERROR_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); } } #endif } } else { #ifdef WITH_UNLINK_DELAY int unlink_loops = 0; try_again_unlink: #endif /* Delete the file we just have send. */ if (unlink(fullname) == -1) { #ifdef WITH_UNLINK_DELAY if ((errno == EBUSY) && (unlink_loops < 20)) { (void)my_usleep(100000L); unlink_loops++; goto try_again_unlink; } #endif system_log(ERROR_SIGN, __FILE__, __LINE__, "Could not unlink() local file %s after sending it successfully : %s", fullname, strerror(errno)); } #ifdef _OUTPUT_LOG if (db.output_log == YES) { (void)memcpy(ol_file_name, db.p_unique_name, db.unl); (void)strcpy(ol_file_name + db.unl, p_file_name_buffer); *ol_file_name_length = (unsigned short)strlen(ol_file_name); ol_file_name[*ol_file_name_length] = SEPARATOR_CHAR; ol_file_name[*ol_file_name_length + 1] = '\0'; (*ol_file_name_length)++; *ol_file_size = *p_file_size_buffer; *ol_job_number = fsa->job_status[(int)db.job_no].job_id; *ol_retries = db.retries; *ol_unl = db.unl; *ol_transfer_time = end_time - start_time; *ol_archive_name_length = 0; *ol_output_type = OT_NORMAL_DELIVERED + '0'; ol_real_size = *ol_file_name_length + ol_size; if (write(ol_fd, ol_data, ol_real_size) != ol_real_size) { system_log(ERROR_SIGN, __FILE__, __LINE__, "write() error : %s", strerror(errno)); } } #endif } /* * After each successful transfer set error * counter to zero, so that other jobs can be * started. */ if (gsf_check_fsa(p_db) != NEITHER) { if ((*p_file_size_buffer > 0) && (fsa->error_counter > 0)) { int fd, #ifdef WITHOUT_FIFO_RW_SUPPORT readfd, #endif j; char fd_wake_up_fifo[MAX_PATH_LENGTH]; #ifdef LOCK_DEBUG lock_region_w(fsa_fd, db.lock_offset + LOCK_EC, __FILE__, __LINE__); #else lock_region_w(fsa_fd, db.lock_offset + LOCK_EC); #endif fsa->error_counter = 0; /* * Wake up FD! */ (void)snprintf(fd_wake_up_fifo, MAX_PATH_LENGTH, "%s%s%s", p_work_dir, FIFO_DIR, FD_WAKE_UP_FIFO); #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(fd_wake_up_fifo, &readfd, &fd) == -1) #else if ((fd = open(fd_wake_up_fifo, O_RDWR)) == -1) #endif { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to open() FIFO %s : %s", fd_wake_up_fifo, strerror(errno)); } else { if (write(fd, "", 1) != 1) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to write() to FIFO %s : %s", fd_wake_up_fifo, strerror(errno)); } #ifdef WITHOUT_FIFO_RW_SUPPORT if (close(readfd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s (read) : %s", fd_wake_up_fifo, strerror(errno)); } #endif if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", fd_wake_up_fifo, strerror(errno)); } } /* * Remove the error condition (NOT_WORKING) from all jobs * of this host. */ for (j = 0; j < fsa->allowed_transfers; j++) { if ((j != db.job_no) && (fsa->job_status[j].connect_status == NOT_WORKING)) { fsa->job_status[j].connect_status = DISCONNECT; } } fsa->error_history[0] = 0; fsa->error_history[1] = 0; #ifdef LOCK_DEBUG unlock_region(fsa_fd, db.lock_offset + LOCK_EC, __FILE__, __LINE__); #else unlock_region(fsa_fd, db.lock_offset + LOCK_EC); #endif #ifdef LOCK_DEBUG lock_region_w(fsa_fd, db.lock_offset + LOCK_HS, __FILE__, __LINE__); #else lock_region_w(fsa_fd, db.lock_offset + LOCK_HS); #endif now = time(NULL); if (now > fsa->end_event_handle) { fsa->host_status &= ~(EVENT_STATUS_FLAGS | AUTO_PAUSE_QUEUE_STAT); if (fsa->end_event_handle > 0L) { fsa->end_event_handle = 0L; } if (fsa->start_event_handle > 0L) { fsa->start_event_handle = 0L; } } else { fsa->host_status &= ~(EVENT_STATUS_STATIC_FLAGS | AUTO_PAUSE_QUEUE_STAT); } #ifdef LOCK_DEBUG unlock_region(fsa_fd, db.lock_offset + LOCK_HS, __FILE__, __LINE__); #else unlock_region(fsa_fd, db.lock_offset + LOCK_HS); #endif /* * Since we have successfully transmitted a file, no need to * have the queue stopped anymore. */ if (fsa->host_status & AUTO_PAUSE_QUEUE_STAT) { char sign[LOG_SIGN_LENGTH]; error_action(fsa->host_alias, "stop", HOST_ERROR_ACTION); event_log(0L, EC_HOST, ET_EXT, EA_ERROR_END, "%s", fsa->host_alias); if ((fsa->host_status & HOST_ERROR_OFFLINE_STATIC) || (fsa->host_status & HOST_ERROR_OFFLINE) || (fsa->host_status & HOST_ERROR_OFFLINE_T)) { (void)memcpy(sign, OFFLINE_SIGN, LOG_SIGN_LENGTH); } else { (void)memcpy(sign, INFO_SIGN, LOG_SIGN_LENGTH); } trans_log(sign, __FILE__, __LINE__, NULL, NULL, "Starting input queue that was stopped by init_afd."); event_log(0L, EC_HOST, ET_AUTO, EA_START_QUEUE, "%s", fsa->host_alias); } } /* if (fsa->error_counter > 0) */ #ifdef WITH_ERROR_QUEUE if (fsa->host_status & ERROR_QUEUE_SET) { remove_from_error_queue(db.id.job, fsa, db.fsa_pos, fsa_fd); } #endif if (fsa->host_status & HOST_ACTION_SUCCESS) { error_action(fsa->host_alias, "start", HOST_SUCCESS_ACTION); } } p_file_name_buffer += MAX_FILENAME_LENGTH; p_file_size_buffer++; } /* for (files_send = 0; files_send < files_to_send; files_send++) */ #ifdef WITH_ARCHIVE_COPY_INFO if (archived_copied > 0) { trans_log(DEBUG_SIGN, __FILE__, __LINE__, NULL, NULL, "Copied %u files to archive.", archived_copied); archived_copied = 0; } #endif if (local_file_counter) { if (gsf_check_fsa(p_db) != NEITHER) { update_tfc(local_file_counter, local_file_size, p_file_size_buffer, files_to_send, files_send, time(NULL)); local_file_size = 0; local_file_counter = 0; } } /* * Remove file directory, but only when all files have * been transmitted. */ if ((files_to_send == files_send) || (files_to_send < 1)) { if (rmdir(file_path) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to remove directory %s : %s", file_path, strerror(errno)); } } else { system_log(WARN_SIGN, __FILE__, __LINE__, "There are still %d files for %s. Will NOT remove this job!", files_to_send - files_send, file_path); exit_status = STILL_FILES_TO_SEND; } #ifdef _WITH_BURST_2 burst_2_counter++; diff_time = time(NULL) - connected; if (((fsa->protocol_options & KEEP_CONNECTED_DISCONNECT) && (db.keep_connected > 0) && (diff_time > db.keep_connected)) || ((db.disconnect > 0) && (diff_time > db.disconnect))) { cb2_ret = NO; break; } } while ((cb2_ret = check_burst_sf(file_path, &files_to_send, 0, # ifdef _WITH_INTERRUPT_JOB 0, # endif # ifdef _OUTPUT_LOG &ol_fd, # endif # ifndef AFDBENCH_CONFIG NULL, # endif NULL)) == YES); burst_2_counter--; if (cb2_ret == NEITHER) { exit_status = STILL_FILES_TO_SEND; } #endif /* _WITH_BURST_2 */ free(buffer); /* Disconnect from remote port. */ wmo_quit(); if ((fsa != NULL) && (fsa->debug > NORMAL_MODE)) { trans_db_log(INFO_SIGN, __FILE__, __LINE__, NULL, "Disconnected from port %d.", db.port); } if (wmo_counter_fd > 0) { close_counter_file(wmo_counter_fd, &wmo_counter); } exitflag = 0; exit(exit_status); }
int main (int argc, char * const * argv) { static int tcp_flag = 0; while (1) { static struct option long_options[] = { { "tcp", no_argument, &tcp_flag, 1 }, { "help", no_argument, 0, 0 }, { 0,0,0,0 } // This is a filler for -1 }; int c; int option_index = -1; c = getopt_long(argc, argv, "h", long_options, &option_index); if (c == -1) break; // no more option // treat long parameter first if (option_index == -1) { switch (c) { case '?': case 'h': usage(argv[0]); return 0; break; } } else { switch (option_index) { case 1: usage(argv[0]); return 0; break; } } } // make stdout unbuffered setbuf(stdout, NULL); log_error("BTdaemon started\n"); // handle CTRL-c signal(SIGINT, daemon_sigint_handler); // handle SIGTERM - suggested for launchd signal(SIGTERM, daemon_sigint_handler); // handle SIGPIPE struct sigaction act; act.sa_handler = SIG_IGN; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction (SIGPIPE, &act, NULL); bt_control_t * control = NULL; #ifdef HAVE_TRANSPORT_H4 config.device_name = UART_DEVICE; config.baudrate_init = UART_SPEED; config.baudrate_main = 0; config.flowcontrol = 1; #if defined(USE_BLUETOOL) && defined(USE_POWERMANAGEMENT) if (bt_control_iphone_power_management_supported()) { // use default (max) UART baudrate over netraph interface config.baudrate_init = 0; transport = hci_transport_h4_iphone_instance(); } else { transport = hci_transport_h4_instance(); } #else transport = hci_transport_h4_instance(); #endif #endif #ifdef HAVE_TRANSPORT_USB transport = hci_transport_usb_instance(); #endif #ifdef USE_BLUETOOL control = &bt_control_iphone; #endif #if defined(USE_BLUETOOL) && defined(USE_POWERMANAGEMENT) if (bt_control_iphone_power_management_supported()) { hci_transport_h4_iphone_set_enforce_wake_device("/dev/btwake"); } #endif #ifdef USE_SPRINGBOARD bluetooth_status_handler = platform_iphone_status_handler; platform_iphone_register_window_manager_restart(update_ui_status); platform_iphone_register_preferences_changed(preferences_changed_callback); #endif #ifdef REMOTE_DEVICE_DB remote_device_db = &REMOTE_DEVICE_DB; #endif run_loop_init(RUN_LOOP_POSIX); // init power management notifications if (control && control->register_for_power_notifications) { control->register_for_power_notifications(power_notification_callback); } // logging loggingEnabled = 0; int newLoggingEnabled = 1; #ifdef USE_BLUETOOL // iPhone has toggle in Preferences.app newLoggingEnabled = platform_iphone_logging_enabled(); #endif daemon_set_logging_enabled(newLoggingEnabled); // init HCI hci_init(transport, &config, control, remote_device_db); // init L2CAP l2cap_init(); l2cap_register_packet_handler(daemon_packet_handler); timeout.process = daemon_no_connections_timeout; #ifdef HAVE_RFCOMM log_info("config.h: HAVE_RFCOMM\n"); rfcomm_init(); rfcomm_register_packet_handler(daemon_packet_handler); #endif #ifdef HAVE_SDP sdp_init(); sdp_register_packet_handler(daemon_packet_handler); #endif #ifdef USE_LAUNCHD socket_connection_create_launchd(); #else // create server if (tcp_flag) { socket_connection_create_tcp(BTSTACK_PORT); } else { socket_connection_create_unix(BTSTACK_UNIX); } #endif socket_connection_register_packet_callback(daemon_client_handler); #ifdef USE_BLUETOOL // notify daemons notify_post("ch.ringwald.btstack.started"); // spawn thread to have BTstack run loop on new thread, while main thread is used to keep CFRunLoop pthread_t run_loop; pthread_create(&run_loop, NULL, &run_loop_thread, NULL); // needed to receive notifications CFRunLoopRun(); #endif // go! run_loop_execute(); return 0; }
bool AppInit2(int argc, char* argv[]) { #ifdef _MSC_VER // Turn off microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, ctrl-c _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifndef __WXMSW__ umask(077); #endif #ifndef __WXMSW__ // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); #endif // // Parameters // ParseParameters(argc, argv); if (mapArgs.count("-datadir")) { filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]); strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir)); } ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir if (mapArgs.count("-?") || mapArgs.count("--help")) { string beta = VERSION_IS_BETA ? _(" beta") : ""; string strUsage = string() + _("Bitcoin version") + " " + FormatVersion(VERSION) + pszSubVer + beta + "\n\n" + _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" + " bitcoin [options] \t " + "\n" + " bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") + " bitcoin [options] help \t\t " + _("List commands\n") + " bitcoin [options] help <command> \t\t " + _("Get help for a command\n") + _("Options:\n") + " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") + " -gen \t\t " + _("Generate coins\n") + " -gen=0 \t\t " + _("Don't generate coins\n") + " -min \t\t " + _("Start minimized\n") + " -datadir=<dir> \t\t " + _("Specify data directory\n") + " -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") + " -addnode=<ip> \t " + _("Add a node to connect to\n") + " -connect=<ip> \t\t " + _("Connect only to the specified node\n") + " -nolisten \t " + _("Don't accept connections from outside\n") + " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") + #ifdef GUI " -server \t\t " + _("Accept command line and JSON-RPC commands\n") + " -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") + #endif " -testnet \t\t " + _("Use the test network\n") + " -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") + " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") + " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") + " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") + " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") + " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") + " -rescan \t " + _("Rescan the block chain for missing wallet transactions\n"); #ifdef USE_SSL strUsage += string() + _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") + " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") + " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") + " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") + " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n"); #endif strUsage += string() + " -? \t\t " + _("This help message\n"); #if defined(__WXMSW__) && defined(GUI) // Tabs make the columns line up in the message box wxMessageBox(strUsage, "Bitcoin", wxOK); #else // Remove tabs strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end()); fprintf(stderr, "%s", strUsage.c_str()); #endif return false; } fDebug = GetBoolArg("-debug"); fDaemon = GetBoolArg("-daemon"); if (fDaemon) fServer = true; else fServer = GetBoolArg("-server"); /* force fServer and fDaemon when running without GUI */ #ifndef GUI fServer = true; fDaemon = true; #endif fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fTestNet = GetBoolArg("-testnet"); fNoListen = GetBoolArg("-nolisten"); fLogTimestamps = GetBoolArg("-logtimestamps"); for (int i = 1; i < argc; i++) if (!IsSwitchChar(argv[i][0])) fCommandLine = true; if (fCommandLine) { int ret = CommandLineRPC(argc, argv); exit(ret); } #ifndef GUI if (fDaemon) { // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) return true; pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("Bitcoin version %s%s%s\n", FormatVersion(VERSION).c_str(), pszSubVer, VERSION_IS_BETA ? _(" beta") : ""); #ifdef GUI printf("OS version %s\n", ((string)wxGetOsDescription()).c_str()); printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str()); printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str()); #endif printf("Default data directory %s\n", GetDefaultDataDir().c_str()); if (GetBoolArg("-loadblockindextest")) { CTxDB txdb("r"); txdb.LoadBlockIndex(); PrintBlockTree(); return false; } // // Limit to single instance per user // Required to protect the database files if we're going to keep deleting log.* // #if defined(__WXMSW__) && defined(GUI) // wxSingleInstanceChecker doesn't work on Linux wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); for (int i = 0; i < strMutexName.size(); i++) if (!isalnum(strMutexName[i])) strMutexName[i] = '.'; wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); if (psingleinstancechecker->IsAnotherRunning()) { printf("Existing instance found\n"); unsigned int nStart = GetTime(); loop { // Show the previous instance and exit HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); if (hwndPrev) { if (IsIconic(hwndPrev)) ShowWindow(hwndPrev, SW_RESTORE); SetForegroundWindow(hwndPrev); return false; } if (GetTime() > nStart + 60) return false; // Resume this instance if the other exits delete psingleinstancechecker; Sleep(1000); psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); if (!psingleinstancechecker->IsAnotherRunning()) break; } }
//---------------------------------------------------------------------- void Demonizer::setup() throw(DemonizerException) { sysLogger.setName(this->getName()); sysLogger.log("Configuring daemon..."); sysLogger.log(std::string("current PID = ") + Logger::itos(getpid())); pid_t pid; struct rlimit limits; struct sigaction sa; umask(0); if (getrlimit(RLIMIT_NOFILE, &limits) < 0) { throw DemonizerException("can`t get RLIMIT_NOFILE"); } //fork process and disconnect it from parent if ((pid = fork()) < 0) { throw DemonizerException("fork error"); } else if (0 != pid) { sysLogger.log(std::string("PID1 = ") + Logger::itos(pid)); exit(0);//stop parent process } //create seance if ((setsid()) == (pid_t) -1) { throw DemonizerException("setsig error"); } //ignoring sighup sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) { throw DemonizerException("can`t ignore SIGHUP"); } //fork again if ((pid = fork()) < 0) { throw DemonizerException("fork error"); } else if (0 != pid) { sysLogger.log(std::string("PID2 = ") + Logger::itos(pid)); exit(0); } //chdir to / if (chdir("/") < 0) { throw DemonizerException("can`t chdir() to /"); } //close all resources if (limits.rlim_max == RLIM_INFINITY) limits.rlim_max = 1024; u_int32_t idx; for (idx = 0; idx < limits.rlim_max; ++idx) { close(idx); } //reopen stdout to /dev/null and another strems to it int fd0 = open("/dev/null", O_RDWR); int fd1 = dup(0); int fd2 = dup(0); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { /* throw DemonizerException("bad file descriptors: " + Logger::itos(fd0) + " " + Logger::itos(fd1) + " " + Logger::itos(fd2)); */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } sysLogger.log("Prepare to be daemon ok"); //check the running - and save new! pid if (SystemTools::checkRunningAndSavePID(this->getName())) { sysLogger.log("Daemon is already running"); throw DemonizerException("Error. Daemon is already running"); } //set handler to signal //signal(SIGTERM, signal_handler); sysLogger.log("Daemonize done"); }
int main(int argc, char *argv[]) #endif { gboolean opt_force_online = FALSE; gboolean opt_help = FALSE; gboolean opt_login = FALSE; gboolean opt_nologin = FALSE; gboolean opt_version = FALSE; gboolean opt_si = TRUE; /* Check for single instance? */ char *opt_config_dir_arg = NULL; char *opt_login_arg = NULL; char *opt_session_arg = NULL; char *search_path; GList *accounts; #ifdef HAVE_SIGNAL_H int sig_indx; /* for setting up signal catching */ sigset_t sigset; RETSIGTYPE (*prev_sig_disp)(int); char errmsg[BUFSIZ]; GIOChannel *signal_channel; GIOStatus signal_status; guint signal_channel_watcher; #ifndef DEBUG char *segfault_message_tmp; #endif GError *error; #endif int opt; gboolean gui_check; gboolean debug_enabled; gboolean migration_failed = FALSE; GList *active_accounts; struct stat st; struct option long_options[] = { {"config", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"force-online", no_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h'}, {"login", optional_argument, NULL, 'l'}, {"multiple", no_argument, NULL, 'm'}, {"nologin", no_argument, NULL, 'n'}, {"session", required_argument, NULL, 's'}, {"version", no_argument, NULL, 'v'}, {"display", required_argument, NULL, 'D'}, {"sync", no_argument, NULL, 'S'}, {0, 0, 0, 0} }; #ifdef DEBUG debug_enabled = TRUE; #else debug_enabled = FALSE; #endif /* Initialize GThread before calling any Glib or GTK+ functions. */ g_thread_init(NULL); g_set_prgname("Carrier"); #ifdef ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); bind_textdomain_codeset(PACKAGE, "UTF-8"); textdomain(PACKAGE); #endif #ifdef HAVE_SETLOCALE /* Locale initialization is not complete here. See gtk_init_check() */ setlocale(LC_ALL, ""); #endif #ifdef HAVE_SIGNAL_H #ifndef DEBUG /* We translate this here in case the crash breaks gettext. */ segfault_message_tmp = g_strdup_printf(_( "%s %s has segfaulted and attempted to dump a core file.\n" "This is a bug in the software and has happened through\n" "no fault of your own.\n\n" "If you can reproduce the crash, please notify the developers\n" "by reporting a bug at:\n" "%ssimpleticket/\n\n" "Please make sure to specify what you were doing at the time\n" "and post the backtrace from the core file. If you do not know\n" "how to get the backtrace, please read the instructions at\n" "%swiki/GetABacktrace\n"), PIDGIN_NAME, DISPLAY_VERSION, PURPLE_DEVEL_WEBSITE, PURPLE_DEVEL_WEBSITE ); /* we have to convert the message (UTF-8 to console charset) early because after a segmentation fault it's not a good practice to allocate memory */ error = NULL; segfault_message = g_locale_from_utf8(segfault_message_tmp, -1, NULL, NULL, &error); if (segfault_message != NULL) { g_free(segfault_message_tmp); } else { /* use 'segfault_message_tmp' (UTF-8) as a fallback */ g_warning("%s\n", error->message); g_error_free(error); segfault_message = segfault_message_tmp; } #else /* Don't mark this for translation. */ segfault_message = g_strdup( "Hi, user. We need to talk.\n" "I think something's gone wrong here. It's probably my fault.\n" "No, really, it's not you... it's me... no no no, I think we get along well\n" "it's just that.... well, I want to see other people. I... what?!? NO! I \n" "haven't been cheating on you!! How many times do you want me to tell you?! And\n" "for the last time, it's just a rash!\n" ); #endif /* * Create a socket pair for receiving unix signals from a signal * handler. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, signal_sockets) < 0) { perror("Failed to create sockets for GLib signal handling"); exit(1); } signal_channel = g_io_channel_unix_new(signal_sockets[1]); /* * Set the channel encoding to raw binary instead of the default of * UTF-8, because we'll be sending integers across instead of strings. */ error = NULL; signal_status = g_io_channel_set_encoding(signal_channel, NULL, &error); if (signal_status != G_IO_STATUS_NORMAL) { fprintf(stderr, "Failed to set the signal channel to raw " "binary: %s", error->message); exit(1); } signal_channel_watcher = g_io_add_watch(signal_channel, G_IO_IN, mainloop_sighandler, NULL); g_io_channel_unref(signal_channel); /* Let's not violate any PLA's!!!! */ /* jseymour: whatever the fsck that means */ /* Robot101: for some reason things like gdm like to block * * useful signals like SIGCHLD, so we unblock all the ones we * * declare a handler for. thanks JSeymour and Vann. */ if (sigemptyset(&sigset)) { snprintf(errmsg, sizeof(errmsg), "Warning: couldn't initialise empty signal set"); perror(errmsg); } for(sig_indx = 0; catch_sig_list[sig_indx] != -1; ++sig_indx) { if((prev_sig_disp = signal(catch_sig_list[sig_indx], sighandler)) == SIG_ERR) { snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d for catching", catch_sig_list[sig_indx]); perror(errmsg); } if(sigaddset(&sigset, catch_sig_list[sig_indx])) { snprintf(errmsg, sizeof(errmsg), "Warning: couldn't include signal %d for unblocking", catch_sig_list[sig_indx]); perror(errmsg); } } for(sig_indx = 0; ignore_sig_list[sig_indx] != -1; ++sig_indx) { if((prev_sig_disp = signal(ignore_sig_list[sig_indx], SIG_IGN)) == SIG_ERR) { snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d to ignore", ignore_sig_list[sig_indx]); perror(errmsg); } } if (sigprocmask(SIG_UNBLOCK, &sigset, NULL)) { snprintf(errmsg, sizeof(errmsg), "Warning: couldn't unblock signals"); perror(errmsg); } #endif /* scan command-line options */ opterr = 1; while ((opt = getopt_long(argc, argv, #ifndef _WIN32 "c:dfhmnl::s:v", #else "c:dfhmnl::v", #endif long_options, NULL)) != -1) { switch (opt) { case 'c': /* config dir */ g_free(opt_config_dir_arg); opt_config_dir_arg = g_strdup(optarg); break; case 'd': /* debug */ debug_enabled = TRUE; break; case 'f': /* force-online */ opt_force_online = TRUE; break; case 'h': /* help */ opt_help = TRUE; break; case 'n': /* no autologin */ opt_nologin = TRUE; break; case 'l': /* login, option username */ opt_login = TRUE; g_free(opt_login_arg); if (optarg != NULL) opt_login_arg = g_strdup(optarg); break; case 's': /* use existing session ID */ g_free(opt_session_arg); opt_session_arg = g_strdup(optarg); break; case 'v': /* version */ opt_version = TRUE; break; case 'm': /* do not ensure single instance. */ opt_si = FALSE; break; case 'D': /* --display */ case 'S': /* --sync */ /* handled by gtk_init_check below */ break; case '?': /* show terse help */ default: show_usage(argv[0], TRUE); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 0; break; } } /* show help message */ if (opt_help) { show_usage(argv[0], FALSE); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 0; } /* show version message */ if (opt_version) { printf("%s %s (libpurple %s)\n", PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version()); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 0; } /* set a user-specified config directory */ if (opt_config_dir_arg != NULL) { purple_util_set_user_dir(opt_config_dir_arg); } /* * We're done piddling around with command line arguments. * Fire up this baby. */ purple_debug_set_enabled(debug_enabled); /* If we're using a custom configuration directory, we * do NOT want to migrate, or weird things will happen. */ if (opt_config_dir_arg == NULL) { if (!purple_core_migrate()) { migration_failed = TRUE; } } search_path = g_build_filename(purple_user_dir(), "gtkrc-2.0", NULL); gtk_rc_add_default_file(search_path); g_free(search_path); gui_check = gtk_init_check(&argc, &argv); if (!gui_check) { char *display = gdk_get_display(); printf("%s %s\n", PIDGIN_NAME, DISPLAY_VERSION); g_warning("cannot open display: %s", display ? display : "unset"); g_free(display); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 1; } g_set_application_name(PIDGIN_NAME); #ifdef _WIN32 winpidgin_init(hint); #endif if (migration_failed) { char *old = g_strconcat(purple_home_dir(), G_DIR_SEPARATOR_S ".gaim", NULL); const char *text = _( "%s encountered errors migrating your settings " "from %s to %s. Please investigate and complete the " "migration by hand. Please report this error at http://developer.pidgin.im"); GtkWidget *dialog; dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, text, PIDGIN_NAME, old, purple_user_dir()); g_free(old); g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(dialog); gtk_main(); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 0; } purple_core_set_ui_ops(pidgin_core_get_ui_ops()); purple_eventloop_set_ui_ops(pidgin_eventloop_get_ui_ops()); /* * Set plugin search directories. Give priority to the plugins * in user's home directory. */ search_path = g_build_filename(purple_user_dir(), "plugins", NULL); if (!g_stat(search_path, &st)) g_mkdir(search_path, S_IRUSR | S_IWUSR | S_IXUSR); purple_plugins_add_search_path(search_path); g_free(search_path); purple_plugins_add_search_path(LIBDIR); if (!purple_core_init(PIDGIN_UI)) { fprintf(stderr, "Initialization of the libpurple core failed. Dumping core.\n" "Please report this!\n"); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif abort(); } if (opt_si && !purple_core_ensure_single_instance()) { #ifdef HAVE_DBUS DBusConnection *conn = purple_dbus_get_connection(); DBusMessage *message = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleBlistSetVisible"); gboolean tr = TRUE; dbus_message_append_args(message, DBUS_TYPE_INT32, &tr, DBUS_TYPE_INVALID); dbus_connection_send_with_reply_and_block(conn, message, -1, NULL); dbus_message_unref(message); #endif gdk_notify_startup_complete(); purple_core_quit(); g_printerr(_("Exiting because another libpurple client is already running.\n")); #ifdef HAVE_SIGNAL_H g_free(segfault_message); #endif return 0; } /* TODO: Move blist loading into purple_blist_init() */ purple_set_blist(purple_blist_new()); purple_blist_load(); /* load plugins we had when we quit */ purple_plugins_load_saved(PIDGIN_PREFS_ROOT "/plugins/loaded"); /* TODO: Move pounces loading into purple_pounces_init() */ purple_pounces_load(); ui_main(); #ifdef USE_SM pidgin_session_init(argv[0], opt_session_arg, opt_config_dir_arg); #endif if (opt_session_arg != NULL) { g_free(opt_session_arg); opt_session_arg = NULL; } if (opt_config_dir_arg != NULL) { g_free(opt_config_dir_arg); opt_config_dir_arg = NULL; } /* This needs to be before purple_blist_show() so the * statusbox gets the forced online status. */ if (opt_force_online) purple_network_force_online(); /* * We want to show the blist early in the init process so the * user feels warm and fuzzy (not cold and prickley). */ purple_blist_show(); if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled")) pidgin_debug_window_show(); if (opt_login) { /* disable all accounts */ for (accounts = purple_accounts_get_all(); accounts != NULL; accounts = accounts->next) { PurpleAccount *account = accounts->data; purple_account_set_enabled(account, PIDGIN_UI, FALSE); } /* honor the startup status preference */ if (!purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) purple_savedstatus_activate(purple_savedstatus_get_startup()); /* now enable the requested ones */ dologin_named(opt_login_arg); if (opt_login_arg != NULL) { g_free(opt_login_arg); opt_login_arg = NULL; } } else if (opt_nologin) { /* Set all accounts to "offline" */ PurpleSavedStatus *saved_status; /* If we've used this type+message before, lookup the transient status */ saved_status = purple_savedstatus_find_transient_by_type_and_message( PURPLE_STATUS_OFFLINE, NULL); /* If this type+message is unique then create a new transient saved status */ if (saved_status == NULL) saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_OFFLINE); /* Set the status for each account */ purple_savedstatus_activate(saved_status); } else { /* Everything is good to go--sign on already */ if (!purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) purple_savedstatus_activate(purple_savedstatus_get_startup()); purple_accounts_restore_current_statuses(); } if ((active_accounts = purple_accounts_get_all_active()) == NULL) { pidgin_accounts_window_show(); } else { g_list_free(active_accounts); } /* GTK clears the notification for us when opening the first window, * but we may have launched with only a status icon, so clear the it * just in case. */ gdk_notify_startup_complete(); #ifdef _WIN32 winpidgin_post_init(); #endif gtk_main(); #ifdef HAVE_SIGNAL_H g_free(segfault_message); g_source_remove(signal_channel_watcher); close(signal_sockets[0]); close(signal_sockets[1]); #endif #ifdef _WIN32 winpidgin_cleanup(); #endif return 0; }
/* * Test receiving of SIGHUP on master hang-up. All of the tests so far have * ignored SIGHUP, and probably would not have received one anyway, since the * process was not its own session leader. Time to test this aspect. */ static void test77e(void) { struct sigaction act, hup_oact, usr_oact; sigset_t set, oset; char tname[PATH_MAX]; int masterfd, slavefd; subtest = 5; memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; if (sigaction(SIGHUP, &act, &hup_oact) < 0) e(0); memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; if (sigaction(SIGUSR1, &act, &usr_oact) < 0) e(0); sigemptyset(&set); sigaddset(&set, SIGHUP); sigaddset(&set, SIGUSR1); if (sigprocmask(SIG_BLOCK, &set, &oset) < 0) e(0); sighups = 0; /* Make ourselves process group leader if we aren't already. */ (void)setsid(); /* Obtain a pseudo terminal. */ (void)get_pty(&masterfd, NULL, tname); switch (fork()) { case 0: if (close(masterfd) < 0) e(0); /* Become session leader. */ if (setsid() < 0) e(0); if ((slavefd = open(tname, O_RDWR)) < 0) e(0); /* Tell the parent we are ready. */ kill(getppid(), SIGUSR1); /* We should now get a SIGHUP. */ set = oset; if (sigsuspend(&set) >= 0) e(0); if (sighups != 1) e(0); exit(errct); case -1: e(0); default: break; } /* Wait for SIGUSR1 from the child. */ set = oset; if (sigsuspend(&set) >= 0) e(0); /* Closing the master should now raise a SIGHUP signal in the child. */ if (close(masterfd) < 0) e(0); if (waitchild() < 0) e(0); if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) e(0); if (sigaction(SIGHUP, &hup_oact, NULL) < 0) e(0); if (sigaction(SIGUSR1, &usr_oact, NULL) < 0) e(0); }
int main(int argc, char *argv[]) { char *buf; struct disk *disks, *dp; int ch, ok; long long minwait, nextwait; struct sigaction sa; long long counter; int initial_debug; const char *conf_file, *save_file; conf_file = _PATH_CONF; save_file = _PATH_SAVE; debug = 0; while ((ch = getopt(argc, argv, "df:o:")) != -1) switch (ch) { case 'd': if (debug) debug *= 2; else debug = 1; break; case 'f': conf_file = optarg; break; case 'o': save_file = optarg; break; default: usage(); /* NOTREACHED */ } argv += optind; argc -= optind; if (argc != 0) usage(); initial_debug = debug; openlog("diskcheckd", LOG_CONS|LOG_PID|(debug?LOG_PERROR:0), LOG_DAEMON); if (!debug && daemon(0, 0) < 0) { syslog(LOG_NOTICE, "daemon() failure: %m"); exit(EXIT_FAILURE); } sa.sa_handler = sigterm; sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = sighup; sigaction(SIGHUP, &sa, NULL); /* Read the configuration file and the saved offsets */ disks = readconf(conf_file); readoffsets(disks, save_file); if ((buf = malloc(READ_SIZE)) == NULL) { syslog(LOG_NOTICE, "malloc failure: %m"); exit(EXIT_FAILURE); } /* The main disk checking loop. * * We wait the shortest amount of time we need to before * another disk is due for a read -- this time is updated * in the 'nextwait' variable, which is then copied to * 'minwait'. After a sleep, 'minwait' is subtracted from * each disk's 'next' field, and when that reaches zero, * that disk is read again. */ counter = 0LL; minwait = 0LL; while (!got_sigterm) { ok = 0; nextwait = LLONG_MAX; for (dp = disks; dp->device != NULL; dp++) if (dp->fd != -1) { if (debug > 1) fprintf(stderr, "%s: next(%qd) -= %qd\n", dp->device, dp->next, minwait); if ((dp->next -= minwait) == 0) { ok = 1; readchunk(dp, buf); } /* XXX debugging */ if (dp->next < 0LL) { syslog(LOG_NOTICE, "dp->next < 0 for %s", dp->device); abort(); } if (dp->next < nextwait) nextwait = dp->next; } if (!ok) { syslog(LOG_EMERG, "all disks had read errors"); exit(EXIT_FAILURE); } /* 300 seconds => 5 minutes */ if (counter >= 300000000LL) { if (debug) fprintf(stderr, "counter rollover %qd => 0\n", counter); updateproctitle(disks); writeoffsets(disks, save_file); counter = 0LL; } minwait = nextwait; if (debug > 1) { --debug; fprintf(stderr, "sleep %qd, counter %qd\n", minwait, counter); } /* * Handle whole seconds and usec separately to avoid overflow * when calling usleep -- useconds_t is only 32 bits on at * least some architectures, and minwait (being long long) * may exceed INT_MAX. */ if (minwait > 1000000LL) sleep((unsigned int)(minwait / 1000000)); if ((minwait % 1000000) > 0) usleep((useconds_t)(minwait % 1000000)); counter += minwait; if (got_sighup) { /* * Got a SIGHUP, so save the offsets, free the * memory used for the disk structures, and then * re-read the config file and the disk offsets. */ if (debug) { fprintf(stderr, "got SIGHUP, counter == %qd\n", counter); debug = initial_debug; } writeoffsets(disks, save_file); for (dp = disks; dp->device != NULL; dp++) { free(dp->device); close(dp->fd); } free(disks); disks = readconf(conf_file); readoffsets(disks, save_file); minwait = 0LL; got_sighup = 0; } } if (debug) fprintf(stderr, "got %s, counter == %qd\n", got_sigterm==SIGTERM?"SIGTERM":"SIGINT", counter); writeoffsets(disks, save_file); return (EXIT_SUCCESS); }
int main(int argc, char **argv) { sigset_t block_mask, unblock_mask; struct sigaction sa; int ch; FILE *timingfd = stderr; enum { FORCE_OPTION = CHAR_MAX + 1 }; static const struct option longopts[] = { { "append", no_argument, NULL, 'a' }, { "command", required_argument, NULL, 'c' }, { "return", no_argument, NULL, 'e' }, { "flush", no_argument, NULL, 'f' }, { "force", no_argument, NULL, FORCE_OPTION, }, { "quiet", no_argument, NULL, 'q' }, { "timing", optional_argument, NULL, 't' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* see comment above */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((ch = getopt_long(argc, argv, "ac:efqt::Vh", longopts, NULL)) != -1) switch(ch) { case 'a': aflg = 1; break; case 'c': cflg = optarg; break; case 'e': eflg = 1; break; case 'f': fflg = 1; break; case FORCE_OPTION: forceflg = 1; break; case 'q': qflg = 1; break; case 't': if (optarg) if ((timingfd = fopen(optarg, "w")) == NULL) err(EXIT_FAILURE, _("cannot open %s"), optarg); tflg = 1; break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); exit(EXIT_SUCCESS); break; case 'h': usage(stdout); break; case '?': default: usage(stderr); } argc -= optind; argv += optind; if (argc > 0) fname = argv[0]; else { fname = DEFAULT_OUTPUT; die_if_link(fname); } if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { warn(_("cannot open %s"), fname); fail(); } shell = getenv("SHELL"); if (shell == NULL) shell = _PATH_BSHELL; getmaster(); if (!qflg) printf(_("Script started, file is %s\n"), fname); fixtty(); #ifdef HAVE_LIBUTEMPTER utempter_add_record(master, NULL); #endif /* setup SIGCHLD handler */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = finish; sigaction(SIGCHLD, &sa, NULL); /* init mask for SIGCHLD */ sigprocmask(SIG_SETMASK, NULL, &block_mask); sigaddset(&block_mask, SIGCHLD); sigprocmask(SIG_SETMASK, &block_mask, &unblock_mask); child = fork(); sigprocmask(SIG_SETMASK, &unblock_mask, NULL); if (child < 0) { warn(_("fork failed")); fail(); } if (child == 0) { sigprocmask(SIG_SETMASK, &block_mask, NULL); subchild = child = fork(); sigprocmask(SIG_SETMASK, &unblock_mask, NULL); if (child < 0) { warn(_("fork failed")); fail(); } if (child) dooutput(timingfd); else doshell(); } else { sa.sa_handler = resize; sigaction(SIGWINCH, &sa, NULL); } doinput(); if (close_stream(timingfd) != 0) errx(EXIT_FAILURE, _("write error")); return EXIT_SUCCESS; }
/********************************************** * main */ int main(int argc, char *argv[]) { AVB_TRACE_ENTRY(AVB_TRACE_HOST); int iniIdx = 0; char *programName; char *optIfnameGlobal = NULL; programName = strrchr(argv[0], '/'); programName = programName ? programName + 1 : argv[0]; if (argc < 2) { openavbTlHostUsage(programName); exit(-1); } tl_handle_t *tlHandleList = NULL; int i1; // Process command line bool optDone = FALSE; while (!optDone) { int opt = getopt(argc, argv, "hI:"); if (opt != EOF) { switch (opt) { case 'I': optIfnameGlobal = strdup(optarg); break; case 'h': default: openavbTlHostUsage(programName); exit(-1); } } else { optDone = TRUE; } } osalAVBInitialize(optIfnameGlobal); iniIdx = optind; U32 tlCount = argc - iniIdx; if (!openavbTLInitialize(tlCount)) { AVB_LOG_ERROR("Unable to initialize talker listener library"); osalAVBFinalize(); exit(-1); } // Setup signal handler // We catch SIGINT and shutdown cleanly bool err; struct sigaction sa; sa.sa_handler = openavbTLSigHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; err = sigaction(SIGINT, &sa, NULL); if (err) { AVB_LOG_ERROR("Failed to setup SIGINT handler"); osalAVBFinalize(); exit(-1); } err = sigaction(SIGUSR1, &sa, NULL); if (err) { AVB_LOG_ERROR("Failed to setup SIGUSR1 handler"); osalAVBFinalize(); exit(-1); } registerStaticMapModule(openavbMapPipeInitialize); registerStaticMapModule(openavbMapAVTPAudioInitialize); registerStaticMapModule(openavbMapCtrlInitialize); registerStaticMapModule(openavbMapH264Initialize); registerStaticMapModule(openavbMapMjpegInitialize); registerStaticMapModule(openavbMapMpeg2tsInitialize); registerStaticMapModule(openavbMapNullInitialize); registerStaticMapModule(openavbMapUncmpAudioInitialize); registerStaticIntfModule(openavbIntfEchoInitialize); registerStaticIntfModule(openavbIntfCtrlInitialize); registerStaticIntfModule(openavbIntfLoggerInitialize); registerStaticIntfModule(openavbIntfNullInitialize); //registerStaticIntfModule(openavbIntfToneGenInitialize); registerStaticIntfModule(openavbIntfViewerInitialize); registerStaticIntfModule(openavbIntfAlsaInitialize); registerStaticIntfModule(openavbIntfMjpegGstInitialize); registerStaticIntfModule(openavbIntfMpeg2tsFileInitialize); registerStaticIntfModule(openavbIntfMpeg2tsGstInitialize); registerStaticIntfModule(openavbIntfWavFileInitialize); registerStaticIntfModule(openavbIntfH264RtpGstInitialize); tlHandleList = calloc(1, sizeof(tl_handle_t) * tlCount); // Open all streams for (i1 = 0; i1 < tlCount; i1++) { tlHandleList[i1] = openavbTLOpen(); } // Parse ini and configure all streams for (i1 = 0; i1 < tlCount; i1++) { openavb_tl_cfg_t cfg; openavb_tl_cfg_name_value_t NVCfg; char iniFile[1024]; snprintf(iniFile, sizeof(iniFile), "%s", argv[i1 + iniIdx]); if (optIfnameGlobal && !strcasestr(iniFile, ",ifname=")) { snprintf(iniFile + strlen(iniFile), sizeof(iniFile), ",ifname=%s", optIfnameGlobal); } openavbTLInitCfg(&cfg); memset(&NVCfg, 0, sizeof(NVCfg)); if (!openavbTLReadIniFileOsal(tlHandleList[i1], iniFile, &cfg, &NVCfg)) { AVB_LOGF_ERROR("Error reading ini file: %s\n", argv[i1 + 1]); osalAVBFinalize(); exit(-1); } if (!openavbTLConfigure(tlHandleList[i1], &cfg, &NVCfg)) { AVB_LOGF_ERROR("Error configuring: %s\n", argv[i1 + 1]); osalAVBFinalize(); exit(-1); } int i2; for (i2 = 0; i2 < NVCfg.nLibCfgItems; i2++) { free(NVCfg.libCfgNames[i2]); free(NVCfg.libCfgValues[i2]); } } #ifdef AVB_FEATURE_GSTREAMER // If we're supporting the interface modules which use GStreamer, // initialize GStreamer here to avoid errors. gst_init(0, NULL); #endif for (i1 = 0; i1 < tlCount; i1++) { openavbTLRun(tlHandleList[i1]); } while (bRunning) { sleep(1); } for (i1 = 0; i1 < tlCount; i1++) { openavbTLStop(tlHandleList[i1]); } for (i1 = 0; i1 < tlCount; i1++) { openavbTLClose(tlHandleList[i1]); } openavbTLCleanup(); #ifdef AVB_FEATURE_GSTREAMER // If we're supporting the interface modules which use GStreamer, // De-initialize GStreamer to clean up resources. gst_deinit(); #endif osalAVBFinalize(); AVB_TRACE_EXIT(AVB_TRACE_HOST); exit(0); }
void execute(struct command *t, int wanttty, int *pipein, int *pipeout) { bool forked = 0; struct biltins *bifunc; int pid = 0; int pv[2]; sigset_t sigset; static sigset_t csigset; static sigset_t ocsigset; static int onosigchld = 0; static int nosigchld = 0; UNREGISTER(forked); UNREGISTER(bifunc); UNREGISTER(wanttty); if (t == 0) return; if (t->t_dflg & F_AMPERSAND) wanttty = 0; switch (t->t_dtyp) { case NODE_COMMAND: if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) (void) memmove(t->t_dcom[0], t->t_dcom[0] + 1, (Strlen(t->t_dcom[0] + 1) + 1) * sizeof(Char)); if ((t->t_dflg & F_REPEAT) == 0) Dfix(t); /* $ " ' \ */ if (t->t_dcom[0] == 0) return; /* fall into... */ case NODE_PAREN: if (t->t_dflg & F_PIPEOUT) mypipe(pipeout); /* * Must do << early so parent will know where input pointer should be. * If noexec then this is all we do. */ if (t->t_dflg & F_READ) { (void) close(0); heredoc(t->t_dlef); if (noexec) (void) close(0); } set(STRstatus, Strsave(STR0)); /* * This mess is the necessary kludge to handle the prefix builtins: * nice, nohup, time. These commands can also be used by themselves, * and this is not handled here. This will also work when loops are * parsed. */ while (t->t_dtyp == NODE_COMMAND) if (eq(t->t_dcom[0], STRnice)) if (t->t_dcom[1]) if (strchr("+-", t->t_dcom[1][0])) if (t->t_dcom[2]) { setname("nice"); t->t_nice = getn(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_NICE; } else break; else { t->t_nice = 4; lshift(t->t_dcom, 1); t->t_dflg |= F_NICE; } else break; else if (eq(t->t_dcom[0], STRnohup)) if (t->t_dcom[1]) { t->t_dflg |= F_NOHUP; lshift(t->t_dcom, 1); } else break; else if (eq(t->t_dcom[0], STRtime)) if (t->t_dcom[1]) { t->t_dflg |= F_TIME; lshift(t->t_dcom, 1); } else break; else break; /* is it a command */ if (t->t_dtyp == NODE_COMMAND) { /* * Check if we have a builtin function and remember which one. */ bifunc = isbfunc(t); if (noexec) { /* * Continue for builtins that are part of the scripting language */ if (bifunc && bifunc->bfunct != dobreak && bifunc->bfunct != docontin && bifunc->bfunct != doelse && bifunc->bfunct != doend && bifunc->bfunct != doforeach && bifunc->bfunct != dogoto && bifunc->bfunct != doif && bifunc->bfunct != dorepeat && bifunc->bfunct != doswbrk && bifunc->bfunct != doswitch && bifunc->bfunct != dowhile && bifunc->bfunct != dozip) break; } } else { /* not a command */ bifunc = NULL; if (noexec) break; } /* * We fork only if we are timed, or are not the end of a parenthesized * list and not a simple builtin function. Simple meaning one that is * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not * fork in some of these cases. */ /* * Prevent forking cd, pushd, popd, chdir cause this will cause the * shell not to change dir! */ if (bifunc && (bifunc->bfunct == dochngd || bifunc->bfunct == dopushd || bifunc->bfunct == dopopd)) t->t_dflg &= ~(F_NICE); if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && (!bifunc || t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) || /* * We have to fork for eval too. */ (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 && bifunc->bfunct == doeval)) { if (t->t_dtyp == NODE_PAREN || t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) { forked++; /* * We need to block SIGCHLD here, so that if the process does * not die before we can set the process group */ if (wanttty >= 0 && !nosigchld) { sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &csigset); nosigchld = 1; } pid = pfork(t, wanttty); if (pid == 0 && nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) backpid = pid; } else { int ochild, osetintr, ohaderr, odidfds; int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp; sigset_t osigset; /* * Prepare for the vfork by saving everything that the child * corrupts before it exec's. Note that in some signal * implementations which keep the signal info in user space * (e.g. Sun's) it will also be necessary to save and restore * the current sigaction's for the signals the child touches * before it exec's. */ if (wanttty >= 0 && !nosigchld && !noexec) { sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &csigset); nosigchld = 1; } sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigaddset(&sigset, SIGINT); sigprocmask(SIG_BLOCK, &sigset, &osigset); ochild = child; osetintr = setintr; ohaderr = haderr; odidfds = didfds; oSHIN = SHIN; oSHOUT = SHOUT; oSHERR = SHERR; oOLDSTD = OLDSTD; otpgrp = tpgrp; ocsigset = csigset; onosigchld = nosigchld; Vsav = Vdp = 0; Vexpath = 0; Vt = 0; pid = vfork(); if (pid < 0) { sigprocmask(SIG_SETMASK, &osigset, NULL); stderror(ERR_NOPROC); } forked++; if (pid) { /* parent */ child = ochild; setintr = osetintr; haderr = ohaderr; didfds = odidfds; SHIN = oSHIN; SHOUT = oSHOUT; SHERR = oSHERR; OLDSTD = oOLDSTD; tpgrp = otpgrp; csigset = ocsigset; nosigchld = onosigchld; xfree((ptr_t) Vsav); Vsav = 0; xfree((ptr_t) Vdp); Vdp = 0; xfree((ptr_t) Vexpath); Vexpath = 0; blkfree((Char **) Vt); Vt = 0; /* this is from pfork() */ palloc(pid, t); sigprocmask(SIG_SETMASK, &osigset, NULL); } else { /* child */ /* this is from pfork() */ int pgrp; bool ignint = 0; if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if (setintr) ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) || (gointr && eq(gointr, STRminus)); pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); child++; if (setintr) { setintr = 0; if (ignint) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } else { (void) signal(SIGINT, vffree); (void) signal(SIGQUIT, SIG_DFL); } if (wanttty >= 0) { (void) signal(SIGTSTP, SIG_DFL); (void) signal(SIGTTIN, SIG_DFL); (void) signal(SIGTTOU, SIG_DFL); } (void) signal(SIGTERM, parterm); } else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } pgetty(wanttty, pgrp); if (t->t_dflg & F_NOHUP) (void) signal(SIGHUP, SIG_IGN); if (t->t_dflg & F_NICE) (void) setpriority(PRIO_PROCESS, 0, t->t_nice); } } } if (pid != 0) { /* * It would be better if we could wait for the whole job when we * knew the last process had been started. Pwait, in fact, does * wait for the whole job anyway, but this test doesn't really * express our intentions. */ if (didfds == 0 && t->t_dflg & F_PIPEIN) { (void) close(pipein[0]); (void) close(pipein[1]); } if ((t->t_dflg & F_PIPEOUT) == 0) { if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if ((t->t_dflg & F_AMPERSAND) == 0) pwait(); } break; } doio(t, pipein, pipeout); if (t->t_dflg & F_PIPEOUT) { (void) close(pipeout[0]); (void) close(pipeout[1]); } /* * Perform a builtin function. If we are not forked, arrange for * possible stopping */ if (bifunc) { func(t, bifunc); if (forked) exitstat(); break; } if (t->t_dtyp != NODE_PAREN) { doexec(NULL, t); /* NOTREACHED */ } /* * For () commands must put new 0,1,2 in FSH* and recurse */ OLDSTD = dcopy(0, FOLDSTD); SHOUT = dcopy(1, FSHOUT); SHERR = dcopy(2, FSHERR); (void) close(SHIN); SHIN = -1; didfds = 0; wanttty = -1; t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dspr, wanttty, NULL, NULL); exitstat(); case NODE_PIPE: t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT)); execute(t->t_dcar, wanttty, pipein, pv); t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT)); if (wanttty > 0) wanttty = 0; /* got tty already */ execute(t->t_dcdr, wanttty, pv, pipeout); break; case NODE_LIST: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dcar, wanttty, NULL, NULL); /* * In strange case of A&B make a new job after A */ if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) pendjob(); } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT); execute(t->t_dcdr, wanttty, NULL, NULL); } break; case NODE_OR: case NODE_AND: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT; execute(t->t_dcar, wanttty, NULL, NULL); if ((getn(value(STRstatus)) == 0) != (t->t_dtyp == NODE_AND)) return; } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT); execute(t->t_dcdr, wanttty, NULL, NULL); } break; } /* * Fall through for all breaks from switch * * If there will be no more executions of this command, flush all file * descriptors. Places that turn on the F_REPEAT bit are responsible for * doing donefds after the last re-execution */ if (didfds && !(t->t_dflg & F_REPEAT)) donefds(); }
int main(int argc, char **argv) { struct sigaction new_action; new_action.sa_handler = SIG_IGN; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGPIPE, &new_action, NULL); int rv = 0; char *host = NULL; char *port = NULL; char *docroot = NULL; size_t max_threads = 20; char *ptr; char *endptr; char *tmp_host = getenv("BLOGC_RUNSERVER_DEFAULT_HOST"); char *default_host = bc_strdup(tmp_host != NULL ? tmp_host : "127.0.0.1"); char *tmp_port = getenv("BLOGC_RUNSERVER_DEFAULT_PORT"); char *default_port = bc_strdup(tmp_port != NULL ? tmp_port : "8080"); size_t args = 0; for (size_t i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'h': print_help(default_host, default_port); goto cleanup; case 'v': printf("%s\n", PACKAGE_STRING); goto cleanup; case 't': if (argv[i][2] != '\0') host = bc_strdup(argv[i] + 2); else host = bc_strdup(argv[++i]); break; case 'p': if (argv[i][2] != '\0') port = bc_strdup(argv[i] + 2); else port = bc_strdup(argv[++i]); break; case 'm': if (argv[i][2] != '\0') ptr = argv[i] + 2; else ptr = argv[++i]; max_threads = strtoul(ptr, &endptr, 10); if (*ptr != '\0' && *endptr != '\0') fprintf(stderr, "blogc-runserver: warning: invalid value " "for -m argument: %s. using %zu instead\n", ptr, max_threads); break; default: print_usage(); fprintf(stderr, "blogc-runserver: error: invalid " "argument: -%c\n", argv[i][1]); rv = 1; goto cleanup; } } else { if (args > 0) { print_usage(); fprintf(stderr, "blogc-runserver: error: only one positional " "argument allowed\n"); rv = 1; goto cleanup; } args++; docroot = bc_strdup(argv[i]); } } if (docroot == NULL) { print_usage(); fprintf(stderr, "blogc-runserver: error: document root directory " "required\n"); rv = 1; goto cleanup; } if (max_threads <= 0 || max_threads > 1000) { print_usage(); fprintf(stderr, "blogc-runserver: error: invalid value for -m. " "Must be integer > 0 and <= 1000\n"); rv = 1; goto cleanup; } rv = br_httpd_run( host != NULL ? host : default_host, port != NULL ? port : default_port, docroot, max_threads); cleanup: free(default_host); free(default_port); free(host); free(port); free(docroot); return rv; }
int main(int argc, char* argv[]) { // Setup bad allocation handler std::set_new_handler(badAllocationHandler); #ifndef _WIN32 // ignore sigpipe... struct sigaction sigh; sigh.sa_handler = SIG_IGN; sigh.sa_flags = 0; sigemptyset(&sigh.sa_mask); sigaction(SIGPIPE, &sigh, nullptr); #endif ServiceManager serviceManager; g_serviceManager = &serviceManager; g_dispatcher.start(); g_scheduler.start(); g_dispatcher.addTask(createTask(std::bind(mainLoader, argc, argv, &serviceManager))); g_loaderSignal.wait(g_loaderUniqueLock); if (serviceManager.is_running()) { std::cout << ">> " << STATUS_SERVER_NAME << " Online!" << std::endl << std::endl; #ifdef _WIN32 SetConsoleCtrlHandler([](DWORD) -> BOOL { g_dispatcher.addTask(createTask([]() { g_dispatcher.addTask(createTask([]() { shutdown(); })); g_scheduler.stop(); g_databaseTasks.stop(); g_dispatcher.stop(); })); ExitThread(0); }, 1); #endif serviceManager.run(); } else { std::cout << ">> No services running. The server is NOT online." << std::endl; g_dispatcher.addTask(createTask([]() { g_dispatcher.addTask(createTask([]() { g_scheduler.shutdown(); g_databaseTasks.shutdown(); g_dispatcher.shutdown(); })); g_scheduler.stop(); g_databaseTasks.stop(); g_dispatcher.stop(); })); } g_scheduler.join(); g_databaseTasks.join(); g_dispatcher.join(); return 0; }
int main () { #ifdef SIG_SETMASK /* Ensure all the signals aren't blocked. The environment in which the testsuite is run may have blocked some for whatever reason. */ { sigset_t newset; sigemptyset (&newset); sigprocmask (SIG_SETMASK, &newset, NULL); } #endif signal (SIGABRT, handle_ABRT); #ifdef SIGHUP signal (SIGHUP, handle_HUP); #endif #ifdef SIGQUIT signal (SIGQUIT, handle_QUIT); #endif #ifdef SIGILL signal (SIGILL, handle_ILL); #endif #ifdef SIGEMT signal (SIGEMT, handle_EMT); #endif #ifdef SIGFPE signal (SIGFPE, handle_FPE); #endif #ifdef SIGBUS signal (SIGBUS, handle_BUS); #endif #ifdef SIGSEGV signal (SIGSEGV, handle_SEGV); #endif #ifdef SIGSYS signal (SIGSYS, handle_SYS); #endif #ifdef SIGPIPE signal (SIGPIPE, handle_PIPE); #endif #ifdef SIGALRM signal (SIGALRM, handle_ALRM); #endif #ifdef SIGURG signal (SIGURG, handle_URG); #endif #ifdef SIGTSTP signal (SIGTSTP, handle_TSTP); #endif #ifdef SIGCONT signal (SIGCONT, handle_CONT); #endif #ifdef SIGCHLD signal (SIGCHLD, handle_CHLD); #endif #ifdef SIGTTIN signal (SIGTTIN, handle_TTIN); #endif #ifdef SIGTTOU signal (SIGTTOU, handle_TTOU); #endif #ifdef SIGIO signal (SIGIO, handle_IO); #endif #ifdef SIGXCPU signal (SIGXCPU, handle_XCPU); #endif #ifdef SIGXFSZ signal (SIGXFSZ, handle_XFSZ); #endif #ifdef SIGVTALRM signal (SIGVTALRM, handle_VTALRM); #endif #ifdef SIGPROF signal (SIGPROF, handle_PROF); #endif #ifdef SIGWINCH signal (SIGWINCH, handle_WINCH); #endif #if defined(SIGLOST) && (!defined(SIGABRT) || SIGLOST != SIGABRT) signal (SIGLOST, handle_LOST); #endif #ifdef SIGUSR1 signal (SIGUSR1, handle_USR1); #endif #ifdef SIGUSR2 signal (SIGUSR2, handle_USR2); #endif #ifdef SIGPWR signal (SIGPWR, handle_PWR); #endif #if defined (SIGPOLL) && (!defined (SIGIO) || SIGPOLL != SIGIO) signal (SIGPOLL, handle_POLL); #endif #ifdef SIGWIND signal (SIGWIND, handle_WIND); #endif #ifdef SIGPHONE signal (SIGPHONE, handle_PHONE); #endif #ifdef SIGWAITING signal (SIGWAITING, handle_WAITING); #endif #ifdef SIGLWP signal (SIGLWP, handle_LWP); #endif #ifdef SIGDANGER signal (SIGDANGER, handle_DANGER); #endif #ifdef SIGGRANT signal (SIGGRANT, handle_GRANT); #endif #ifdef SIGRETRACT signal (SIGRETRACT, handle_RETRACT); #endif #ifdef SIGMSG signal (SIGMSG, handle_MSG); #endif #ifdef SIGSOUND signal (SIGSOUND, handle_SOUND); #endif #ifdef SIGSAK signal (SIGSAK, handle_SAK); #endif #ifdef SIGPRIO signal (SIGPRIO, handle_PRIO); #endif #ifdef __Lynx__ /* Lynx doesn't seem to have anything in signal.h for this. */ signal (33, handle_33); signal (34, handle_34); signal (35, handle_35); signal (36, handle_36); signal (37, handle_37); signal (38, handle_38); signal (39, handle_39); signal (40, handle_40); signal (41, handle_41); signal (42, handle_42); signal (43, handle_43); signal (44, handle_44); signal (45, handle_45); signal (46, handle_46); signal (47, handle_47); signal (48, handle_48); signal (49, handle_49); signal (50, handle_50); signal (51, handle_51); signal (52, handle_52); signal (53, handle_53); signal (54, handle_54); signal (55, handle_55); signal (56, handle_56); signal (57, handle_57); signal (58, handle_58); signal (59, handle_59); signal (60, handle_60); signal (61, handle_61); signal (62, handle_62); signal (63, handle_63); #endif /* lynx */ signal (SIGTERM, handle_TERM); x = 0; gen_ABRT (); gen_HUP (); gen_QUIT (); gen_ILL (); gen_EMT (); gen_FPE (); gen_BUS (); gen_SEGV (); gen_SYS (); gen_PIPE (); gen_ALRM (); gen_URG (); gen_TSTP (); gen_CONT (); gen_CHLD (); gen_TTIN (); gen_TTOU (); gen_IO (); gen_XCPU (); gen_XFSZ (); gen_VTALRM (); gen_PROF (); gen_WINCH (); gen_LOST (); gen_USR1 (); gen_USR2 (); gen_PWR (); gen_POLL (); gen_WIND (); gen_PHONE (); gen_WAITING (); gen_LWP (); gen_DANGER (); gen_GRANT (); gen_RETRACT (); gen_MSG (); gen_SOUND (); gen_SAK (); gen_PRIO (); gen_33 (); gen_34 (); gen_35 (); gen_36 (); gen_37 (); gen_38 (); gen_39 (); gen_40 (); gen_41 (); gen_42 (); gen_43 (); gen_44 (); gen_45 (); gen_46 (); gen_47 (); gen_48 (); gen_49 (); gen_50 (); gen_51 (); gen_52 (); gen_53 (); gen_54 (); gen_55 (); gen_56 (); gen_57 (); gen_58 (); gen_59 (); gen_60 (); gen_61 (); gen_62 (); gen_63 (); gen_TERM (); return 0; /* end of main */ }