[PATCH/RFC V2 05/26] Convert vpn_mainloop() into a library function
Kevin Cernekee
cernekee at gmail.com
Sun Aug 11 21:49:06 EDT 2013
In order to make the mainloop a reusable library function, it should not
take over any POSIX signals. Handle the signals in main.c instead, and
use the cancel_fd mechanism to tell the mainloop to exit.
Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
---
cstp.c | 2 +-
libopenconnect.map.in | 1 +
main.c | 33 +++++++++++++++++++++++++++++++--
mainloop.c | 28 ++++------------------------
openconnect-internal.h | 3 ---
openconnect.h | 4 ++++
tun.c | 1 -
7 files changed, 41 insertions(+), 31 deletions(-)
diff --git a/cstp.c b/cstp.c
index bb79e7e..beab3f9 100644
--- a/cstp.c
+++ b/cstp.c
@@ -567,7 +567,7 @@ int cstp_reconnect(struct openconnect_info *vpninfo)
_("sleep %ds, remaining timeout %ds\n"),
interval, timeout);
sleep(interval);
- if (killed)
+ if (cancel_fd_check(vpninfo))
return 1;
timeout -= interval;
interval += vpninfo->reconnect_interval;
diff --git a/libopenconnect.map.in b/libopenconnect.map.in
index 2845754..a530324 100644
--- a/libopenconnect.map.in
+++ b/libopenconnect.map.in
@@ -46,6 +46,7 @@ OPENCONNECT_2.2 {
OPENCONNECT_2.3 {
global:
openconnect_setup_cancel_pipe;
+ openconnect_mainloop;
} OPENCONNECT_2.2;
OPENCONNECT_PRIVATE {
diff --git a/main.c b/main.c
index 5ddd9b8..b3b1776 100644
--- a/main.c
+++ b/main.c
@@ -331,6 +331,20 @@ static void read_stdin(char **string)
if (c)
*c = 0;
}
+
+static int sig_cancel_fd;
+static int sig_caught;
+
+static void handle_sigint(int sig)
+{
+ char x = 'x';
+
+ sig_caught = sig;
+ if (write(sig_cancel_fd, &x, 1) < 0) {
+ /* suppress warn_unused_result */
+ }
+}
+
static void handle_sigusr(int sig)
{
if (sig == SIGUSR1)
@@ -795,12 +809,23 @@ int main(int argc, char **argv)
vpninfo->progress = syslog_progress;
}
+ sig_cancel_fd = openconnect_setup_cancel_pipe(vpninfo);
+ if (sig_cancel_fd < 0) {
+ fprintf(stderr, _("Error opening cancel pipe\n"));
+ exit(1);
+ }
+
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = handle_sigusr;
+ sa.sa_handler = handle_sigusr;
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL);
+ sa.sa_handler = handle_sigint;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+
if (vpninfo->sslkey && do_passphrase_from_fsid)
openconnect_passphrase_from_fsid(vpninfo);
@@ -921,7 +946,11 @@ int main(int argc, char **argv)
if (fp)
fclose(fp);
}
- vpn_mainloop(vpninfo);
+ openconnect_mainloop(vpninfo);
+
+ if (sig_caught)
+ vpn_progress(vpninfo, PRG_INFO, _("Caught signal: %s\n"), strsignal(sig_caught));
+
if (fp)
unlink(pidfile);
exit(1);
diff --git a/mainloop.c b/mainloop.c
index 2d10147..ccd1861 100644
--- a/mainloop.c
+++ b/mainloop.c
@@ -27,7 +27,6 @@
#include <limits.h>
#include <sys/select.h>
#include <stdlib.h>
-#include <signal.h>
#include <unistd.h>
#include <string.h>
@@ -55,23 +54,9 @@ int queue_new_packet(struct pkt **q, void *buf, int len)
return 0;
}
-int killed;
-
-static void handle_sigint(int sig)
-{
- killed = sig;
-}
-
-int vpn_mainloop(struct openconnect_info *vpninfo)
+int openconnect_mainloop(struct openconnect_info *vpninfo)
{
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = handle_sigint;
-
- sigaction(SIGTERM, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
-
+ cancel_fd_set(vpninfo, &vpninfo->select_rfds, &vpninfo->select_nfds);
while (!vpninfo->quit_reason) {
int did_work = 0;
int timeout = INT_MAX;
@@ -103,13 +88,8 @@ int vpn_mainloop(struct openconnect_info *vpninfo)
if (vpninfo->quit_reason)
break;
- if (killed) {
- if (killed == SIGHUP)
- vpninfo->quit_reason = "Client received SIGHUP";
- else if (killed == SIGINT)
- vpninfo->quit_reason = "Client received SIGINT";
- else
- vpninfo->quit_reason = "Client killed";
+ if (cancel_fd_check(vpninfo)) {
+ vpninfo->quit_reason = "Aborted by caller";
break;
}
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 549448c..5215ea5 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -450,14 +450,11 @@ int openconnect_local_cert_md5(struct openconnect_info *vpninfo,
/* mainloop.c */
int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events);
-int vpn_mainloop(struct openconnect_info *vpninfo);
int queue_new_packet(struct pkt **q, void *buf, int len);
void queue_packet(struct pkt **q, struct pkt *new);
int keepalive_action(struct keepalive_info *ka, int *timeout);
int ka_stalled_action(struct keepalive_info *ka, int *timeout);
-extern int killed;
-
/* xml.c */
int config_lookup_host(struct openconnect_info *vpninfo, const char *host);
diff --git a/openconnect.h b/openconnect.h
index 47ac8b5..6297e4a 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -224,6 +224,10 @@ int openconnect_setup_cancel_pipe(struct openconnect_info *vpninfo);
const char *openconnect_get_version(void);
+/* Start the main loop; exits if data is received on cancel_fd or the remote
+ site aborts. */
+int openconnect_mainloop(struct openconnect_info *vpninfo);
+
/* The first (privdata) argument to each of these functions is either
the privdata argument provided to openconnect_vpninfo_new_with_cbdata(),
or if that argument was NULL then it'll be the vpninfo itself. */
diff --git a/tun.c b/tun.c
index 8f5f1b9..0db7c43 100644
--- a/tun.c
+++ b/tun.c
@@ -28,7 +28,6 @@
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <string.h>
-#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
--
1.7.9.5
More information about the openconnect-devel
mailing list