diff options
author | Roland Knall <rknall@gmail.com> | 2016-06-28 21:34:46 +0200 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2016-07-05 11:54:43 +0000 |
commit | f2786bc8ff5ea25fd1c36d3ebf83a29277ee662b (patch) | |
tree | 0e0f3c89505d3257ab5510c55eff956543814e40 /extcap.c | |
parent | fdd87a1e41db7039b0af5bb15f40b83db1ca3a96 (diff) |
extcap: Remove g_spawn_helper support
Move g_spawn to separate file and implement functions to
use Windows based method of spawning, instead of the glib
based version
Change-Id: Ibae03d834ec86531eba37dc8768fbf17ddadf57f
Reviewed-on: https://code.wireshark.org/review/16049
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Graham Bloice <graham.bloice@trihedral.com>
Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'extcap.c')
-rw-r--r-- | extcap.c | 189 |
1 files changed, 58 insertions, 131 deletions
@@ -51,6 +51,7 @@ #include "extcap.h" #include "extcap_parser.h" +#include "extcap_spawn.h" #ifdef _WIN32 static HANDLE pipe_h = NULL; @@ -153,67 +154,28 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb, GDir *dir; const gchar *file; gboolean keep_going; - gint i; - gchar **argv; -#ifdef _WIN32 - gchar **dll_search_envp; - gchar *progfile_dir; -#endif keep_going = TRUE; - argv = (gchar **) g_malloc0(sizeof(gchar *) * (argc + 2)); - -#ifdef _WIN32 - /* - * Make sure executables can find dependent DLLs and that they're *our* - * DLLs: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx - * Alternatively we could create a simple wrapper exe similar to Create - * Hidden Process (http://www.commandline.co.uk/chp/). - */ - dll_search_envp = g_get_environ(); - progfile_dir = g_strdup_printf("%s;%s", get_progfile_dir(), g_environ_getenv(dll_search_envp, "Path")); - dll_search_envp = g_environ_setenv(dll_search_envp, "Path", progfile_dir, TRUE); - g_free(progfile_dir); -#endif - if ((dir = g_dir_open(dirname, 0, NULL)) != NULL) { GString *extcap_path = NULL; extcap_path = g_string_new(""); while (keep_going && (file = g_dir_read_name(dir)) != NULL ) { gchar *command_output = NULL; - gboolean status = FALSE; - gint exit_status = 0; - gchar **envp = NULL; /* full path to extcap binary */ #ifdef _WIN32 g_string_printf(extcap_path, "%s\\%s", dirname, file); - envp = dll_search_envp; #else g_string_printf(extcap_path, "%s/%s", dirname, file); #endif if ( extcap_if_exists(ifname) && !extcap_if_exists_for_extcap(ifname, extcap_path->str ) ) continue; -#ifdef _WIN32 - argv[0] = g_strescape(extcap_path->str, NULL); -#else - argv[0] = g_strdup(extcap_path->str); -#endif - for (i = 0; i < argc; ++i) - argv[i+1] = args[i]; - argv[argc+1] = NULL; - - status = g_spawn_sync(dirname, argv, envp, - (GSpawnFlags) 0, NULL, NULL, - &command_output, NULL, &exit_status, NULL); - - if (status && exit_status == 0) + if ( extcap_spawn_sync ( (gchar *) dirname, extcap_path->str, argc, args, &command_output ) ) keep_going = cb(extcap_path->str, ifname, command_output, cb_data, err_str); - g_free(argv[0]); g_free(command_output); } @@ -221,10 +183,6 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb, g_string_free(extcap_path, TRUE); } -#ifdef _WIN32 - g_strfreev(dll_search_envp); -#endif - g_free(argv); } static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data, @@ -644,7 +602,7 @@ void extcap_cleanup(capture_options * capture_opts) { /* skip native interfaces */ if (interface_opts.if_type != IF_EXTCAP) - continue; + continue; g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Extcap [%s] - Cleaning up fifo: %s; PID: %d", interface_opts.name, @@ -730,34 +688,20 @@ static void extcap_child_watch_cb(GPid pid, gint status _U_, gpointer user_data) } } -/* call mkfifo for each extcap, - * returns FALSE if there's an error creating a FIFO */ -gboolean -extcap_init_interfaces(capture_options *capture_opts) +static +GPtrArray * extcap_prepare_arguments(interface_options interface_opts) { - guint i; - interface_options interface_opts; - - for (i = 0; i < capture_opts->ifaces->len; i++) - { - GPtrArray *args = NULL; - GPid pid = INVALID_EXTCAP_PID; - gchar **tmp; - int tmp_i; - - interface_opts = g_array_index(capture_opts->ifaces, interface_options, i); - - /* skip native interfaces */ - if (interface_opts.if_type != IF_EXTCAP ) - continue; + GPtrArray *result = NULL; +#if ARG_DEBUG + gchar **tmp; + int tmp_i; +#endif - /* create pipe for fifo */ - if ( ! extcap_create_pipe ( &interface_opts.extcap_fifo ) ) - return FALSE; + if (interface_opts.if_type == IF_EXTCAP ) + { + result = g_ptr_array_new(); - /* Create extcap call */ - args = g_ptr_array_new(); -#define add_arg(X) g_ptr_array_add(args, g_strdup(X)) +#define add_arg(X) g_ptr_array_add(result, g_strdup(X)) add_arg(interface_opts.extcap); add_arg(EXTCAP_ARGUMENT_RUN_CAPTURE); @@ -824,26 +768,62 @@ extcap_init_interfaces(capture_options *capture_opts) } else { - g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, args); + g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, result); } add_arg(NULL); #undef add_arg +#if ARG_DEBUG /* Dump commandline parameters sent to extcap. */ - for (tmp = (gchar **)args->pdata, tmp_i = 0; *tmp && **tmp; ++tmp_i, ++tmp) + for (tmp = (gchar **)result->pdata, tmp_i = 0; *tmp && **tmp; ++tmp_i, ++tmp) { g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", tmp_i, *tmp); } +#endif + + } - /* Wireshark for windows crashes here sometimes * - * Access violation reading location 0x... */ - g_spawn_async(NULL, (gchar **)args->pdata, NULL, - (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, - &pid,NULL); + return result; +} + +/* call mkfifo for each extcap, + * returns FALSE if there's an error creating a FIFO */ +gboolean +extcap_init_interfaces(capture_options *capture_opts) +{ + guint i; + interface_options interface_opts; + + for (i = 0; i < capture_opts->ifaces->len; i++) + { + GPtrArray *args = NULL; + GPid pid = INVALID_EXTCAP_PID; + + interface_opts = g_array_index(capture_opts->ifaces, interface_options, i); + + /* skip native interfaces */ + if (interface_opts.if_type != IF_EXTCAP ) + continue; + + /* create pipe for fifo */ + if ( ! extcap_create_pipe ( &interface_opts.extcap_fifo ) ) + return FALSE; + + /* Create extcap call */ + args = extcap_prepare_arguments(interface_opts); + + interface_opts.extcap_userdata = NULL; + + pid = extcap_spawn_async(&interface_opts, args ); g_ptr_array_foreach(args, (GFunc)g_free, NULL); g_ptr_array_free(args, TRUE); + + if ( pid == INVALID_EXTCAP_PID ) + continue; + interface_opts.extcap_pid = pid; + interface_opts.extcap_child_watch = g_child_watch_add(pid, extcap_child_watch_cb, (gpointer)capture_opts); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, i); @@ -861,60 +841,7 @@ extcap_init_interfaces(capture_options *capture_opts) */ if (pid != INVALID_EXTCAP_PID) { - DWORD dw; - HANDLE handles[2]; - OVERLAPPED ov; - ov.Pointer = 0; - ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - ConnectNamedPipe(pipe_h, &ov); - handles[0] = ov.hEvent; - handles[1] = pid; - - if (GetLastError() == ERROR_PIPE_CONNECTED) - { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap connected to pipe"); - } - else - { - dw = WaitForMultipleObjects(2, handles, FALSE, 30000); - if (dw == WAIT_OBJECT_0) - { - /* ConnectNamedPipe finished. */ - DWORD code; - - code = GetLastError(); - if (code == ERROR_IO_PENDING) - { - DWORD dummy; - if (!GetOverlappedResult(ov.hEvent, &ov, &dummy, TRUE)) - { - code = GetLastError(); - } - else - { - code = ERROR_SUCCESS; - } - } - - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "ConnectNamedPipe code: %d", code); - } - else if (dw == (WAIT_OBJECT_0 + 1)) - { - /* extcap process terminated. */ - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap terminated without connecting to pipe!"); - } - else if (dw == WAIT_TIMEOUT) - { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "extcap didn't connect to pipe within 30 seconds!"); - } - else - { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "WaitForMultipleObjects returned 0x%08X. Error %d", dw, GetLastError()); - } - } - - CloseHandle(ov.hEvent); + extcap_wait_for_pipe(pipe_h, pid); } #endif } |