コード例 #1
0
ファイル: id3.c プロジェクト: a5216652166/fasterpussycat
struct id3_node *build_tree(struct url_test *test, struct id3_node *root){
  struct feature *picked;
  /* if the root node is null, construct a new root node */

  if(root==NULL){
    root=calloc(sizeof(struct id3_node),1);
    root->type=ID3_ROOT;
    root->test=test;
    root->score.test=test;
    root->score.score=(double) test->success / (double) test->count;
    return build_tree(test,root);
  }
  

  /* otherwise continue */

  picked=pick_feature(root);
  if(picked==NULL){
  //print_path(root->parent);
  //printf("[STOP]\n");
  return root; /* end of tree */
  }
  root->feature=picked;
  root->child_evidence=spawn_child(root,1);
  root->child_no_evidence=spawn_child(root,0);
  build_tree(test, root->child_evidence);
  build_tree(test, root->child_no_evidence);
  return root;




  
}
コード例 #2
0
 int svc (void)
 {
   int result = 0;
   ACE_exitcode exitcode;
   pid_t my_child = spawn_child (argv0_,
                                 mgr_,
                                 sleep_time_,
                                 0);
   result = mgr_.wait (my_child,
                       &exitcode);
   if (result != my_child)
     {
       ACE_ERROR ((LM_ERROR,
                   ACE_TEXT ("(%P) Error: expected to reap child (%d); got %d\n"),
                   my_child,
                   result));
       if (result == ACE_INVALID_PID)
         ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
       //test_status = 1;
     }
   else
     ACE_DEBUG ((LM_DEBUG,
                 ACE_TEXT ("(%P) reaped child, pid %d: %d\n"),
                 my_child,
                 exitcode));
   char tmp[10];
   order += ACE_OS::itoa (sleep_time_, tmp, 10);
   return 0;
 }
コード例 #3
0
ファイル: tree.c プロジェクト: pinne/algodat
void create_tree(struct tree *node, int depth)
{
	if (node->level < depth) {
		node->left = spawn_child(node, node->left);
		create_tree(node->left, depth);
		node->right = spawn_child(node, node->right);
		create_tree(node->right, depth);

#ifndef TWO_DIMENSION
		node->up = spawn_child(node, node->up);
		create_tree(node->up, depth);
		node->down = spawn_child(node, node->down);
		create_tree(node->down, depth);
#endif
	}
}
コード例 #4
0
ファイル: Audio.c プロジェクト: Remmy/afterstep
Bool audio_player_ext(short sound)
{
    if( check_singleton_child(AUDIO_SINGLETON_ID,False) > 0 ) return False ;/* previous command still running */
    if( sound_table[sound] == NULL ) return False; /* nothing to do */

    spawn_child( SOUNDPLAYER, AUDIO_SINGLETON_ID, -1, NULL, None, 0, True, False, Config->playcmd, sound_table[sound], NULL );

    return True ;
}
コード例 #5
0
void
accept_connection(SOCKET listen_fd) {

  struct sockaddr_storage peeraddr;
  netperf_socklen_t peeraddrlen;
#if defined(SO_KEEPALIVE)
  int on = 1;
#endif

  if (debug) {
    fprintf(where,
	    "%s: enter\n",
	    __FUNCTION__);
    fflush(where);
  }

  peeraddrlen = sizeof(peeraddr);

  /* while server_control is only used by the WIN32 path, but why
     bother ifdef'ing it?  and besides, do we *really* need knowledge
     of server_control in the WIN32 case? do we have to tell the
     child about *all* the listen endpoints? raj 2011-07-08 */
  server_control = listen_fd;

  if ((server_sock = accept(listen_fd,
			   (struct sockaddr *)&peeraddr,
			    &peeraddrlen)) == INVALID_SOCKET) {
    fprintf(where,
	    "%s: accept failure: %s (errno %d)\n",
	    __FUNCTION__,
	    strerror(errno),
	    errno);
    fflush(where);
    exit(1);
  }

#if defined(SO_KEEPALIVE)
  /* we are not terribly concerned if this does not work, it is merely
     duct tape added to belts and suspenders. raj 2011-07-08 */
  setsockopt(server_sock,
	     SOL_SOCKET,
	     SO_KEEPALIVE,
	     (const char *)&on,
	     sizeof(on));
#endif

  if (spawn_on_accept) {
    spawn_child();
    /* spawn_child() only returns when we are the parent */
    close(server_sock);
  }
  else {
    process_requests();
  }
}
コード例 #6
0
static int start_btcli(btcli* child)
{
    /* The handles of the pipes */
    int pipetochild[2], pipefromchild[2];
    int pid;

    if((print_output & 2) != 0)
	printf("Starting BTCLI\n");

    /* Create the pipes */
    if (pipe (pipetochild))
    {
	printf("pipe (to child) -> got !0\n");
	perror (progname);
	exit (EXIT_FAILURE);
    }

    if (pipe (pipefromchild))
    {
	printf("pipe (from child) -> got !0\n");
	perror (progname);
	exit (EXIT_FAILURE);
    }

    /* FORK so that the child can execute (inhereting files) */
    pid = fork ();
    switch (pid)
    {
    case -1:
	printf("fork -> got -1\n");
	perror (progname);
	exit (EXIT_FAILURE);
	break;

    case 0:
        signal (SIGPIPE, SIG_IGN);

	spawn_child(pipetochild, pipefromchild);
	_exit (EXIT_FAILURE);
	break; 

    default:
	if((print_output & 2) != 0)
	    printf ("Parent (PID %i); child PID is %i\n", getpid (), pid);
	close (pipefromchild[PIPE_WRITEEND]);
	close (pipetochild[PIPE_READEND]);
    }

    child->read  = pipefromchild[PIPE_READEND];
    child->write = pipetochild[PIPE_WRITEEND];
    child->pid   = pid;

    return pid;
}
コード例 #7
0
static void
wait_for_connection(krb5_context context,
		    krb5_socket_t *socks, unsigned int num_socks)
{
    unsigned int i;
    int e;
    fd_set orig_read_set, read_set;
    int status, max_fd = -1;

    FD_ZERO(&orig_read_set);

    for(i = 0; i < num_socks; i++) {
#ifdef FD_SETSIZE
	if (socks[i] >= FD_SETSIZE)
	    errx (1, "fd too large");
#endif
	FD_SET(socks[i], &orig_read_set);
	max_fd = max(max_fd, socks[i]);
    }

    pgrp = getpid();

    if(setpgid(0, pgrp) < 0)
	err(1, "setpgid");

    signal(SIGTERM, terminate);
    signal(SIGINT, terminate);
    signal(SIGCHLD, sigchld);

    while (term_flag == 0) {
	read_set = orig_read_set;
	e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
	if(rk_IS_SOCKET_ERROR(e)) {
	    if(rk_SOCK_ERRNO != EINTR)
		krb5_warn(context, rk_SOCK_ERRNO, "select");
	} else if(e == 0)
	    krb5_warnx(context, "select returned 0");
	else {
	    for(i = 0; i < num_socks; i++) {
		if(FD_ISSET(socks[i], &read_set))
		    if(spawn_child(context, socks, num_socks, i) == 0)
			return;
	    }
	}
    }
    signal(SIGCHLD, SIG_IGN);

    while ((waitpid(-1, &status, WNOHANG)) > 0)
	;

    exit(0);
}
コード例 #8
0
ファイル: kadm_conn.c プロジェクト: 2014-class/freerouter
static int
wait_for_connection(krb5_context context,
		    int *socks, int num_socks)
{
    int i, e;
    fd_set orig_read_set, read_set;
    int max_fd = -1;
    
    FD_ZERO(&orig_read_set);
    
    for(i = 0; i < num_socks; i++) {
	if (socks[i] >= FD_SETSIZE)
	    errx (1, "fd too large");
	FD_SET(socks[i], &orig_read_set);
	max_fd = max(max_fd, socks[i]);
    }
    
    pgrp = getpid();

    if(setpgid(0, pgrp) < 0)
	err(1, "setpgid");

    signal(SIGTERM, terminate);
    signal(SIGINT, terminate);
    signal(SIGCHLD, sigchld);

    while (term_flag == 0) {
	read_set = orig_read_set;
	e = select(max_fd + 1, &read_set, NULL, NULL, NULL);
	if(e < 0) {
	    if(errno != EINTR)
		krb5_warn(context, errno, "select");
	} else if(e == 0)
	    krb5_warnx(context, "select returned 0");
	else {
	    for(i = 0; i < num_socks; i++) {
		if(FD_ISSET(socks[i], &read_set))
		    if(spawn_child(context, socks, num_socks, i) == 0)
			return 0;
	    }
	}
    }
    signal(SIGCHLD, SIG_IGN);
    while(1) {
	int status;
	pid_t pid;
	pid = waitpid(-1, &status, 0);
	if(pid == -1 && errno == ECHILD)
	    break;
    }
    exit(0);
}
コード例 #9
0
static int spawn_curl(const char* url) {
    char **argv = STRV_MAKE("curl",
                            "-HAccept: application/vnd.fdo.journal",
                            "--silent",
                            "--show-error",
                            url);
    int r;

    r = spawn_child("curl", argv);
    if (r < 0)
        log_error_errno(errno, "Failed to spawn curl: %m");
    return r;
}
コード例 #10
0
ファイル: scgi.c プロジェクト: dengzhp/cSCGI
void init_scgi(struct scgi_server *server, unsigned short port,
	       int max_children, struct scgi_handler *handler)
{
	server->listen_port = port;
	server->max_children = max_children;

	server->children.first = NULL;
	server->children.last = &server->children.first;
	server->children.size = 0;

	server->handler = handler;

	spawn_child(server, -1);
}
コード例 #11
0
static int spawn_getter(const char *getter, const char *url) {
    int r;
    _cleanup_strv_free_ char **words = NULL;

    assert(getter);
    r = strv_split_quoted(&words, getter, false);
    if (r < 0)
        return log_error_errno(r, "Failed to split getter option: %m");

    r = strv_extend(&words, url);
    if (r < 0)
        return log_error_errno(r, "Failed to create command line: %m");

    r = spawn_child(words[0], words);
    if (r < 0)
        log_error_errno(errno, "Failed to spawn getter %s: %m", getter);

    return r;
}
コード例 #12
0
ファイル: aeternum.c プロジェクト: 4nodejs/aeternum
void spawn_cb(uv_process_t *req, int exit_status, int signal_status) {
  struct timeval tv;
  int ms_up;

  if (opts.min_uptime != 0) {
    gettimeofday(&tv, NULL);
    ms_up = ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) -
            ((start_tv.tv_sec * 1000) + (start_tv.tv_usec / 1000));

    if (ms_up < opts.min_uptime) {
      fprintf(stderr, "Child exited prematurely with %d, exiting.\n", exit_status);
      exit(2);
    }
  }

  if (signal_status) {
    fprintf(stderr, "Child killed by signal %d, restarting.\n", signal_status);
  }
  else {
    fprintf(stderr, "Child exited with %d, restarting.\n", exit_status);
  }
  spawn_child(0);
}
コード例 #13
0
int
run_main (int argc, ACE_TCHAR *argv[])
{
#if defined (ACE_HAS_WIN32_PRIORITY_CLASS)
  ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("dp:"));
#else
  ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("d"));
#endif
  int opt;
  while ((opt = get_opt ()) != EOF)
    {
      switch (opt)
        {
          case 'd':
            debug_test = 1u;
            break;
#if defined (ACE_HAS_WIN32_PRIORITY_CLASS)
          case 'p':
            process_id = ACE_OS::atoi (get_opt.opt_arg ());
            break;
#endif
        }
    }

  if (get_opt.opt_ind () == argc - 1)
    {
      // child process: sleep & exit
      ACE_TCHAR lognm[MAXPATHLEN];
      int const mypid (ACE_OS::getpid ());
      ACE_OS::snprintf (lognm, MAXPATHLEN,
                        ACE_TEXT ("Process_Manager_Test-child-%d"), mypid);

      ACE_START_TEST (lognm);
      int const secs = ACE_OS::atoi (argv[get_opt.opt_ind ()]);
      ACE_OS::sleep (secs ? secs : 1);

      ACE_TCHAR prio[64];
#if defined (ACE_WIN32_HAS_PRIORITY_CLASS)
      DWORD priority = ::GetPriorityClass (::GetCurrentProcess());

      check_process_priority(priority);

      if (priority == ABOVE_NORMAL_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'above normal'"));
      else if (priority == BELOW_NORMAL_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'below normal'"));
      else if (priority == HIGH_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'high'"));
      else if (priority == IDLE_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'idle'"));
      else if (priority == NORMAL_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'normal'"));
      else if (priority == REALTIME_PRIORITY_CLASS)
        ACE_OS::snprintf (prio, 64, ACE_TEXT ("and priority 'realtime'"));
#else
      prio[0] = ACE_TEXT ('\0');
#endif
      if (debug_test)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%T: pid %P about to exit with code %d %s\n"),
                    secs,
                    prio));
      ACE_END_LOG;

      return secs;
    }

  if (get_opt.opt_ind () != argc)      // incorrect usage
    usage (argv[0]);

  ACE_START_TEST (ACE_TEXT ("Process_Manager_Test"));

  int test_status = 0;

#ifdef ACE_HAS_PROCESS_SPAWN

  int result = 0;
  if ((result = command_line_test ()) != 0)
    test_status = result;

  // Try the explicit <ACE_Process_Manager::wait> functions

  ACE_Process_Manager mgr;

  mgr.register_handler (new Exit_Handler ("default"));

  ACE_exitcode exitcode;

  // --------------------------------------------------
  // wait for a specific PID
  pid_t child1 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              1,
                              1);
  result = mgr.wait (child1,
                     &exitcode);

  if (result != child1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) Error: expected to reap child1 (%d); got %d\n"),
                  child1,
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) reaped child1, pid %d: %d\n"),
                child1,
                exitcode));

  // --------------------------------------------------
  // wait for a specific PID; another should finish first
  pid_t child2 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              1,
                              2);
  pid_t child3 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              4,
                              3);
  result = mgr.wait (child3,
                     &exitcode);

  if (result != child3)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) Error: expected to reap child3 (%d); got %d\n"),
                  child3,
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) reaped child 3, pid %d: %d\n"),
                child3,
                exitcode));

  // Now wait for any...should get the one that finished earlier.

  result = mgr.wait (0, &exitcode);

  if (result != child2)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) Error: expected to reap child2 (%d); got %d\n"),
                  child2,
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) reaped child 2, pid %d: %d\n"),
                result,
                exitcode));

  // --------------------------------------------------
  // Try the timed wait functions

  // This one shouldn't timeout:
  pid_t child4 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              1,
                              4);
#if defined (ACE_HAS_CPP11)
  result = mgr.wait (0, std::chrono::seconds (4), &exitcode);
#else
  result = mgr.wait (0, ACE_Time_Value (4), &exitcode);
#endif

  if (result != child4)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) Error: expected to reap child4 (%d); got %d\n"),
                  child4,
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) reaped child 4 pid %d: %d\n"),
                result,
                exitcode));

  // This one should timeout:
  pid_t child5 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              4,
                              5);
  result = mgr.wait (0, ACE_Time_Value (1), &exitcode);
  if (result != 0)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) Error: expected wait to time out; got %d\n"),
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) Correctly timed out wait at child 5\n")));

  // Now wait indefinitely to clean up...
  result = mgr.wait (0, &exitcode);

  if (result != child5)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("Error: expected to reap child5 pid %d; got %d\n"),
                  child5,
                  result));
      if (result == ACE_INVALID_PID)
        ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("error")));
      test_status = 1;
    }
  else
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P) reaped child 5, pid %d: %d\n"),
                result,
                exitcode));

  // Terminate a child process and make sure we can wait for it.
  pid_t child6 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              5,
                              6);
  ACE_exitcode status6;
  if (-1 == mgr.terminate (child6))
    {
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P) %p\n"), ACE_TEXT ("terminate child6")));
      test_status = 1;
      mgr.wait (child6, &status6);  // Wait for child to exit just to clean up
    }
  else
    {
      if (-1 == mgr.wait (child6, &status6))
        {
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("(%P) wait on child6 reported ACE_INVALID_PID\n")));
          test_status = 1;
        }
      else
        {
          // Get the results of the termination.
#if !defined(ACE_WIN32)
          if (WIFSIGNALED (status6) != 0)
            ACE_DEBUG ((LM_DEBUG,
                        ACE_TEXT ("(%P) child6 died on signal %d - correct\n"),
                        WTERMSIG (status6)));
          else
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("(%P) child6 should have died on signal, ")
                        ACE_TEXT ("but didn't; exit status %d\n"),
                        WEXITSTATUS (status6)));
#else
          ACE_DEBUG
            ((LM_DEBUG,
              ACE_TEXT ("(%P) The process terminated with exit code %d\n"),
              status6));
#endif /*ACE_WIN32*/
        }
    }

#ifdef ACE_HAS_THREADS
  Process_Task task1 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 3);
  Process_Task task2 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 2);
  Process_Task task3 (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"), mgr, 1);
  task1.open (0);
  task2.open (0);
  task3.open (0);

  while (running_tasks!=0)
    {
      ACE_OS::sleep (1);
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) still running tasks\n")));
    }

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("(%P) result: '%C'\n"),
              order.c_str ()));

  if (order != "321123")
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P) wrong order of spawns ('%C', should be '321123')\n"),
                  order.c_str ()));
      test_status = 1;
    }
#endif /* ACE_HAS_THREADS */

#if !defined (ACE_OPENVMS) && \
  (defined ACE_WIN32 || !defined ACE_LACKS_UNIX_SIGNALS)
  // --------------------------------------------------
  // Finally, try the reactor stuff...
  mgr.open (ACE_Process_Manager::DEFAULT_SIZE,
            ACE_Reactor::instance ());

  pid_t child7 = spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                              mgr,
                              5,
                              7);
  /* pid_t child8 = */ spawn_child (argc > 0 ? argv[0] : ACE_TEXT ("Process_Manager_Test"),
                                    mgr,
                                    6,
                                    0);

  mgr.register_handler (new Exit_Handler ("specific"),
                        child7);

  ACE_Time_Value how_long (10);

  ACE_Reactor::instance ()->run_reactor_event_loop (how_long);

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("(%P) Reactor loop done!\n") ));

  size_t const nr_procs = mgr.managed ();
  if (nr_procs != 0)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("(%P) %d processes left in manager\n"),
                nr_procs));
#endif /* !defined (ACE_OPENVMS) */
#endif // ACE_HAS_PROCESS_SPAWN
  ACE_END_TEST;
  return test_status;
}
コード例 #14
0
ファイル: aeternum.c プロジェクト: 4nodejs/aeternum
int main(int argc, char *argv[]) {
  int r;
  saneopt_t* opt;
  char** args;
  char* min_uptime;

  signal(SIGHUP, SIG_IGN);
  signal(SIGINT, handle_signal);
  signal(SIGTERM, handle_signal);
  signal(SIGUSR1, restart_child);

  loop = uv_default_loop();

  if (argc == 1) {
    printf("Usage: aeternum [action] [options] -- program\n");
    return 1;
  }

  opt = saneopt_init(argc - 1, argv + 1);
  args = saneopt_arguments(opt);

  if (strcmp(args[0], "start") == 0) {
    argv[1] = "run";

    opts.infile = NULL;
    opts.outfile = NULL;
    opts.errfile = NULL;
    opts.pidname = NULL;
    opts.min_uptime = 0;
    opts.target = argv[0];
    opts.json = 0;
    opts.child_args = argv;

    spawn_child(1);
    printf("%d\n", child_req.pid);
    return 0;
  }

  opts.infile = saneopt_get(opt, "i");
  opts.outfile = saneopt_get(opt, "o");
  opts.errfile = saneopt_get(opt, "e");
  opts.pidname = saneopt_get(opt, "p");
  opts.json = (saneopt_get(opt, "j") != NULL) ? 1 : 0;
  opts.target = args[1];
  opts.child_args = &args[1];

  min_uptime = saneopt_get(opt, "min-uptime");
  if (min_uptime != NULL) {
    sscanf(min_uptime, "%d", &opts.min_uptime);
    gettimeofday(&start_tv, NULL);

  }
  else {
    opts.min_uptime = 0;
  }

  configure_stdio();

  spawn_child(0);

  r = uv_run(loop, UV_RUN_DEFAULT);

  return r;
}
コード例 #15
0
ファイル: scgi.c プロジェクト: dengzhp/cSCGI
static int delegate_request(struct scgi_server *server, int conn)
{
	fd_set fds;
	int highest_fd, r;
	struct child *child;
	struct timeval timeout;
	char magic;

	timeout.tv_usec = 0;
	timeout.tv_sec = 0;

	while (1) {
		highest_fd = fill_children_fdset(&server->children, &fds);
		r = select(highest_fd + 1, &fds, NULL, NULL, &timeout);
		if (r < 0) {
			if (errno == EINTR) {
				continue;
			} else {
				die("select error");
			}
		} else if (r > 0) {
			/*  One or more children look like they are ready.
			    Do the same walk order so that we keep preferring
			    the same child.
			*/
			child = get_ready_child(&server->children, &fds);
			if (child == NULL) {
				/* should never get here */
				fputs("Ooops\n", stderr);
				continue;
			}

			/*
			  Try to read the single byte written by the child.
			  This can fail if the child died or the pipe really
			  wasn't ready (select returns a hint only).  The fd has
			  been made non-blocking by spawn_child.  If this fails
			  we fall through to the "reap_children" logic and will
			  retry the select call.
			*/

			r = read(child->fd, &magic, 1);
			if (r == -1 && errno != EAGAIN) {
				die("read byte error");
			} else if (r == 1) {
				assert(magic == '1');
				/*
				  The byte was read okay, now we need to pass the fd
				  of the request to the child.  This can also fail
				  if the child died.  Again, if this fails we fall
				  through to the "reap_children" logic and will
				  retry the select call.
				*/
				if (send_fd(child->fd, conn) == -1 && errno != EPIPE) {
					die("sendfd error");
				} else {
					/*
					  fd was apparently passed okay to the child.
					  The child could die before completing the
					  request but that's not our problem anymore.
					*/
					return 0;
				}
			}
		}

		/* didn't find any child, check if any died */
		reap_children(server);

		/* start more children if we haven't met max_children limit */
		if (server->children.size < server->max_children)
			spawn_child(server, conn);

		/* Start blocking inside select.  We might have reached
		   max_children limit and they are all busy.
		*/
		timeout.tv_sec = 2;

	} /* end of while */

	return 0;
}
コード例 #16
0
ファイル: multi-oom.c プロジェクト: dahun0428/Pintos
/* The first copy is invoked without command line arguments.
   Subsequent copies are invoked with a parameter 'depth'
   that describes how many parent processes preceded them.
   Each process spawns one or multiple recursive copies of
   itself, passing 'depth+1' as depth.

   Some children are started with the '-k' flag, which will
   result in abnormal termination.
 */
int
main (int argc, char *argv[])
{
  int n;

  n = argc > 1 ? atoi (argv[1]) : 0;
  bool is_at_root = (n == 0);
  if (is_at_root)
    msg ("begin");

  /* If -k is passed, crash this process. */
  if (argc > 2 && !strcmp(argv[2], "-k"))
    {
      consume_some_resources_and_die (n);
      NOT_REACHED ();
    }

  int howmany = is_at_root ? EXPECTED_REPETITIONS : 1;
  int i, expected_depth = -1;

  for (i = 0; i < howmany; i++)
    {
      pid_t child_pid;

      /* Spawn a child that will be abnormally terminated.
         To speed the test up, do this only for processes
         spawned at a certain depth. */
      if (n > EXPECTED_DEPTH_TO_PASS/2)
        {
          child_pid = spawn_child (n + 1, CRASH);
          if (child_pid != -1)
            {
              if (wait (child_pid) != -1)
                fail ("crashed child should return -1.");
            }
          /* If spawning this child failed, so should
             the next spawn_child below. */
        }

      /* Now spawn the child that will recurse. */
      child_pid = spawn_child (n + 1, RECURSE);

      /* If maximum depth is reached, return result. */
      if (child_pid == -1)
        return n;
      
      /* Else wait for child to report how deeply it was able to recurse. */
      int reached_depth = wait (child_pid);
      if (reached_depth == -1)
        fail ("wait returned -1.");

      /* Record the depth reached during the first run; on subsequent
         runs, fail if those runs do not match the depth achieved on the
         first run. */
      if (i == 0)
        expected_depth = reached_depth;
      else if (expected_depth != reached_depth)
        fail ("after run %d/%d, expected depth %d, actual depth %d.",
              i, howmany, expected_depth, reached_depth);
      ASSERT (expected_depth == reached_depth);
    }

  consume_some_resources ();

  if (n == 0)
    {
      if (expected_depth < EXPECTED_DEPTH_TO_PASS)
        fail ("should have forked at least %d times.", EXPECTED_DEPTH_TO_PASS);
      msg ("success. program forked %d times.", howmany);
      msg ("end");
    }

  return expected_depth;
}
コード例 #17
0
ファイル: linkshare.c プロジェクト: Maffblaster/libhugetlbfs
int main(int argc, char *argv[], char *envp[])
{
	test_init(argc, argv);

	if (argc == 1) {
		/*
		 * first process
		 */
		pid_t children_pids[NUM_CHILDREN];
		int ret, i;
		int status;
		/*
		 * We catch children's segfaults via waitpid's status,
		 * but this is to catch the parent itself segfaulting.
		 * This can happen, for instance, if an old (bad)
		 * segment file is left lying around in the hugetlbfs
		 * mountpoint
		 */
		struct sigaction sa_seg = {
			.sa_sigaction = sigsegv_handler,
			.sa_flags = SA_SIGINFO,
		};

		parse_env();

		ret = sigaction(SIGSEGV, &sa_seg, NULL);
		if (ret < 0)
			FAIL("Installing SIGSEGV handler failed: %s",
							strerror(errno));

		shmid = shmget(SHM_KEY, NUM_CHILDREN * NUM_TESTS *
					sizeof(ino_t), IPC_CREAT | IPC_EXCL |
					0666);
		if (shmid < 0)
			FAIL("Parent's shmget failed: %s", strerror(errno));

		shm = shmat(shmid, NULL, 0);
		if (shm == (void *)-1)
			FAIL("Parent's shmat failed: %s", strerror(errno));

		for (i = 0; i < NUM_CHILDREN; i++)
			children_pids[i] = spawn_child(argv[0], i);

		for (i = 0; i < NUM_CHILDREN; i++) {
			ret = waitpid(children_pids[i], &status, 0);
			if (ret < 0) {
				shmctl(shmid, IPC_RMID, NULL);
				shmdt(shm);
				FAIL("waitpid failed: %s", strerror(errno));
			}

			if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
				shmctl(shmid, IPC_RMID, NULL);
				shmdt(shm);
				FAIL("Child %d exited with non-zero status: %d",
							i + 1, WEXITSTATUS(status));
			}

			if (WIFSIGNALED(status)) {
				shmctl(shmid, IPC_RMID, NULL);
				shmdt(shm);
				FAIL("Child %d killed by signal: %s", i + 1,
							strsignal(WTERMSIG(status)));
			}
		}

		verify_inodes();

		shmctl(shmid, IPC_RMID, NULL);
		shmdt(shm);
		PASS();
	} else {
コード例 #18
0
ファイル: afterstep.c プロジェクト: cooljeanius/AfterStep
void
Done (Bool restart, char *command )
{
    int restart_screen = get_flags( AfterStepState, ASS_SingleScreen)?Scr.screen:-1;
	Bool restart_self = False ; 
    char *local_command = NULL ;
	{
		static int already_dead = False ; 
		if( already_dead ) 	return;/* non-reentrant function ! */
		already_dead = True ;
	}

    /* lets duplicate the string so we don't accidental;y delete it while closing self down */
    if( restart )
	{
		int my_name_len = strlen(MyName);
		if( command ) 
		{
			if( strncmp(command, MyName, my_name_len )==0 )
				restart_self = (command[my_name_len] == ' '|| command[my_name_len] == '\0');
			local_command = mystrdup(command);
		}else 
		{		  
        	local_command = mystrdup(MyName);
			restart_self = True ;
	    }
		if (!is_executable_in_path(local_command))
		{
			if (!restart_self || MyArgs.saved_argv[0] == NULL)
			{
				show_error("Cannot restart with command \"%s\" - application is not in PATH!", local_command);
				return;
			}
			free(local_command);
			if (command)
			{
				local_command = safemalloc(strlen(command) + 1+ strlen(MyArgs.saved_argv[0])+1);
				sprintf( local_command, "%s %s", MyArgs.saved_argv[0], command + my_name_len);
			}else
				local_command = mystrdup(MyArgs.saved_argv[0]);
		}
	}


#ifdef XSHMIMAGE
	/* may not need to do that as server may still have some of the shared 
	 * memory and work in it */
	flush_shm_cache();
#endif

LOCAL_DEBUG_CALLER_OUT( "%s restart, cmd=\"%s\"", restart?"Do":"Don't", command?command:"");

	XSelectInput( dpy, Scr.Root, 0 );	   
	SendPacket (-1, M_SHUTDOWN, 0);
	FlushAllQueues(); 
	sleep_a_millisec(1000);

	LOCAL_DEBUG_OUT( "local_command = \"%s\", restart_self = %s", local_command, restart_self?"Yes":"No"); 
    set_flags( AfterStepState, ASS_Shutdown );
    if( restart )
        set_flags( AfterStepState, ASS_Restarting );
    clear_flags( AfterStepState, ASS_NormalOperation );
#ifndef NO_VIRTUAL
    MoveViewport (0, 0, False);
#endif
#ifndef NO_SAVEWINDOWS
	if (!restart)
    {
        char *fname = make_session_file( Session, AFTER_SAVE, False );
        save_aswindow_list( Scr.Windows, NULL );
        free( fname );
    }
#endif

	/* Close all my pipes */
    ShutdownModules(False);

    desktop_cover_cleanup();
    
	/* remove window frames */
    CleanupScreen();
    /* Really make sure that the connection is closed and cleared! */
    XSync (dpy, 0);

	if (ASDBus_fd>=0)
		asdbus_shutdown();

#ifdef XSHMIMAGE
	flush_shm_cache();
#endif
	if (restart)
	{
		set_flags( MyArgs.flags, ASS_Restarting );
        spawn_child( local_command, -1, restart_screen, original_DISPLAY_string,
                     None, C_NO_CONTEXT, False, restart_self, NULL );
    } else
	{

	    XCloseDisplay (dpy);
		dpy = NULL ;

		/* freeing up memory */
		DestroyPendingFunctionsQueue();
		DestroyCategories();

	    cleanup_default_balloons();
		destroy_asdatabase();
    	destroy_assession( Session );
		destroy_asenvironment( &Environment );
    	/* pixmap references */
    	build_xpm_colormap (NULL);

		free_scratch_ids_vector();
		free_scratch_layers_vector();		
        clientprops_cleanup ();
        wmprops_cleanup ();

        free_func_hash();
		flush_keyword_ids();
        purge_asimage_registry();
	
		asxml_var_cleanup();
		custom_color_cleanup(); 

        free_as_app_args();
		free( ASDefaultScr );

		flush_default_asstorage();
        flush_asbidirlist_memory_pool();
        flush_ashash_memory_pool();
#ifdef DEBUG_ALLOCS
        print_unfreed_mem ();
#endif /*DEBUG_ALLOCS */
#ifdef XSHMIMAGE
		flush_shm_cache();
#endif
    
	}
    exit(0);
}
コード例 #19
0
ファイル: sigio1.c プロジェクト: Tolchi/misc
int main(int argc, char *argv[]) {
  int fd[2], rc, n;
  char buf[100];

  pipe(fd);
  spawn_child(fd,"hello\n","world\n");
  close(fd[1]);

  /* request SIGIO to our pid when fd[0] is ready; see fcntl(2) */
  int fl = fcntl(fd[0], F_GETFL);
  fl |= O_ASYNC | O_NONBLOCK;
  fcntl(fd[0], F_SETFL, fl);
  fcntl(fd[0], F_SETOWN, getpid()); 

  /* block all signals. we stay blocked always except in sugsuspend */
  sigset_t all;
  sigfillset(&all);
  sigprocmask(SIG_SETMASK,&all,NULL);

  /* a smaller set of signals we'll block during sigsuspend */
  sigset_t ss;
  sigfillset(&ss);
  for(n=0; n < sizeof(sigs)/sizeof(*sigs); n++) sigdelset(&ss, sigs[n]);

  /* establish handlers for signals that'll be unblocked in sigsuspend */
  struct sigaction sa;
  sa.sa_handler=sighandler;  /* no fd information (not sa_sigaction)  */
  sa.sa_flags=0;             /* no extra information (not SA_SIGINFO* */
  sigfillset(&sa.sa_mask);
  for(n=0; n < sizeof(sigs)/sizeof(*sigs); n++) sigaction(sigs[n], &sa, NULL);

  /* here is a special line. we'll come back here whenever a signal happens */
  int signo = sigsetjmp(jmp,1);

  switch (signo) {
    case 0:
      /* initial setup. no signal yet */
      break;
    case SIGCHLD:
      /* this can happen before we get the last SIGIO,
         so fall through to grab any final pipe content */
      printf("got sigchld\n");
    case SIGIO:
      rc = read(fd[0], buf, sizeof(buf));
      if (rc > 0) printf("read: %.*s", rc, buf);
      else if (rc == 0) { close(fd[0]); goto done; }
      else if (rc == -1) {perror("read error"); close(fd[0]);}
      break;
    default:
      printf("got signal %d\n", signo);
      goto done;
      break;
  }

  /* wait for signals */
  sigsuspend(&ss);

  /* the only way we get past this point
   * is from the "goto done" above, because
   * sigsuspend waits for signals, and when
   * one arrives we longjmp back to sigsetjmp! */

done:
  return 0;
}
コード例 #20
0
// token recovery
void token_recovery(int event_rec) {
  int           error = 0;
  u_int         nbytes, ntokens = 0, ret_ntokens, i;
  dm_token_t    *tokenbuf = NULL, *tokenptr;
  size_t        buflen=0, ret_buflen;
  char          *msgbuf = NULL;
  dm_eventmsg_t *msg;
  void            *hanp;
  size_t           hlen;
  dm_data_event_t *msgev; 

  // Initial sizes for the token and message buffers
  ret_buflen=16*(sizeof(dm_eventmsg_t)+sizeof(dm_data_event_t)+HANDLE_LEN);
  ret_ntokens = 16;

  // get the list of tokens
  do {
    dm_token_t *tmpbuf;
    ntokens = (ntokens != ret_ntokens) ? ret_ntokens : ntokens*2;
    nbytes = ntokens * (sizeof(dm_token_t) + sizeof(dm_vardata_t));
    tmpbuf = realloc(tokenbuf, nbytes);
    if (tmpbuf == NULL) {
      fprintf(stderr,"Can't malloc %d bytes for tokenbuf\n", nbytes);
      exit_program(0);
    }

    tokenbuf = tmpbuf;
    error = dm_getall_tokens(sid, ntokens, tokenbuf, &ret_ntokens);
  } while (error && errno == E2BIG);

  if (error) {
    fprintf(stderr,"Can't get all outstanding tokens\n");
    exit_program(0);
  }

  tokenptr = tokenbuf;
  for (i = 0; i < ret_ntokens; i++) {

    do {
      char *tmpbuf;
      buflen = (buflen != ret_buflen) ? ret_buflen : buflen * 2;
      tmpbuf = realloc(msgbuf, buflen);
      if (tmpbuf == NULL) {
        fprintf(stderr,"Can't malloc %lu bytes for msgbuf\n", (long unsigned int)buflen);
        exit_program(0);
      }
      msgbuf = tmpbuf;
      error = dm_find_eventmsg(sid, *tokenptr, buflen, msgbuf, &ret_buflen);
    } while (error && errno == E2BIG);
    if (error) {
      fprintf(stderr,"Can't find the event message for token %llu %llu\n", tokenptr->high,tokenptr->low);
      exit_program(0);
    }

    msg = (dm_eventmsg_t *) msgbuf;
    while (msg != NULL) {
      // get file handle 
      msgev  = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
      hanp = DM_GET_VALUE(msgev, de_handle, void *);
      hlen = DM_GET_LEN(msgev, de_handle);

      if(event_rec==msg->ev_type) {
        if (Verbose)
          fprintf(stderr,"Recovering outstanding event for token %llu %llu\n",tokenptr->high,tokenptr->low);

        switch (msg->ev_type) {
           case DM_EVENT_MOUNT:
           spawn_child(msg->ev_token, hanp, hlen, "MOUNT");
           break;
         case DM_EVENT_READ:
           spawn_child(msg->ev_token, hanp, hlen, "READ");
           break;
         case DM_EVENT_WRITE:
           spawn_child(msg->ev_token, hanp, hlen, "WRITE");
           break;
         case DM_EVENT_TRUNCATE:
           spawn_child(msg->ev_token, hanp, hlen, "TRUNC");
           break;
         default:
           fprintf(stderr,"Invalid msg type %d\n", msg->ev_type);
           break;
        }
      }
      // go to next event
      msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
    }

    tokenptr++;
  }

  if (tokenbuf) free(tokenbuf);
  if (msgbuf) free(msgbuf);

}
コード例 #21
0
// main event loop
void event_loop() {
  void *msgbuf;
  size_t bufsize, rlen;
  int error;
  dm_eventmsg_t *msg;
  pid_t process_id;

  void *hanp;
  size_t hlen;
  dm_data_event_t *msgev;

  int first_time=1;

  // define inizial message buffer size
  bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN;
  bufsize *= 16;
  msgbuf  = (void *)malloc(bufsize);
  if (msgbuf == NULL) {
    fprintf(stderr,"Can't allocate memory for buffer\n");
    goto out;
  }

  // start infinite loop
  for (;;) {
    // cleanup all finished children
    while (child_proc_count) {
      process_id = waitpid((pid_t) -1, NULL, WNOHANG);
      if (process_id < 0) { // waitpid error
        fprintf(stderr, "cannot waitpid\n");
        exit(1);
      } else if (process_id == 0)  break; // no child to wait
      else {
        child_proc_count--;  // cleaned up one child
        if(Verbose) {
           fprintf(stderr,"Cleanup child with pid %d\n",process_id);
        }
      }
    }

    // if initialization is not finished, try to finalize
    if(global_state==1) finalize_init();

    // check if filesystem is mounted, otherwise exit
    if(global_state==2&&!filesystem_is_mounted()) exit_program(0);

    // sleep for MAIN_LOOP_SLEEP_TIME mus
    usleep(MAIN_LOOP_SLEEP_TIME);

    // check if maximum number of children has been reached
    if(child_proc_count>=MAXIMUM_ALLOWED_CHILDREN) {
      if(first_time) printf("Maximum number of children reached %d/%d\n",child_proc_count,MAXIMUM_ALLOWED_CHILDREN);
      first_time=0;
      continue;
    }

    if(!first_time) {
      printf("Number of children back to normality %d/%d\n",child_proc_count,MAXIMUM_ALLOWED_CHILDREN);
      first_time=1;
    }

    // get MAXIMUM_MESSAGES available event messages with unblocking call
    error = dm_get_events(sid, MAXIMUM_MESSAGES, 0, bufsize, msgbuf, &rlen);
    if (error == -1) {
      if (errno == E2BIG) {
        // message buffer was too small, enlarge it
        free(msgbuf);
        msgbuf = (void *)malloc(rlen);
        if (msgbuf == NULL) {
          fprintf(stderr,"Can't resize msg buffer\n");
          goto out;
        }
        continue;
      }
      // we got an error while getting events, or simply there were no events
      // for the moment continue, but should improve error handling here
      continue;
    }

    // examine each message and dispatch children to manage events and respond to client
    msg = (dm_eventmsg_t *)msgbuf;
    while (msg != NULL ) {
      if (Verbose) {
        fprintf(stderr, "Received %s, sid %llx token %llx %llx\n", (msg->ev_type == DM_EVENT_READ ? "READ" : 
                                                         (msg->ev_type == DM_EVENT_WRITE ? "WRITE" : (msg->ev_type == DM_EVENT_TRUNCATE ? "TRUNCATE" : "MOUNT"))), 
                                                         sid, msg->ev_token.high, msg->ev_token.low);
      }

      // get file handle 
      msgev  = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
      hanp = DM_GET_VALUE(msgev, de_handle, void *);
      hlen = DM_GET_LEN(msgev, de_handle);
     
      switch (msg->ev_type) {
         case DM_EVENT_MOUNT:
           spawn_child(msg->ev_token, hanp, hlen, "MOUNT");
           break;
         case DM_EVENT_READ:
           spawn_child(msg->ev_token, hanp, hlen, "READ");
           break;
         case DM_EVENT_WRITE:
           spawn_child(msg->ev_token, hanp, hlen, "WRITE");
           break;
         case DM_EVENT_TRUNCATE:
           spawn_child(msg->ev_token, hanp, hlen, "TRUNC");
           break;
         default:
           fprintf(stderr,"Invalid msg type %d\n", msg->ev_type);
           break;
      }
      // go to next event
      msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *);
    }
  }

out:
  if (msgbuf != NULL) free(msgbuf);
  exit_program(0);
}
コード例 #22
0
ファイル: redir.cpp プロジェクト: movsb/concon
bool redir_t::open(LPCTSTR cmdline, LPCTSTR working_directory)
{
	HANDLE h_stdout_read_tmp = nullptr;
	HANDLE h_stdout_write = nullptr, h_stderr_write = nullptr;
	HANDLE h_stdin_write_tmp = nullptr;
	HANDLE h_stdin_read = nullptr;

	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = nullptr;
	sa.bInheritHandle = TRUE;

	try{
		if(!::CreatePipe(&h_stdout_read_tmp, &h_stdout_write, &sa, 0))
			throw "[error] CreatePipe failed.";

		if(!::DuplicateHandle(GetCurrentProcess(), h_stdout_write,
			GetCurrentProcess(), &h_stderr_write,
			0, TRUE, DUPLICATE_SAME_ACCESS))
		{
			throw "[error] DuplicateHandle failed.";
		}

		if(!::CreatePipe(&h_stdin_read, &h_stdin_write_tmp, &sa, 0))
			throw "[error] CreatePipe failed.";

		if(!::DuplicateHandle(GetCurrentProcess(), h_stdout_read_tmp,
			::GetCurrentProcess(), &_h_stdout_read,
			0, FALSE, DUPLICATE_SAME_ACCESS))
		{
			throw "[error] DuplicateHandle failed.";
		}

		if(!::DuplicateHandle(::GetCurrentProcess(), h_stdin_write_tmp,
			::GetCurrentProcess(), &_h_stdin_write,
			0, FALSE, DUPLICATE_SAME_ACCESS))
		{
			throw "[error] DuplicateHandle failed.";
		}

		close_handle(h_stdout_read_tmp);
		close_handle(h_stdin_write_tmp);

		if(!spawn_child(cmdline, h_stdout_write, h_stdin_read, h_stderr_write, working_directory))
			throw "[error] spawn_child failed.";

		close_handle(h_stdout_write);
		close_handle(h_stdin_read);
		close_handle(h_stderr_write);

		_h_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
		_h_thread = ::CreateThread(nullptr, 0, thread_output, this, 0, &_dw_thread_id);

		if(!_h_event || !_h_thread)
			throw "[error] CreateEvent or CreateThread failed.";
	}
	catch(...) {
		throw;
	}

	return true;
}
コード例 #23
0
ファイル: mpmt_os2.c プロジェクト: kheradmand/Break
/* Main processing of the parent process
 * returns TRUE if restarting
 */
static char master_main()
{
    server_rec *s = ap_server_conf;
    ap_listen_rec *lr;
    parent_info_t *parent_info;
    char *listener_shm_name;
    int listener_num, num_listeners, slot;
    ULONG rc;

    printf("%s \n", ap_get_server_version());
    set_signals();

    if (ap_setup_listeners(ap_server_conf) < 1) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                     "no listening sockets available, shutting down");
        return FALSE;
    }

    /* Allocate a shared memory block for the array of listeners */
    for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) {
        num_listeners++;
    }

    listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid());
    rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name,
                           sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t),
                           PAG_READ|PAG_WRITE|PAG_COMMIT);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure allocating shared memory, shutting down");
        return FALSE;
    }

    /* Store the listener sockets in the shared memory area for our children to see */
    for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) {
        apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd);
    }

    /* Create mutex to prevent multiple child processes from detecting
     * a connection with apr_poll()
     */

    rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure creating accept mutex, shutting down");
        return FALSE;
    }

    parent_info->accept_mutex = ap_mpm_accept_mutex;

    /* Allocate shared memory for scoreboard */
    if (ap_scoreboard_image == NULL) {
        void *sb_mem;
        rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname,
                               ap_calc_scoreboard_size(),
                               PAG_COMMIT|PAG_READ|PAG_WRITE);

        if (rc) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                         "unable to allocate shared memory for scoreboard , exiting");
            return FALSE;
        }

        ap_init_scoreboard(sb_mem);
    }

    ap_scoreboard_image->global->restart_time = apr_time_now();
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		"%s configured -- resuming normal operations",
		ap_get_server_version());
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
		"Server built: %s", ap_get_server_built());
#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
		"AcceptMutex: %s (default: %s)",
		apr_proc_mutex_name(accept_mutex),
		apr_proc_mutex_defname());
#endif
    if (one_process) {
        ap_scoreboard_image->parent[0].pid = getpid();
        ap_mpm_child_main(pconf);
        return FALSE;
    }

    while (!restart_pending && !shutdown_pending) {
        RESULTCODES proc_rc;
        PID child_pid;
        int active_children = 0;

        /* Count number of active children */
        for (slot=0; slot < HARD_SERVER_LIMIT; slot++) {
            active_children += ap_scoreboard_image->parent[slot].pid != 0 &&
                !ap_scoreboard_image->parent[slot].quiescing;
        }

        /* Spawn children if needed */
        for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) {
            if (ap_scoreboard_image->parent[slot].pid == 0) {
                spawn_child(slot);
                active_children++;
            }
        }

        rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0);

        if (rc == 0) {
            /* A child has terminated, remove its scoreboard entry & terminate if necessary */
            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++);

            if (slot < HARD_SERVER_LIMIT) {
                ap_scoreboard_image->parent[slot].pid = 0;
                ap_scoreboard_image->parent[slot].quiescing = 0;

                if (proc_rc.codeTerminate == TC_EXIT) {
                    /* Child terminated normally, check its exit code and
                     * terminate server if child indicates a fatal error
                     */
                    if (proc_rc.codeResult == APEXIT_CHILDFATAL)
                        break;
                }
            }
        } else if (rc == ERROR_CHILD_NOT_COMPLETE) {
            /* No child exited, lets sleep for a while.... */
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
        }
    }

    /* Signal children to shut down, either gracefully or immediately */
    for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
      kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
    }

    DosFreeMem(parent_info);
    return restart_pending;
}
コード例 #24
0
ファイル: afterstep.c プロジェクト: cooljeanius/AfterStep
/***********************************************************************
 *  Procedure:
 *	main - start of afterstep
 ************************************************************************/
int
main (int argc, char **argv, char **envp)
{
    register int i ;
	
	int start_viewport_x = 0 ;
	int start_viewport_y = 0 ;
	int start_desk = 0 ;

#ifdef LOCAL_DEBUG
#if 0
	LOCAL_DEBUG_OUT( "calibrating sleep_a_millisec : %s","" );
	for( i = 0 ; i < 500 ; ++i )
		sleep_a_millisec( 10 );
	LOCAL_DEBUG_OUT( "500 sliip_a_millisec(10) completed%s","" );
	for( i = 0 ; i < 50 ; ++i )
		sleep_a_millisec( 100 );
	LOCAL_DEBUG_OUT( "50 sliip_a_millisec(100) completed%s","" );
	for( i = 0 ; i < 10 ; ++i )
		sleep_a_millisec( 300 );
	LOCAL_DEBUG_OUT( "10 sliip_a_millisec(300) completed%s","" );
#endif
#endif

	_as_grab_screen_func = GrabEm;
	_as_ungrab_screen_func = UngrabEm;

	original_DISPLAY_string = getenv("DISPLAY");
	if (original_DISPLAY_string)
		original_DISPLAY_string = mystrdup(original_DISPLAY_string);

#ifdef DEBUG_TRACE_X
	trace_window_id2name_hook = &window_id2name;
#endif
	set_DeadPipe_handler(DeadPipe);

#if !HAVE_DECL_ENVIRON
	override_environ( envp );
#endif
    InitMyApp( CLASS_AFTERSTEP, argc, argv, NULL, AfterStep_usage, 0);

	LinkAfterStepConfig();

    AfterStepState = MyArgs.flags ;
    clear_flags( AfterStepState, ASS_NormalOperation );
	set_flags( AfterStepState, ASS_SuppressDeskBack );

#ifdef __CYGWIN__
    CloseOnExec = ASCloseOnExec ;
#endif

#if defined(LOG_FONT_CALLS)
	fprintf (stderr, "logging font calls now\n");
#endif

    /* These signals are mandatory : */
    signal (SIGUSR1, Restart);
    /* These signals we would like to handle only if those are not handled already (by debugger): */
    IgnoreSignal(SIGINT);
    IgnoreSignal(SIGHUP);
    IgnoreSignal(SIGQUIT);
    IgnoreSignal(SIGTERM);

    if( ConnectX( ASDefaultScr, AS_ROOT_EVENT_MASK ) < 0  )
	{
		show_error( "Hostile X server encountered - unable to proceed :-(");
		return 1;/* failed to accure window management selection - other wm is running */
	}


	ASDBus_fd = asdbus_init();

	XSetWindowBackground( dpy, Scr.Root, Scr.asv->black_pixel );
	Scr.Look.desktop_animation_tint = get_random_tint_color();

    cover_desktop();
	if( get_flags( AfterStepState, ASS_Restarting ))
	{	
		show_progress( "AfterStep v.%s is restarting ...", VERSION );
		display_progress( True, "AfterStep v.%s is restarting ...", VERSION );
	}else
	{	
    	show_progress( "AfterStep v.%s is starting up ...", VERSION );
		display_progress( True, "AfterStep v.%s is starting up ...", VERSION );
	}

	if (ASDBus_fd>=0)
	{
    	show_progress ("Successfuly accured System DBus connection.");	
		asdbus_RegisterSMClient(SMClientID_string);
	}
	
SHOW_CHECKPOINT;
	InitSession();
SHOW_CHECKPOINT;
	XSync (dpy, 0);
SHOW_CHECKPOINT;
    set_parent_hints_func( afterstep_parent_hints_func ); /* callback for collect_hints() */
SHOW_CHECKPOINT;
    SetupModules();
SHOW_CHECKPOINT;
	SetupScreen();
SHOW_CHECKPOINT;
	event_setup( True /*Bool local*/ );
SHOW_CHECKPOINT;
	/*
     *  Lets init each and every screen separately :
     */
	
    for (i = 0; i < Scr.NumberOfScreens; i++)
	{
        show_progress( "Initializing screen %d ...", i );
        display_progress( True, "Initializing screen %d ...", i );

        if (i != Scr.screen)
        {
            if( !get_flags(MyArgs.flags, ASS_SingleScreen) )
            {
                int pid = spawn_child( MyName, (i<MAX_USER_SINGLETONS_NUM)?i:-1, i, NULL, None, C_NO_CONTEXT, True, True, NULL );
                if( pid >= 0 )
                    show_progress( "\t instance of afterstep spawned with pid %d.", pid );
                else
                    show_error( "failed to launch instance of afterstep to handle screen #%d", i );
            }
        }else
        {
            make_screen_envvars(ASDefaultScr);
            putenv (Scr.rdisplay_string);
            putenv (Scr.display_string);
            if( is_output_level_under_threshold( OUTPUT_LEVEL_PROGRESS ) )
            {
                show_progress( "\t screen[%d].size = %ux%u", Scr.screen, Scr.MyDisplayWidth, Scr.MyDisplayHeight );
                display_progress( True, "    screen[%d].size = %ux%u", Scr.screen, Scr.MyDisplayWidth, Scr.MyDisplayHeight );
                show_progress( "\t screen[%d].root = %lX", Scr.screen, Scr.Root );
                show_progress( "\t screen[%d].color_depth = %d", Scr.screen, Scr.asv->true_depth );
                display_progress( True, "    screen[%d].color_depth = %d", Scr.screen, Scr.asv->true_depth );
                show_progress( "\t screen[%d].colormap    = 0x%lX", Scr.screen, Scr.asv->colormap );
                show_progress( "\t screen[%d].visual.id         = %X",  Scr.screen, Scr.asv->visual_info.visualid );
                display_progress( True, "    screen[%d].visual.id         = %X",  Scr.screen, Scr.asv->visual_info.visualid );
                show_progress( "\t screen[%d].visual.class      = %d",  Scr.screen, Scr.asv->visual_info.class );
                display_progress( True, "    screen[%d].visual.class      = %d",  Scr.screen, Scr.asv->visual_info.class );
                show_progress( "\t screen[%d].visual.red_mask   = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.red_mask   );
                show_progress( "\t screen[%d].visual.green_mask = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.green_mask );
                show_progress( "\t screen[%d].visual.blue_mask  = 0x%8.8lX", Scr.screen, Scr.asv->visual_info.blue_mask  );
                show_progress( "\t screen[%d].rdisplay_string = \"%s\"", Scr.screen, Scr.rdisplay_string );
                show_progress( "\t screen[%d].display_string = \"%s\"", Scr.screen, Scr.display_string );
                display_progress( True, "    screen[%d].display_string = \"%s\"", Scr.screen, Scr.display_string );
            }
        }
    }

   /* make sure we're on the right desk, and the _WIN_DESK property is set */
    Scr.CurrentDesk = INVALID_DESK ;
    if( get_flags( Scr.wmprops->set_props, WMC_ASDesks )  )
	{
		start_desk = Scr.wmprops->as_current_desk ;
    }else if( get_flags( Scr.wmprops->set_props, WMC_DesktopCurrent )  )
    {
        int curr = Scr.wmprops->desktop_current ;
        start_desk = curr;
        if( get_flags( Scr.wmprops->set_props, WMC_DesktopViewport ) &&
            curr < Scr.wmprops->desktop_viewports_num )
        {
            /* we have to do that prior to capturing any window so that they'll get in
             * correct position and will not end up outside of the screen */
            start_viewport_x = Scr.wmprops->desktop_viewport[curr<<1] ;
			start_viewport_y = Scr.wmprops->desktop_viewport[(curr<<1)+1] ;
        }
    }
    if( get_flags( Scr.wmprops->set_props, WMC_ASViewport )  )
	{
		start_viewport_x = Scr.wmprops->as_current_vx ;
		start_viewport_y = Scr.wmprops->as_current_vy ;
	}
	/* temporarily setting up desktop 0 */
	ChangeDesks(0);

    /* Load config ... */
    /* read config file, set up menus, colors, fonts */
    LoadASConfig (0, PARSE_EVERYTHING);

    /* Reparent all the windows and setup pan frames : */
    XSync (dpy, 0);
   /***********************************************************/
#ifndef DONT_GRAB_SERVER                    /* grabbed   !!!!!*/
	grab_server();                		/* grabbed   !!!!!*/
#endif										/* grabbed   !!!!!*/
    init_screen_panframes(ASDefaultScr);            /* grabbed   !!!!!*/
    display_progress( True, "Capturing all windows ..." );
    CaptureAllWindows (ASDefaultScr);               /* grabbed   !!!!!*/
    display_progress( False, "Done." );
    check_screen_panframes(ASDefaultScr);           /* grabbed   !!!!!*/
    ASSync( False );
#ifndef DONT_GRAB_SERVER                    /* grabbed   !!!!!*/
	ungrab_server();					/* UnGrabbed !!!!!*/
#endif										/* UnGrabbed !!!!!*/
	/**********************************************************/
    XDefineCursor (dpy, Scr.Root, Scr.Feel.cursors[ASCUR_Default]);

    display_progress( True, "Seting initial viewport to %+d%+d ...", Scr.wmprops->as_current_vx, Scr.wmprops->as_current_vy );

    SetupFunctionHandlers();
    display_progress( True, "Processing all pending events ..." );
    ConfigureNotifyLoop();
    display_progress( True, "All done." );
    remove_desktop_cover();

	if( !get_flags(AfterStepStartupFlags, ASSF_BypassAutoexec))
    	DoAutoexec(get_flags( AfterStepState, ASS_Restarting));
	
	/* once all the windows are swallowed and placed in its proper desks - we cas restore proper
	   desktop/viewport : */
	clear_flags( AfterStepState, ASS_SuppressDeskBack );
	ChangeDeskAndViewport ( start_desk, start_viewport_x, start_viewport_y, False);

    /* all system Go! we are completely Operational! */
    set_flags( AfterStepState, ASS_NormalOperation);

#if (defined(LOCAL_DEBUG)||defined(DEBUG)) && defined(DEBUG_ALLOCS)
    LOCAL_DEBUG_OUT( "printing memory%s","");
    spool_unfreed_mem( "afterstep.allocs.startup", NULL );
#endif
    LOCAL_DEBUG_OUT( "entering main loop%s","");

    HandleEvents ();
	return (0);
}