|  | @@ -100,6 +100,7 @@ static int conn_close_if_marked(int i);
 | 
	
		
			
				|  |  |  static void connection_start_reading_from_linked_conn(connection_t *conn);
 | 
	
		
			
				|  |  |  static int connection_should_read_from_linked_conn(connection_t *conn);
 | 
	
		
			
				|  |  |  static int run_main_loop_until_done(void);
 | 
	
		
			
				|  |  | +static void process_signal(int sig);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /********* START VARIABLES **********/
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2260,11 +2261,10 @@ run_main_loop_until_done(void)
 | 
	
		
			
				|  |  |    return loop_result;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#ifndef _WIN32 /* Only called when we're willing to use signals */
 | 
	
		
			
				|  |  |  /** Libevent callback: invoked when we get a signal.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  static void
 | 
	
		
			
				|  |  | -signal_callback(int fd, short events, void *arg)
 | 
	
		
			
				|  |  | +signal_callback(evutil_socket_t fd, short events, void *arg)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    const int *sigptr = arg;
 | 
	
		
			
				|  |  |    const int sig = *sigptr;
 | 
	
	
		
			
				|  | @@ -2273,10 +2273,9 @@ signal_callback(int fd, short events, void *arg)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    process_signal(sig);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /** Do the work of acting on a signal received in <b>sig</b> */
 | 
	
		
			
				|  |  | -void
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  |  process_signal(int sig)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    switch (sig)
 | 
	
	
		
			
				|  | @@ -2501,36 +2500,73 @@ exit_function(void)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/** Set up the signal handlers for either parent or child. */
 | 
	
		
			
				|  |  | +#ifdef _WIN32
 | 
	
		
			
				|  |  | +#define UNIX_ONLY 0
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +#define UNIX_ONLY 1
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +static struct {
 | 
	
		
			
				|  |  | +  int signal_value;
 | 
	
		
			
				|  |  | +  int try_to_register;
 | 
	
		
			
				|  |  | +  struct event *signal_event;
 | 
	
		
			
				|  |  | +} signal_handlers[] = {
 | 
	
		
			
				|  |  | +#ifdef SIGINT
 | 
	
		
			
				|  |  | +  { SIGINT, UNIX_ONLY, NULL }, /* do a controlled slow shutdown */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGTERM
 | 
	
		
			
				|  |  | +  { SIGTERM, UNIX_ONLY, NULL }, /* to terminate now */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGPIPE
 | 
	
		
			
				|  |  | +  { SIGPIPE, UNIX_ONLY, NULL }, /* otherwise SIGPIPE kills us */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGUSR1
 | 
	
		
			
				|  |  | +  { SIGUSR1, UNIX_ONLY, NULL }, /* dump stats */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGUSR2
 | 
	
		
			
				|  |  | +  { SIGUSR2, UNIX_ONLY, NULL }, /* go to loglevel debug */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGHUP
 | 
	
		
			
				|  |  | +  { SIGHUP, UNIX_ONLY, NULL }, /* to reload config, retry conns, etc */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGXFSZ
 | 
	
		
			
				|  |  | +  { SIGXFSZ, UNIX_ONLY, NULL }, /* handle file-too-big resource exhaustion */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef SIGCHLD
 | 
	
		
			
				|  |  | +  { SIGCHLD, UNIX_ONLY, NULL }, /* handle dns/cpu workers that exit */
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +  /* These are controller-only */
 | 
	
		
			
				|  |  | +  { SIGNEWNYM, 0, NULL },
 | 
	
		
			
				|  |  | +  { SIGCLEARDNSCACHE, 0, NULL },
 | 
	
		
			
				|  |  | +  { SIGHEARTBEAT, 0, NULL },
 | 
	
		
			
				|  |  | +  { -1, -1, NULL }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/** Set up the signal handlers for either parent or child process */
 | 
	
		
			
				|  |  |  void
 | 
	
		
			
				|  |  |  handle_signals(int is_parent)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -#ifndef _WIN32 /* do signal stuff only on Unix */
 | 
	
		
			
				|  |  |    int i;
 | 
	
		
			
				|  |  | -  static const int signals[] = {
 | 
	
		
			
				|  |  | -    SIGINT,  /* do a controlled slow shutdown */
 | 
	
		
			
				|  |  | -    SIGTERM, /* to terminate now */
 | 
	
		
			
				|  |  | -    SIGPIPE, /* otherwise SIGPIPE kills us */
 | 
	
		
			
				|  |  | -    SIGUSR1, /* dump stats */
 | 
	
		
			
				|  |  | -    SIGUSR2, /* go to loglevel debug */
 | 
	
		
			
				|  |  | -    SIGHUP,  /* to reload config, retry conns, etc */
 | 
	
		
			
				|  |  | -#ifdef SIGXFSZ
 | 
	
		
			
				|  |  | -    SIGXFSZ, /* handle file-too-big resource exhaustion */
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -    SIGCHLD, /* handle dns/cpu workers that exit */
 | 
	
		
			
				|  |  | -    -1 };
 | 
	
		
			
				|  |  | -  static struct event *signal_events[16]; /* bigger than it has to be. */
 | 
	
		
			
				|  |  |    if (is_parent) {
 | 
	
		
			
				|  |  | -    for (i = 0; signals[i] >= 0; ++i) {
 | 
	
		
			
				|  |  | -      signal_events[i] = tor_evsignal_new(tor_libevent_get_base(), signals[i],
 | 
	
		
			
				|  |  | -                                          signal_callback,
 | 
	
		
			
				|  |  | -                                          /* Cast away const */
 | 
	
		
			
				|  |  | -                                          (int*)&signals[i]);
 | 
	
		
			
				|  |  | -      if (event_add(signal_events[i], NULL))
 | 
	
		
			
				|  |  | -        log_warn(LD_BUG, "Error from libevent when adding event for signal %d",
 | 
	
		
			
				|  |  | -                 signals[i]);
 | 
	
		
			
				|  |  | +    for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
 | 
	
		
			
				|  |  | +      if (signal_handlers[i].try_to_register) {
 | 
	
		
			
				|  |  | +        signal_handlers[i].signal_event =
 | 
	
		
			
				|  |  | +          tor_evsignal_new(tor_libevent_get_base(),
 | 
	
		
			
				|  |  | +                           signal_handlers[i].signal_value,
 | 
	
		
			
				|  |  | +                           signal_callback,
 | 
	
		
			
				|  |  | +                           &signal_handlers[i].signal_value);
 | 
	
		
			
				|  |  | +        if (event_add(signal_handlers[i].signal_event, NULL))
 | 
	
		
			
				|  |  | +          log_warn(LD_BUG, "Error from libevent when adding "
 | 
	
		
			
				|  |  | +                   "event for signal %d",
 | 
	
		
			
				|  |  | +                   signal_handlers[i].signal_value);
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        signal_handlers[i].signal_event =
 | 
	
		
			
				|  |  | +          tor_event_new(tor_libevent_get_base(), -1,
 | 
	
		
			
				|  |  | +                        EV_SIGNAL, signal_callback,
 | 
	
		
			
				|  |  | +                        &signal_handlers[i].signal_value);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  | +#ifndef _WIN32
 | 
	
		
			
				|  |  |      struct sigaction action;
 | 
	
		
			
				|  |  |      action.sa_flags = 0;
 | 
	
		
			
				|  |  |      sigemptyset(&action.sa_mask);
 | 
	
	
		
			
				|  | @@ -2544,10 +2580,21 @@ handle_signals(int is_parent)
 | 
	
		
			
				|  |  |  #ifdef SIGXFSZ
 | 
	
		
			
				|  |  |      sigaction(SIGXFSZ, &action, NULL);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* Make sure the signal handler for signal_num will be called. */
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +activate_signal(int signal_num)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  int i;
 | 
	
		
			
				|  |  | +  for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
 | 
	
		
			
				|  |  | +    if (signal_handlers[i].signal_value == signal_num) {
 | 
	
		
			
				|  |  | +      event_active(signal_handlers[i].signal_event, EV_SIGNAL, 1);
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -#else /* MS windows */
 | 
	
		
			
				|  |  | -  (void)is_parent;
 | 
	
		
			
				|  |  | -#endif /* signal stuff */
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /** Main entry point for the Tor command-line client.
 |