Create C handles for pipes before running dumpcap.
authorGuy Harris <guy@alum.mit.edu>
Mon, 16 Nov 2015 22:33:32 +0000 (14:33 -0800)
committerGuy Harris <guy@alum.mit.edu>
Tue, 17 Nov 2015 08:08:44 +0000 (08:08 +0000)
If the C handles can't be created, there's no point in running dumpcap.

Catch some more possible _open_osfhandle() failures while we're at it.

Change-Id: I2b955378705fc932f8d383804e908e95a957be44
Ping-Bug: 11702
Reviewed-on: https://code.wireshark.org/review/11890
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
capchild/capture_sync.c

index 97777c63999c5bd19b1251f3af4f1b60864ef0e4..8273ee6dacf4eb8a9652a4b8ae5d4bb8654fe449 100644 (file)
@@ -363,6 +363,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
 #ifdef _WIN32
     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
     HANDLE sync_pipe_write;                 /* pipe used to send messages from child to parent */
+    int signal_pipe_write_fd;
     HANDLE signal_pipe;                     /* named pipe used to send messages from parent to child (currently only stop) */
     GString *args = g_string_sized_new(200);
     gchar *quoted_arg;
@@ -583,6 +584,26 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
         return FALSE;
     }
 
+    /*
+     * Associate a C run-time file handle with the Windows HANDLE for the
+     * read side of the message pipe.
+     *
+     * (See http://www.flounder.com/handles.htm for information on various
+     * types of file handle in C/C++ on Windows.)
+     */
+    sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
+    if (sync_pipe_read_fd == -1) {
+        /* Couldn't create the pipe between parent and child. */
+        report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
+        CloseHandle(sync_pipe_read);
+        CloseHandle(sync_pipe_write);
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
+        g_free(argv);
+        return FALSE;
+    }
+
     /* Create the signal pipe */
     signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
     signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
@@ -593,6 +614,8 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
         /* Couldn't create the signal pipe between parent and child. */
         report_failure("Couldn't create signal pipe: %s",
                        win32strerror(GetLastError()));
+        ws_close(sync_pipe_read_fd);    /* Should close sync_pipe_read */
+        CloseHandle(sync_pipe_write);
         for (i = 0; i < argc; i++) {
             g_free( (gpointer) argv[i]);
         }
@@ -600,6 +623,27 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
         return FALSE;
     }
 
+    /*
+     * Associate a C run-time file handle with the Windows HANDLE for the
+     * read side of the message pipe.
+     *
+     * (See http://www.flounder.com/handles.htm for information on various
+     * types of file handle in C/C++ on Windows.)
+     */
+    signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
+    if (sync_pipe_read_fd == -1) {
+        /* Couldn't create the pipe between parent and child. */
+        report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
+        ws_close(sync_pipe_read_fd);    /* Should close sync_pipe_read */
+        CloseHandle(sync_pipe_write);
+        CloseHandle(signal_pipe);
+        for (i = 0; i < argc; i++) {
+            g_free( (gpointer) argv[i]);
+        }
+        g_free(argv);
+        return FALSE;
+    }
+
     /* init STARTUPINFO */
     memset(&si, 0, sizeof(si));
     si.cb           = sizeof(si);
@@ -643,8 +687,9 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
         report_failure("Couldn't run %s in child process: %s",
                        args->str, win32strerror(GetLastError()));
-        CloseHandle(sync_pipe_read);
+        ws_close(sync_pipe_read_fd);    /* Should close sync_pipe_read */
         CloseHandle(sync_pipe_write);
+        CloseHandle(signal_pipe);
         for (i = 0; i < argc; i++) {
             g_free( (gpointer) argv[i]);
         }
@@ -654,12 +699,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
     cap_session->fork_child = pi.hProcess;
     g_string_free(args, TRUE);
 
-    /* associate the operating system filehandle to a C run-time file handle */
-    /* (good file handle infos at: http://www.flounder.com/handles.htm) */
-    sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
-
-    /* associate the operating system filehandle to a C run-time file handle */
-    cap_session->signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
+    cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
 
 #else /* _WIN32 */
     if (pipe(sync_pipe) < 0) {
@@ -812,13 +852,53 @@ sync_pipe_open_command(char** argv, int *data_read_fd,
         return -1;
     }
 
+    /*
+     * Associate a C run-time file handle with the Windows HANDLE for the
+     * read side of the message pipe.
+     *
+     * (See http://www.flounder.com/handles.htm for information on various
+     * types of file handle in C/C++ on Windows.)
+     */
+    *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
+    if (*message_read_fd == -1) {
+        *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
+        CloseHandle(sync_pipe[PIPE_READ]);
+        CloseHandle(sync_pipe[PIPE_WRITE]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
+        g_free( (gpointer) argv);
+        return -1;
+    }
+
     /* Create a pipe for the child process to send us data */
     /* (increase this value if you have trouble while fast capture file switches) */
     if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
         /* Couldn't create the message pipe between parent and child. */
         *msg = g_strdup_printf("Couldn't create data pipe: %s",
                                win32strerror(GetLastError()));
-        CloseHandle(sync_pipe[PIPE_READ]);
+        ws_close(*message_read_fd);    /* Should close sync_pipe[PIPE_READ] */
+        CloseHandle(sync_pipe[PIPE_WRITE]);
+        for (i = 0; argv[i] != NULL; i++) {
+            g_free( (gpointer) argv[i]);
+        }
+        g_free( (gpointer) argv);
+        return -1;
+    }
+
+    /*
+     * Associate a C run-time file handle with the Windows HANDLE for the
+     * read side of the data pipe.
+     *
+     * (See http://www.flounder.com/handles.htm for information on various
+     * types of file handle in C/C++ on Windows.)
+     */
+    *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
+    if (*data_read_fd == -1) {
+        *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
+        CloseHandle(data_pipe[PIPE_READ]);
+        CloseHandle(data_pipe[PIPE_WRITE]);
+        ws_close(*message_read_fd);    /* Should close sync_pipe[PIPE_READ] */
         CloseHandle(sync_pipe[PIPE_WRITE]);
         for (i = 0; argv[i] != NULL; i++) {
             g_free( (gpointer) argv[i]);
@@ -857,9 +937,9 @@ sync_pipe_open_command(char** argv, int *data_read_fd,
                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
         *msg = g_strdup_printf("Couldn't run %s in child process: %s",
                                args->str, win32strerror(GetLastError()));
-        CloseHandle(data_pipe[PIPE_READ]);
+        ws_close(*data_read_fd);       /* Should close data_pipe[PIPE_READ] */
         CloseHandle(data_pipe[PIPE_WRITE]);
-        CloseHandle(sync_pipe[PIPE_READ]);
+        ws_close(*message_read_fd);    /* Should close sync_pipe[PIPE_READ] */
         CloseHandle(sync_pipe[PIPE_WRITE]);
         for (i = 0; argv[i] != NULL; i++) {
             g_free( (gpointer) argv[i]);
@@ -869,35 +949,6 @@ sync_pipe_open_command(char** argv, int *data_read_fd,
     }
     *fork_child = pi.hProcess;
     g_string_free(args, TRUE);
-
-    /* associate the operating system filehandles to C run-time file handles */
-    /* (good file handle infos at: http://www.flounder.com/handles.htm) */
-    *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
-    if (*data_read_fd == -1) {
-        *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
-        CloseHandle(data_pipe[PIPE_READ]);
-        CloseHandle(data_pipe[PIPE_WRITE]);
-        CloseHandle(sync_pipe[PIPE_READ]);
-        CloseHandle(sync_pipe[PIPE_WRITE]);
-        for (i = 0; argv[i] != NULL; i++) {
-            g_free( (gpointer) argv[i]);
-        }
-        g_free( (gpointer) argv);
-        return -1;
-    }
-    *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
-    if (*message_read_fd == -1) {
-        *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
-        ws_close(*data_read_fd);    /* Should close data_pipe[PIPE_READ] */
-        CloseHandle(data_pipe[PIPE_WRITE]);
-        CloseHandle(sync_pipe[PIPE_READ]);
-        CloseHandle(sync_pipe[PIPE_WRITE]);
-        for (i = 0; argv[i] != NULL; i++) {
-            g_free( (gpointer) argv[i]);
-        }
-        g_free( (gpointer) argv);
-        return -1;
-    }
 #else /* _WIN32 */
     /* Create a pipe for the child process to send us messages */
     if (pipe(sync_pipe) < 0) {