Esempio n. 1
0
/* 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);
        }
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}
Esempio n. 6
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);
}
Esempio n. 7
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()));
    }
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
/******************************************************************************
 *                                                                            *
 * 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();
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
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);
  }
}
Esempio n. 14
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 */
}
Esempio n. 15
0
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 */
Esempio n. 16
0
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
}
Esempio n. 17
0
//初始化事件处理函数
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;
}
Esempio n. 18
0
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
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;
        }
    }
Esempio n. 21
0
    //----------------------------------------------------------------------
    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");
    }
Esempio n. 22
0
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;
}
Esempio n. 23
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);
}
Esempio n. 24
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);
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
/**********************************************
 * 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);
}
Esempio n. 27
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();
}
Esempio n. 28
0
File: main.c Progetto: blogc/blogc
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
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 */
}