[PATCH 1/1] Apply application logging approach for vpnc-script output
Ľubomír Carik
lubomir.carik at gmail.com
Sun Apr 15 14:08:53 PDT 2018
- inherit handlers for child process
- update close app handles
- update flags
Signed-off-by: Ľubomír Carik <Lubomir.Carik at gmail.com>
---
openconnect.h | 2 ++
script.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 94 insertions(+), 12 deletions(-)
diff --git a/openconnect.h b/openconnect.h
index e97dacbc..75dfdd18 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -29,6 +29,8 @@ extern "C" {
#endif
#ifdef _WIN32
+#include <winsock2.h>
+
#define uid_t unsigned
#endif
diff --git a/script.c b/script.c
index 5b751ad5..695ebd38 100644
--- a/script.c
+++ b/script.c
@@ -24,6 +24,8 @@
#include <unistd.h>
#ifndef _WIN32
#include <sys/wait.h>
+#else
+#include <stdbool.h>
#endif
#include <errno.h>
#include <ctype.h>
@@ -32,6 +34,15 @@
#include "openconnect-internal.h"
+#ifdef _WIN32
+#define BUFSIZE 4096
+
+HANDLE g_hChildStd_OUT_Rd = NULL;
+HANDLE g_hChildStd_OUT_Wr = NULL;
+HANDLE g_hChildStd_ERR_Rd = NULL;
+HANDLE g_hChildStd_ERR_Wr = NULL;
+#endif
+
int script_setenv(struct openconnect_info *vpninfo,
const char *opt, const char *val, int append)
{
@@ -459,17 +470,52 @@ int script_config_tun(struct openconnect_info *vpninfo, const char *reason)
int ret;
char *cmd;
PROCESS_INFORMATION pi;
+ SECURITY_ATTRIBUTES sa;
STARTUPINFOW si;
DWORD cpflags;
+ DWORD dwRead = 0;
+ CHAR chBuf[BUFSIZE];
+ bool bSuccess = FALSE;
+ char* token = NULL;
+
if (!vpninfo->vpnc_script || vpninfo->script_tun)
return 0;
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
+ // Set the bInheritHandle flag so pipe handles are inherited.
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+ // Create a pipe for the child process's STDERR.
+ if (!CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &sa, 0)) {
+ return -EPIPE;
+ }
+ // Ensure the read handle to the pipe for STDERR is not inherited.
+ if (!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) {
+ return -EPIPE;
+ }
+ // Create a pipe for the child process's STDOUT.
+ if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0)) {
+ return -EPIPE;
+ }
+ // Ensure the read handle to the pipe for STDOUT is not inherited
+ if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
+ return -EPIPE;
+ }
+
+ // Set up members of the PROCESS_INFORMATION structure.
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+ // Set up members of the STARTUPINFO structure.
+ // This structure specifies the STDERR and STDOUT handles for redirection.
+ ZeroMemory(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
/* probably superfluous */
- si.dwFlags = STARTF_USESHOWWINDOW;
+ si.dwFlags |= STARTF_USESHOWWINDOW;
+ si.dwFlags |= STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
+ si.hStdError = g_hChildStd_ERR_Wr;
+ si.hStdOutput = g_hChildStd_OUT_Wr;
script_setenv(vpninfo, "reason", reason, 0);
@@ -495,19 +541,53 @@ int script_config_tun(struct openconnect_info *vpninfo, const char *reason)
if (!GetConsoleWindow())
cpflags |= CREATE_NO_WINDOW;
- if (CreateProcessW(NULL, script_w, NULL, NULL, FALSE, cpflags,
- script_env, NULL, &si, &pi)) {
- ret = WaitForSingleObject(pi.hProcess,10000);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- if (ret == WAIT_TIMEOUT)
- ret = -ETIMEDOUT;
- else
- ret = 0;
+ if (CreateProcessW(NULL,
+ script_w, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ cpflags, // creation flags
+ script_env, // use parent's environment
+ NULL, // use parent's current directory
+ &si, // STARTUPINFO pointer
+ &pi) // receives PROCESS_INFORMATION
+ ) {
+ CloseHandle(g_hChildStd_ERR_Wr);
+ CloseHandle(g_hChildStd_OUT_Wr);
+ ret = 0;
} else {
ret = -EIO;
}
+ // Read from pipe that is the standard output for child process.
+ for (;;) {
+ bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
+ if (!bSuccess || dwRead == 0) break;
+
+ chBuf[dwRead] = 0;
+ token = strtok(chBuf, "\r\n");
+ while (token) {
+ vpn_progress(vpninfo, PRG_INFO,
+ _("vpnc: %s\n"),
+ token);
+ token = strtok(NULL, "\r\n");
+ }
+ }
+ dwRead = 0;
+ for (;;) {
+ bSuccess = ReadFile(g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
+ if (!bSuccess || dwRead == 0) break;
+
+ chBuf[dwRead] = 0;
+ token = strtok(chBuf, "\r\n");
+ while (token) {
+ vpn_progress(vpninfo, PRG_ERR,
+ _("vpnc: %s\n"),
+ token);
+ token = strtok(NULL, "\r\n");
+ }
+ }
+
free(script_env);
if (ret < 0) {
--
2.16.2
More information about the openconnect-devel
mailing list