#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
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);
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);
*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) */
* Win32 only: Indications sent out on the signal pipe (from parent to child)
* (UNIX-like sends signals for this)
*/
+#define SP_INIT 'I' /* child process initialized */
#define SP_QUIT 'Q' /* "gracefully" capture quit message (SIGUSR1) */
/* write a single message header to the recipient pipe */