diff options
author | Gerald Combs <gerald@wireshark.org> | 2016-04-27 12:14:11 -0700 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2016-04-27 23:11:34 +0000 |
commit | e5f4c5c8a80e2f5970b8c1d4fdfc29ab851f0e6f (patch) | |
tree | f1c26c89c7cae3dcc468508ab61a742853e7d631 /capchild | |
parent | ab6c9f2e2b8898a1592dafacd34cf1fff7ef20b3 (diff) |
Windows: Wait for dumpcap to initialize.
As the MSDN documentation says, "CreateProcess returns without waiting
for the new process to finish its initialization." Add an SP_INIT sync
pipe indicator on Windows and use it in dumpcap to signal to its parent
that it has started up.
Change-Id: I88a4c158871dbe2dd6eba13434e92c5d4b1c2e4b
Reviewed-on: https://code.wireshark.org/review/15132
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'capchild')
-rw-r--r-- | capchild/capture_sync.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c index edd0c5de7a..9d4ab636e2 100644 --- a/capchild/capture_sync.c +++ b/capchild/capture_sync.c @@ -98,12 +98,11 @@ #include <process.h> /* For spawning child process */ #endif - - #ifdef _WIN32 static void create_dummy_signal_pipe(); static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */ static gchar *dummy_control_id; +static gboolean pipe_wait_for_init(int pipe_fd); #else static const char *sync_pipe_signame(int); #endif @@ -696,6 +695,10 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf g_free( (gpointer) argv); return FALSE; } + if (!pipe_wait_for_init(sync_pipe_read_fd)) { + return FALSE; + } + cap_session->fork_child = pi.hProcess; /* We may need to store this and close it later */ CloseHandle(pi.hThread); @@ -950,6 +953,10 @@ sync_pipe_open_command(char** argv, int *data_read_fd, g_free( (gpointer) argv); return -1; } + if (!pipe_wait_for_init(*message_read_fd)) { + return -1; + } + *fork_child = pi.hProcess; /* We may need to store this and close it later */ CloseHandle(pi.hThread); @@ -1716,6 +1723,28 @@ pipe_convert_header(const guchar *header, int header_len, char *indicator, int * *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF); } +#ifdef _WIN32 +/* CreateProcess returns immediately. Wait for the child process to send + us SP_INIT. Note that WaitForInputIdle is the wrong call to use here + as it only applies to GUI applications: + https://blogs.msdn.microsoft.com/oldnewthing/20100325-00/?p=14493 + */ +gboolean +pipe_wait_for_init(int pipe_fd) { + char indicator; + char buffer[SP_MAX_MSG_LEN+1] = {0}; + char *primary_msg; + + pipe_read_block(pipe_fd, &indicator, SP_MAX_MSG_LEN, buffer, &primary_msg); + if (indicator != SP_INIT) { + report_failure("Child sent startup indicator '%c', expected '%c'.", + indicator, SP_INIT); + return FALSE; + } + return TRUE; +} +#endif + /* read a message from the sending pipe in the standard format (1-byte message indicator, 3-byte message length (excluding length and indicator field), and the rest is the message) */ |