[PATCH/RFC V2 04/26] library: Add new openconnect_setup_cancel_pipe() call
Kevin Cernekee
cernekee at gmail.com
Sun Aug 11 21:49:05 EDT 2013
Most callers will use a simple nonblocking UNIX pipe as their cancel_fd,
so provide a convenience function for creating it. Also, libopenconnect
will take care of cleaning up pipes created in this manner when the
library instance is freed.
Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
---
libopenconnect.map.in | 5 +++++
library.c | 24 ++++++++++++++++++++++++
openconnect-internal.h | 1 +
openconnect.h | 5 +++++
4 files changed, 35 insertions(+)
diff --git a/libopenconnect.map.in b/libopenconnect.map.in
index 16d3380..2845754 100644
--- a/libopenconnect.map.in
+++ b/libopenconnect.map.in
@@ -43,6 +43,11 @@ OPENCONNECT_2.2 {
openconnect_set_token_mode;
} OPENCONNECT_2.1;
+OPENCONNECT_2.3 {
+ global:
+ openconnect_setup_cancel_pipe;
+} OPENCONNECT_2.2;
+
OPENCONNECT_PRIVATE {
global: @SYMVER_TIME@ @SYMVER_ASPRINTF@ @SYMVER_GETLINE@ @SYMVER_PRINT_ERR@
openconnect_SSL_gets;
diff --git a/library.c b/library.c
index 66bf89b..86c3df8 100644
--- a/library.c
+++ b/library.c
@@ -26,6 +26,8 @@
#include <string.h>
#include <errno.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
#ifdef HAVE_LIBSTOKEN
#include <stoken.h>
@@ -57,6 +59,7 @@ struct openconnect_info *openconnect_vpninfo_new(char *useragent,
vpninfo->progress = progress;
vpninfo->cbdata = privdata ? : vpninfo;
vpninfo->cancel_fd = -1;
+ vpninfo->cancel_fd_write = -1;
vpninfo->xmlpost = 1;
openconnect_set_reported_os(vpninfo, NULL);
@@ -106,6 +109,10 @@ static void free_optlist(struct vpn_option *opt)
void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
{
openconnect_close_https(vpninfo, 1);
+ if (vpninfo->cancel_fd_write != -1) {
+ close(vpninfo->cancel_fd);
+ close(vpninfo->cancel_fd_write);
+ }
free(vpninfo->peer_addr);
free_optlist(vpninfo->cookies);
free_optlist(vpninfo->cstp_options);
@@ -287,6 +294,23 @@ void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd)
vpninfo->cancel_fd = fd;
}
+int openconnect_setup_cancel_pipe(struct openconnect_info *vpninfo)
+{
+ int pipefd[2];
+
+ if (pipe(pipefd) < 0)
+ return -EIO;
+ if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) ||
+ fcntl(pipefd[1], F_SETFL, O_NONBLOCK)) {
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return -EIO;
+ }
+ vpninfo->cancel_fd = pipefd[0];
+ vpninfo->cancel_fd_write = pipefd[1];
+ return vpninfo->cancel_fd_write;
+}
+
const char *openconnect_get_version(void)
{
return openconnect_version_str;
diff --git a/openconnect-internal.h b/openconnect-internal.h
index ea59d23..549448c 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -295,6 +295,7 @@ struct openconnect_info {
int dtls_fd;
int new_dtls_fd;
int cancel_fd;
+ int cancel_fd_write;
struct pkt *incoming_queue;
struct pkt *outgoing_queue;
diff --git a/openconnect.h b/openconnect.h
index d48bc25..47ac8b5 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -217,6 +217,11 @@ void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo,
cancellation mechanism inactive. */
void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd);
+/* Create a nonblocking pipe, set the read end as the cancel_fd, and return a
+ file descriptor for the write end. Both sides will be closed by
+ openconnect_vpninfo_free(). */
+int openconnect_setup_cancel_pipe(struct openconnect_info *vpninfo);
+
const char *openconnect_get_version(void);
/* The first (privdata) argument to each of these functions is either
--
1.7.9.5
More information about the openconnect-devel
mailing list