diff options
author | Harald Welte <laforge@gnumonks.org> | 2010-05-04 11:02:54 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-05-04 11:02:54 +0200 |
commit | c3dcba0fa66a65da5f0b6e267415150a9fcf86f9 (patch) | |
tree | f7d05fde95a50a009d52d2a634432caed85f75c7 /ggsn/ggsn.c | |
parent | e67556e96f135aff7ebb80ad3b8ae89973bbcdaa (diff) |
Fix GGSN signal handling
In order te exit gracefully (closing the tun devices), we install a SIGINT
handler and note its occurrence in a global variable.
This fix is from http://sourceforge.net/tracker/index.php?func=detail&aid=1811513&group_id=68956&atid=522957
Diffstat (limited to 'ggsn/ggsn.c')
-rw-r--r-- | ggsn/ggsn.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index ca6a5cc..452df30 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -54,7 +54,7 @@ #include "../gtp/gtp.h" #include "cmdline.h" - +int end = 0; int maxfd = 0; /* For select() */ struct in_addr listen_; @@ -70,6 +70,11 @@ struct gsn_t *gsn; /* GSN instance */ struct tun_t *tun; /* TUN instance */ struct ippool_t *ippool; /* Pool of IP addresses */ +/* To exit gracefully. Used with GCC compilation flag -pg and gprof */ +void signal_handler(int s) { + if (debug) printf("Received signal %d, exiting.\n", s); + end = 1; +} /* Used to write process ID to file. Assume someone else will delete */ void log_pid(char *pidfile) { @@ -208,6 +213,14 @@ int main(int argc, char **argv) struct hostent *host; + /* Handle keyboard interrupt SIGINT */ + struct sigaction s; + s.sa_handler = (void *) signal_handler; + if ((0 != sigemptyset( &s.sa_mask )) && debug) + printf("sigemptyset failed.\n"); + s.sa_flags = SA_RESETHAND; + if ((sigaction(SIGINT, &s, NULL) != 0) && debug) + printf("Could not register SIGINT signal handler.\n"); fd_set fds; /* For select() */ struct timeval idleTime; /* How long to select() */ @@ -478,8 +491,8 @@ int main(int argc, char **argv) /* Main select loop */ /******************************************************************/ - while (((starttime + timelimit) > time(NULL)) || (0 == timelimit)) { - + while ((((starttime + timelimit) > time(NULL)) || (0 == timelimit)) && (!end)) { + FD_ZERO(&fds); if (tun) FD_SET(tun->fd, &fds); FD_SET(gsn->fd0, &fds); |