Make the "-Z" argument to dumpcap take an argument that's the file
[obnox/wireshark/wip.git] / capture_sync.c
1 /* capture_sync.c
2  * Synchronisation between Wireshark capture parent and child instances
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <glib.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <string.h>
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #ifdef HAVE_FCNTL_H
41 #include <fcntl.h>
42 #endif
43
44 #include <signal.h>
45
46 #ifdef _WIN32
47 #include "epan/unicode-utils.h"
48 #endif
49
50 #ifdef HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
52 #endif
53
54 #include "capture-pcap-util.h"
55
56 #ifndef _WIN32
57 /*
58  * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
59  * macros) on UNIX systems that don't have them.
60  */
61 #ifndef WIFEXITED
62 # define WIFEXITED(status)      (((status) & 0177) == 0)
63 #endif
64 #ifndef WIFSTOPPED
65 # define WIFSTOPPED(status)     (((status) & 0177) == 0177)
66 #endif
67 #ifndef WIFSIGNALED
68 # define WIFSIGNALED(status)    (!WIFSTOPPED(status) && !WIFEXITED(status))
69 #endif
70 #ifndef WEXITSTATUS
71 # define WEXITSTATUS(status)    ((status) >> 8)
72 #endif
73 #ifndef WTERMSIG
74 # define WTERMSIG(status)       ((status) & 0177)
75 #endif
76 #ifndef WCOREDUMP
77 # define WCOREDUMP(status)      ((status) & 0200)
78 #endif
79 #ifndef WSTOPSIG
80 # define WSTOPSIG(status)       ((status) >> 8)
81 #endif
82 #endif /* _WIN32 */
83
84 #include <epan/packet.h>
85 #include <epan/prefs.h>
86
87 #include "globals.h"
88 #include "file.h"
89 #include <epan/filesystem.h>
90
91 #include "capture.h"
92 #include "capture_sync.h"
93 #include "simple_dialog.h"
94
95 #include "sync_pipe.h"
96
97 #ifdef _WIN32
98 #include "capture-wpcap.h"
99 #endif
100 #include "ui_util.h"
101 #include "file_util.h"
102 #include "log.h"
103
104 #ifdef _WIN32
105 #include <process.h>    /* For spawning child process */
106 #endif
107
108
109
110 #ifndef _WIN32
111 static const char *sync_pipe_signame(int);
112 #endif
113
114
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static void sync_pipe_wait_for_child(capture_options *capture_opts);
117
118
119
120 /* Append an arg (realloc) to an argc/argv array */
121 /* (add a string pointer to a NULL-terminated array of string pointers) */
122 static const char **
123 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
124 {
125   /* Grow the array; "*argc" currently contains the number of string
126      pointers, *not* counting the NULL pointer at the end, so we have
127      to add 2 in order to get the new size of the array, including the
128      new pointer and the terminating NULL pointer. */
129   args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
130
131   /* Stuff the pointer into the penultimate element of the array, which
132      is the one at the index specified by "*argc". */
133   args[*argc] = arg;
134
135   /* Now bump the count. */
136   (*argc)++;
137
138   /* We overwrite the NULL pointer; put it back right after the
139      element we added. */
140   args[*argc] = NULL;
141
142   return args;
143 }
144
145
146
147 #ifdef _WIN32
148 /* Quote the argument element if necessary, so that it will get
149  * reconstructed correctly in the C runtime startup code.  Note that
150  * the unquoting algorithm in the C runtime is really weird, and
151  * rather different than what Unix shells do. See stdargv.c in the C
152  * runtime sources (in the Platform SDK, in src/crt).
153  *
154  * Stolen from GLib's protect_argv(), an internal routine that quotes
155  * string in an argument list so that they arguments will be handled
156  * correctly in the command-line string passed to CreateProcess()
157  * if that string is constructed by gluing those strings together.
158  */
159 static gchar *
160 protect_arg (const gchar *argv)
161 {
162     gchar *new_arg;
163     const gchar *p = argv;
164     gchar *q;
165     gint len = 0;
166     gboolean need_dblquotes = FALSE;
167
168     while (*p) {
169         if (*p == ' ' || *p == '\t')
170             need_dblquotes = TRUE;
171         else if (*p == '"')
172             len++;
173         else if (*p == '\\') {
174             const gchar *pp = p;
175
176             while (*pp && *pp == '\\')
177                 pp++;
178             if (*pp == '"')
179                 len++;
180         }
181         len++;
182         p++;
183     }
184
185     q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
186     p = argv;
187
188     if (need_dblquotes)
189         *q++ = '"';
190
191     while (*p) {
192         if (*p == '"')
193             *q++ = '\\';
194         else if (*p == '\\') {
195             const gchar *pp = p;
196
197             while (*pp && *pp == '\\')
198                 pp++;
199             if (*pp == '"')
200                 *q++ = '\\';
201         }
202         *q++ = *p;
203         p++;
204     }
205
206     if (need_dblquotes)
207         *q++ = '"';
208     *q++ = '\0';
209
210     return new_arg;
211 }
212 #endif
213
214 /* Initialize an argument list and add dumpcap to it. */
215 static const char **
216 init_pipe_args(int *argc) {
217     const char **argv;
218     const char *progfile_dir;
219     char *exename;
220
221     progfile_dir = get_progfile_dir();
222     if (progfile_dir == NULL) {
223       return NULL;
224     }
225
226     /* Allocate the string pointer array with enough space for the
227        terminating NULL pointer. */
228     *argc = 0;
229     argv = g_malloc(sizeof (char *));
230     *argv = NULL;
231
232     /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
233     exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
234
235     /* Make that the first argument in the argument list (argv[0]). */
236     argv = sync_pipe_add_arg(argv, argc, exename);
237
238     return argv;
239 }
240
241 #define ARGV_NUMBER_LEN 24
242 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
243 gboolean
244 sync_pipe_start(capture_options *capture_opts) {
245     char ssnap[ARGV_NUMBER_LEN];
246     char scount[ARGV_NUMBER_LEN];
247     char sfilesize[ARGV_NUMBER_LEN];
248     char sfile_duration[ARGV_NUMBER_LEN];
249     char sring_num_files[ARGV_NUMBER_LEN];
250     char sautostop_files[ARGV_NUMBER_LEN];
251     char sautostop_filesize[ARGV_NUMBER_LEN];
252     char sautostop_duration[ARGV_NUMBER_LEN];
253 #ifdef _WIN32
254     char buffer_size[ARGV_NUMBER_LEN];
255     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
256     HANDLE sync_pipe_write;                 /* pipe used to send messages from child to parent */
257     HANDLE signal_pipe_read;                /* pipe used to send messages from parent to child (currently only stop) */
258     HANDLE signal_pipe_write;               /* pipe used to send messages from parent to child (currently only stop) */
259     GString *args = g_string_sized_new(200);
260     gchar *quoted_arg;
261     SECURITY_ATTRIBUTES sa;
262     STARTUPINFO si;
263     PROCESS_INFORMATION pi;
264     int i;
265 #else
266     char errmsg[1024+1];
267     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
268     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
269 #endif
270     int sync_pipe_read_fd;
271     int argc;
272     const char **argv;
273
274
275     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
276     capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
277
278     capture_opts->fork_child = -1;
279
280     argv = init_pipe_args(&argc);
281     if (!argv) {
282         /* We don't know where to find dumpcap. */
283         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
284         return FALSE;
285     }
286
287     argv = sync_pipe_add_arg(argv, &argc, "-i");
288     argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
289
290     if (capture_opts->has_snaplen) {
291       argv = sync_pipe_add_arg(argv, &argc, "-s");
292       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
293       argv = sync_pipe_add_arg(argv, &argc, ssnap);
294     }
295
296     if (capture_opts->linktype != -1) {
297       argv = sync_pipe_add_arg(argv, &argc, "-y");
298 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
299       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
300 #else
301       /* we can't get the type name, just treat it as a number */
302       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
303 #endif
304       argv = sync_pipe_add_arg(argv, &argc, ssnap);
305     }
306
307     if(capture_opts->multi_files_on) {
308       if (capture_opts->has_autostop_filesize) {
309         argv = sync_pipe_add_arg(argv, &argc, "-b");
310         g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
311         argv = sync_pipe_add_arg(argv, &argc, sfilesize);
312       }
313
314       if (capture_opts->has_file_duration) {
315         argv = sync_pipe_add_arg(argv, &argc, "-b");
316         g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
317         argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
318       }
319
320       if (capture_opts->has_ring_num_files) {
321         argv = sync_pipe_add_arg(argv, &argc, "-b");
322         g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
323         argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
324       }
325
326       if (capture_opts->has_autostop_files) {
327         argv = sync_pipe_add_arg(argv, &argc, "-a");
328         g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
329         argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
330       }
331     } else {
332         if (capture_opts->has_autostop_filesize) {
333           argv = sync_pipe_add_arg(argv, &argc, "-a");
334           g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
335           argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
336         }
337     }
338
339     if (capture_opts->has_autostop_packets) {
340       argv = sync_pipe_add_arg(argv, &argc, "-c");
341       g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
342       argv = sync_pipe_add_arg(argv, &argc, scount);
343     }
344
345     if (capture_opts->has_autostop_duration) {
346       argv = sync_pipe_add_arg(argv, &argc, "-a");
347       g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
348       argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
349     }
350
351     if (!capture_opts->promisc_mode)
352       argv = sync_pipe_add_arg(argv, &argc, "-p");
353
354     /* dumpcap should be running in capture child mode (hidden feature) */
355 #ifndef DEBUG_CHILD
356     argv = sync_pipe_add_arg(argv, &argc, "-Z");
357     argv = sync_pipe_add_arg(argv, &argc, "1");
358 #endif
359
360 #ifdef _WIN32
361     argv = sync_pipe_add_arg(argv, &argc, "-B");
362     g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
363     argv = sync_pipe_add_arg(argv, &argc, buffer_size);
364 #endif
365
366     if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
367       argv = sync_pipe_add_arg(argv, &argc, "-f");
368       argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
369     }
370
371     if(capture_opts->save_file) {
372       argv = sync_pipe_add_arg(argv, &argc, "-w");
373       argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
374     }
375
376 #ifdef _WIN32
377     /* init SECURITY_ATTRIBUTES */
378     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
379     sa.bInheritHandle = TRUE;
380     sa.lpSecurityDescriptor = NULL;
381
382     /* Create a pipe for the child process */
383     /* (inrease this value if you have trouble while fast capture file switches) */
384     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
385       /* Couldn't create the pipe between parent and child. */
386       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
387                         strerror(errno));
388       g_free( (gpointer) argv[0]);
389       g_free( (gpointer) argv);
390       return FALSE;
391     }
392
393     /* Create a pipe for the parent process */
394     if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
395       /* Couldn't create the signal pipe between parent and child. */
396       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
397                         strerror(errno));
398       CloseHandle(sync_pipe_read);
399       CloseHandle(sync_pipe_write);
400       g_free( (gpointer) argv[0]);
401       g_free( (gpointer) argv);
402       return FALSE;
403     }
404
405     /* init STARTUPINFO */
406     memset(&si, 0, sizeof(si));
407     si.cb           = sizeof(si);
408 #ifdef DEBUG_CHILD
409     si.dwFlags = STARTF_USESHOWWINDOW;
410     si.wShowWindow  = SW_SHOW;
411 #else
412     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
413     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
414     si.hStdInput = signal_pipe_read;
415     si.hStdOutput = sync_pipe_write;
416     si.hStdError = sync_pipe_write;
417     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
418 #endif
419
420     /* convert args array into a single string */
421     /* XXX - could change sync_pipe_add_arg() instead */
422     /* there is a drawback here: the length is internally limited to 1024 bytes */
423     for(i=0; argv[i] != 0; i++) {
424         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
425         quoted_arg = protect_arg(argv[i]);
426         g_string_append(args, quoted_arg);
427         g_free(quoted_arg);
428     }
429
430     /* call dumpcap */
431     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
432                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
433       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
434                     "Couldn't run %s in child process: error %u",
435                     args->str, GetLastError());
436       CloseHandle(sync_pipe_read);
437       CloseHandle(sync_pipe_write);
438       g_free( (gpointer) argv[0]);
439       g_free( (gpointer) argv);
440       return FALSE;
441     }
442     capture_opts->fork_child = (int) pi.hProcess;
443     g_string_free(args, TRUE);
444
445     /* associate the operating system filehandle to a C run-time file handle */
446     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
447     sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
448
449     /* associate the operating system filehandle to a C run-time file handle */
450     capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
451
452     /* child owns the read side now, close our handle */
453     CloseHandle(signal_pipe_read);
454 #else /* _WIN32 */
455     if (pipe(sync_pipe) < 0) {
456       /* Couldn't create the pipe between parent and child. */
457       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
458                         strerror(errno));
459       g_free( (gpointer) argv[0]);
460       g_free(argv);
461       return FALSE;
462     }
463
464     if ((capture_opts->fork_child = fork()) == 0) {
465       /*
466        * Child process - run dumpcap with the right arguments to make
467        * it just capture with the specified capture parameters
468        */
469       eth_close(1);
470       dup(sync_pipe[PIPE_WRITE]);
471       eth_close(sync_pipe[PIPE_READ]);
472       execv(argv[0], (gpointer)argv);
473       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
474                 argv[0], strerror(errno));
475       sync_pipe_errmsg_to_parent(1, errmsg, "");
476
477       /* Exit with "_exit()", so that we don't close the connection
478          to the X server (and cause stuff buffered up by our parent but
479          not yet sent to be sent, as that stuff should only be sent by
480          our parent). */
481       _exit(2);
482     }
483
484     sync_pipe_read_fd = sync_pipe[PIPE_READ];
485 #endif
486
487     g_free( (gpointer) argv[0]);  /* exename */
488
489     /* Parent process - read messages from the child process over the
490        sync pipe. */
491     g_free( (gpointer) argv);   /* free up arg array */
492
493     /* Close the write side of the pipe, so that only the child has it
494        open, and thus it completely closes, and thus returns to us
495        an EOF indication, if the child closes it (either deliberately
496        or by exiting abnormally). */
497 #ifdef _WIN32
498     CloseHandle(sync_pipe_write);
499 #else
500     eth_close(sync_pipe[PIPE_WRITE]);
501 #endif
502
503     if (capture_opts->fork_child == -1) {
504       /* We couldn't even create the child process. */
505       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
506                         "Couldn't create child process: %s", strerror(errno));
507       eth_close(sync_pipe_read_fd);
508 #ifdef _WIN32
509       eth_close(capture_opts->signal_pipe_write_fd);
510 #endif
511       return FALSE;
512     }
513
514     /* we might wait for a moment till child is ready, so update screen now */
515     main_window_update();
516
517     /* We were able to set up to read the capture file;
518        arrange that our callback be called whenever it's possible
519        to read from the sync pipe, so that it's called when
520        the child process wants to tell us something. */
521
522     /* we have a running capture, now wait for the real capture filename */
523     pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
524         &capture_opts->fork_child, sync_pipe_input_cb);
525
526     return TRUE;
527 }
528
529 /*
530  * Open dumpcap with the supplied arguments.  On success, msg points to
531  * a buffer containing the dumpcap output and returns 0.  read_fd and
532  * fork_child point to the pipe's file descriptor and child PID/handle,
533  * respectively.  On failure, msg points to the error message returned by
534  * dumpcap, and returns dumpcap's exit value.  In either case, msg must be
535  * freed with g_free().
536  */
537 /* XXX - This duplicates a lot of code in sync_pipe_start() */
538 #define PIPE_BUF_SIZE 5120
539 static int
540 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
541 #ifdef _WIN32
542     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
543     HANDLE sync_pipe_write;                 /* pipe used to send messages from parent to child */
544     GString *args = g_string_sized_new(200);
545     gchar *quoted_arg;
546     SECURITY_ATTRIBUTES sa;
547     STARTUPINFO si;
548     PROCESS_INFORMATION pi;
549     int i;
550 #else
551     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
552     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
553 #endif
554
555     *fork_child = -1;
556     *read_fd = -1;
557     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
558
559     if (!msg) {
560         /* We can't return anything */
561 #ifdef _WIN32
562         g_string_free(args, TRUE);
563 #endif
564         return -1;
565     }
566
567 #ifdef _WIN32
568     /* init SECURITY_ATTRIBUTES */
569     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
570     sa.bInheritHandle = TRUE;
571     sa.lpSecurityDescriptor = NULL;
572
573     /* Create a pipe for the child process */
574     /* (inrease this value if you have trouble while fast capture file switches) */
575     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
576         /* Couldn't create the pipe between parent and child. */
577         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
578         g_free( (gpointer) argv[0]);
579         g_free( (gpointer) argv);
580         return CANT_RUN_DUMPCAP;
581     }
582
583     /* init STARTUPINFO */
584     memset(&si, 0, sizeof(si));
585     si.cb           = sizeof(si);
586 #ifdef DEBUG_CHILD
587     si.dwFlags = STARTF_USESHOWWINDOW;
588     si.wShowWindow  = SW_SHOW;
589 #else
590     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
591     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
592     si.hStdInput = NULL;
593     si.hStdOutput = sync_pipe_write;
594     si.hStdError = sync_pipe_write;
595     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
596 #endif
597
598     /* convert args array into a single string */
599     /* XXX - could change sync_pipe_add_arg() instead */
600     /* there is a drawback here: the length is internally limited to 1024 bytes */
601     for(i=0; argv[i] != 0; i++) {
602         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
603         quoted_arg = protect_arg(argv[i]);
604         g_string_append(args, quoted_arg);
605         g_free(quoted_arg);
606     }
607
608     /* call dumpcap */
609     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
610                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
611         *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
612                         args->str, GetLastError());
613         CloseHandle(sync_pipe_read);
614         CloseHandle(sync_pipe_write);
615         g_free( (gpointer) argv[0]);
616         g_free( (gpointer) argv);
617         return CANT_RUN_DUMPCAP;
618     }
619     *fork_child = (int) pi.hProcess;
620     g_string_free(args, TRUE);
621
622     /* associate the operating system filehandle to a C run-time file handle */
623     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
624     *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
625
626 #else /* _WIN32 */
627     if (pipe(sync_pipe) < 0) {
628         /* Couldn't create the pipe between parent and child. */
629         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
630         g_free( (gpointer) argv[0]);
631         g_free(argv);
632         return CANT_RUN_DUMPCAP;
633     }
634
635     if ((*fork_child = fork()) == 0) {
636         /*
637          * Child process - run dumpcap with the right arguments to make
638          * it just capture with the specified capture parameters
639          */
640         eth_close(1);
641         dup(sync_pipe[PIPE_WRITE]);
642         eth_close(sync_pipe[PIPE_READ]);
643         execv(argv[0], (gpointer)argv);
644         *msg = g_strdup_printf("Couldn't run %s in child process: %s",
645                 argv[0], strerror(errno));
646         return CANT_RUN_DUMPCAP;
647     }
648
649     *read_fd = sync_pipe[PIPE_READ];
650 #endif
651
652     g_free( (gpointer) argv[0]);  /* exename */
653
654     /* Parent process - read messages from the child process over the
655        sync pipe. */
656     g_free( (gpointer) argv);   /* free up arg array */
657
658     /* Close the write side of the pipe, so that only the child has it
659        open, and thus it completely closes, and thus returns to us
660        an EOF indication, if the child closes it (either deliberately
661        or by exiting abnormally). */
662 #ifdef _WIN32
663     CloseHandle(sync_pipe_write);
664 #else
665     eth_close(sync_pipe[PIPE_WRITE]);
666 #endif
667
668     if (*fork_child == -1) {
669         /* We couldn't even create the child process. */
670         *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
671         eth_close(*read_fd);
672         return CANT_RUN_DUMPCAP;
673     }
674
675     /* we might wait for a moment till child is ready, so update screen now */
676     main_window_update();
677     return 0;
678 }
679
680 static int
681 #ifdef _WIN32
682 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
683 #else
684 sync_pipe_close_command(int *read_fd, gchar **msg) {
685 #endif
686     int fork_child_status;
687
688     eth_close(*read_fd);
689
690     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open: wait till child closed");
691
692 #ifdef _WIN32
693     /* XXX - Should we signal the child somehow? */
694     sync_pipe_kill(*fork_child);
695     if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
696         *msg = g_strdup_printf("Child capture process stopped unexpectedly "
697             "(errno:%u)", errno);
698         return CANT_RUN_DUMPCAP;
699     }
700 #else
701     if (wait(&fork_child_status) != -1) {
702         if (WIFEXITED(fork_child_status)) {
703             /* The child exited. */
704             fork_child_status = WEXITSTATUS(fork_child_status);
705         } else {
706             if (WIFSTOPPED(fork_child_status)) {
707                 /* It stopped, rather than exiting.  "Should not happen." */
708                 *msg = g_strdup_printf("Child capture process stopped: %s",
709                     sync_pipe_signame(WSTOPSIG(fork_child_status)));
710             } else if (WIFSIGNALED(fork_child_status)) {
711                 /* It died with a signal. */
712                 *msg = g_strdup_printf("Child capture process died: %s%s",
713                     sync_pipe_signame(WTERMSIG(fork_child_status)),
714                     WCOREDUMP(fork_child_status) ? " - core dumped" : "");
715             } else {
716                 /* What?  It had to either have exited, or stopped, or died with
717                    a signal; what happened here? */
718                 *msg = g_strdup_printf("Child capture process died: wait status %#o",
719                     fork_child_status);
720             }
721             return CANT_RUN_DUMPCAP;
722         }
723     } else {
724       *msg = g_strdup_printf("Child capture process stopped unexpectedly "
725         "(errno:%u)", errno);
726       return CANT_RUN_DUMPCAP;
727     }
728 #endif
729     return 0;
730 }
731
732 /*
733  * Run dumpcap with the supplied arguments.  On success, msg points to
734  * a buffer containing the dumpcap output and returns 0.  On failure, msg
735  * points to the error message returned by dumpcap, and returns dumpcap's
736  * exit value.  In either case, msg must be freed with g_free().
737  */
738 /* XXX - This duplicates a lot of code in sync_pipe_start() */
739 #define PIPE_BUF_SIZE 5120
740 static int
741 sync_pipe_run_command(const char** argv, gchar **msg) {
742     int sync_pipe_read_fd, fork_child, ret;
743     gchar buf[PIPE_BUF_SIZE+1];
744     GString *msg_buf = NULL;
745     int count;
746
747     ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
748
749     if (ret)
750         return ret;
751
752     /* We were able to set up to read dumpcap's output.  Do so and
753        return its exit value. */
754     msg_buf = g_string_new("");
755     while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
756         buf[count] = '\0';
757         g_string_append(msg_buf, buf);
758     }
759
760 #ifdef _WIN32
761     ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
762 #else
763     ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
764 #endif
765
766     if (ret) {
767         g_string_free(msg_buf, TRUE);
768         return ret;
769     }
770
771     *msg = msg_buf->str;
772     g_string_free(msg_buf, FALSE);
773     return 0;
774 }
775
776 /*
777  * Get an interface list using dumpcap.  On success, msg points to
778  * a buffer containing the dumpcap output and returns 0.  On failure, msg
779  * points to the error message returned by dumpcap, and returns dumpcap's
780  * exit value.  In either case, msg must be freed with g_free().
781  */
782 int
783 sync_interface_list_open(gchar **msg) {
784     int argc;
785     const char **argv;
786
787     if (!msg) {
788         /* We can't return anything */
789         return -1;
790     }
791
792     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
793
794     argv = init_pipe_args(&argc);
795
796     if (!argv) {
797         *msg = g_strdup_printf("We don't know where to find dumpcap.");
798         return CANT_RUN_DUMPCAP;
799     }
800
801     /* Ask for the interface list */
802     argv = sync_pipe_add_arg(argv, &argc, "-D");
803     argv = sync_pipe_add_arg(argv, &argc, "-M");
804
805     /* dumpcap should be running in capture child mode (hidden feature) */
806 #ifndef DEBUG_CHILD
807     argv = sync_pipe_add_arg(argv, &argc, "-Z");
808     argv = sync_pipe_add_arg(argv, &argc, "1");
809 #endif
810
811     return sync_pipe_run_command(argv, msg);
812 }
813
814 /*
815  * Get an linktype list using dumpcap.  On success, msg points to
816  * a buffer containing the dumpcap output and returns 0.  On failure, msg
817  * points to the error message returned by dumpcap, and returns dumpcap's
818  * exit value.  In either case, msg must be freed with g_free().
819  */
820 int
821 sync_linktype_list_open(gchar *ifname, gchar **msg) {
822     int argc;
823     const char **argv;
824
825     if (!msg) {
826         /* We can't return anything */
827         return -1;
828     }
829
830     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
831
832     argv = init_pipe_args(&argc);
833
834     if (!argv) {
835         *msg = g_strdup_printf("We don't know where to find dumpcap.");
836         return CANT_RUN_DUMPCAP;
837     }
838
839     /* Ask for the linktype list */
840     argv = sync_pipe_add_arg(argv, &argc, "-i");
841     argv = sync_pipe_add_arg(argv, &argc, ifname);
842     argv = sync_pipe_add_arg(argv, &argc, "-L");
843     argv = sync_pipe_add_arg(argv, &argc, "-M");
844
845     /* dumpcap should be running in capture child mode (hidden feature) */
846 #ifndef DEBUG_CHILD
847     argv = sync_pipe_add_arg(argv, &argc, "-Z");
848     argv = sync_pipe_add_arg(argv, &argc, "1");
849 #endif
850
851     return sync_pipe_run_command(argv, msg);
852 }
853
854 /*
855  * Start getting interface statistics using dumpcap.  On success, read_fd
856  * contains the file descriptor for the pipe's stdout, msg is unchanged,
857  * and zero is returned.  On failure, msg will point to an error message
858  * that must be g_free()d and a nonzero error value will be returned.
859  */
860 int
861 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
862     int argc;
863     const char **argv;
864
865     if (!msg) {
866         /* We can't return anything */
867         return -1;
868     }
869
870     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
871
872     argv = init_pipe_args(&argc);
873
874     if (!argv) {
875         *msg = g_strdup_printf("We don't know where to find dumpcap.");
876         return CANT_RUN_DUMPCAP;
877     }
878
879     /* Ask for the linktype list */
880     argv = sync_pipe_add_arg(argv, &argc, "-S");
881     argv = sync_pipe_add_arg(argv, &argc, "-M");
882
883     /* dumpcap should be running in capture child mode (hidden feature) */
884 #ifndef DEBUG_CHILD
885     argv = sync_pipe_add_arg(argv, &argc, "-Z");
886     argv = sync_pipe_add_arg(argv, &argc, "1");
887 #endif
888
889     return sync_pipe_open_command(argv, read_fd, fork_child, msg);
890 }
891
892 /* Close down the stats process */
893 int
894 sync_interface_stats_close(int *read_fd, int *fork_child
895 #ifndef _WIN32
896 _U_
897 #endif
898 , gchar **msg) {
899 #ifdef _WIN32
900     return sync_pipe_close_command(read_fd, fork_child, msg);
901 #else
902     return sync_pipe_close_command(read_fd, msg);
903 #endif
904 }
905
906 /* read a number of bytes from a pipe */
907 /* (blocks until enough bytes read or an error occurs) */
908 static int
909 pipe_read_bytes(int pipe, char *bytes, int required) {
910     int newly;
911     int offset = 0;
912
913     while(required) {
914         newly = read(pipe, &bytes[offset], required);
915         if (newly == 0) {
916             /* EOF */
917             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
918                   "read from pipe %d: EOF (capture closed?)", pipe);
919             return offset;
920         }
921         if (newly < 0) {
922             /* error */
923             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
924                   "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
925             return newly;
926         }
927
928         required -= newly;
929         offset += newly;
930     }
931
932     return offset;
933 }
934
935 static gboolean pipe_data_available(int pipe) {
936 #ifdef _WIN32 /* PeekNamedPipe */
937     HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
938     DWORD bytes_avail;
939
940     if (hPipe == INVALID_HANDLE_VALUE)
941         return FALSE;
942
943     if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
944         return FALSE;
945
946     if (bytes_avail > 0)
947         return TRUE;
948     return FALSE;
949 #else /* select */
950     fd_set rfds;
951     struct timeval timeout;
952
953     FD_ZERO(&rfds);
954     FD_SET(pipe, &rfds);
955     timeout.tv_sec = 0;
956     timeout.tv_usec = 0;
957
958     if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
959         return TRUE;
960
961     return FALSE;
962 #endif
963 }
964
965 /* Read a line from a pipe, similar to fgets */
966 int
967 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
968     int newly;
969     int offset = -1;
970
971     while(offset < max - 1) {
972         offset++;
973         if (! pipe_data_available(pipe))
974             break;
975         newly = read(pipe, &bytes[offset], 1);
976         if (newly == 0) {
977             /* EOF - not necessarily an error */
978             break;
979         } else if (newly < 0) {
980             /* error */
981             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
982                   "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
983             return newly;
984         } else if (bytes[offset] == '\n') {
985             break;
986         }
987     }
988
989     if (offset >= 0)
990         bytes[offset] = '\0';
991
992     return offset;
993 }
994
995
996 /* convert header values (indicator and 4-byte length) */
997 static void
998 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
999
1000     g_assert(header_len == 4);
1001
1002     /* convert header values */
1003     *indicator = header[0];
1004     *block_len = header[1]<<16 | header[2]<<8 | header[3];
1005 }
1006
1007 /* read a message from the sending pipe in the standard format
1008    (1-byte message indicator, 3-byte message length (excluding length
1009    and indicator field), and the rest is the message) */
1010 static int
1011 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1012     int required;
1013     int newly;
1014     guchar header[4];
1015
1016
1017     /* read header (indicator and 3-byte length) */
1018     newly = pipe_read_bytes(pipe, header, 4);
1019     if(newly != 4) {
1020         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1021               "read %d failed to read header: %u", pipe, newly);
1022         return -1;
1023     }
1024
1025     /* convert header values */
1026     pipe_convert_header(header, 4, indicator, &required);
1027
1028     /* only indicator with no value? */
1029     if(required == 0) {
1030         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1031               "read %d indicator: %c empty value", pipe, *indicator);
1032         return 4;
1033     }
1034
1035     /* does the data fit into the given buffer? */
1036     if(required > len) {
1037         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1038               "read %d length error, required %d > len %d, indicator: %u",
1039               pipe, required, len, *indicator);
1040
1041         /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1042         memcpy(msg, header, sizeof(header));
1043         newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1044         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1045         return -1;
1046     }
1047     len = required;
1048
1049     /* read the actual block data */
1050     newly = pipe_read_bytes(pipe, msg, required);
1051     if(newly != required) {
1052         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1053         return -1;
1054     }
1055
1056     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1057           "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1058           len, msg);
1059     return newly + 4;
1060 }
1061
1062
1063 /* There's stuff to read from the sync pipe, meaning the child has sent
1064    us a message, or the sync pipe has closed, meaning the child has
1065    closed it (perhaps because it exited). */
1066 static gboolean
1067 sync_pipe_input_cb(gint source, gpointer user_data)
1068 {
1069   capture_options *capture_opts = (capture_options *)user_data;
1070   char buffer[SP_MAX_MSG_LEN+1];
1071   int  nread;
1072   char indicator;
1073   int  primary_len;
1074   char * primary_msg;
1075   int  secondary_len;
1076   char * secondary_msg;
1077
1078
1079   nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1080   if(nread <= 0) {
1081     if (nread == 0)
1082       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1083             "sync_pipe_input_cb: child has closed sync_pipe");
1084     else
1085       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1086             "sync_pipe_input_cb: error reading from sync pipe");
1087
1088     /* The child has closed the sync pipe, meaning it's not going to be
1089        capturing any more packets.  Pick up its exit status, and
1090        complain if it did anything other than exit with status 0.
1091
1092        We don't have to worry about killing the child, if the sync pipe
1093        returned an error. Usually this error is caused as the child killed itself
1094        while going down. Even in the rare cases that this isn't the case,
1095        the child will get an error when writing to the broken pipe the next time,
1096        cleaning itself up then. */
1097     sync_pipe_wait_for_child(capture_opts);
1098
1099 #ifdef _WIN32
1100     eth_close(capture_opts->signal_pipe_write_fd);
1101 #endif
1102     capture_input_closed(capture_opts);
1103     return FALSE;
1104   }
1105
1106   /* we got a valid message block from the child, process it */
1107   switch(indicator) {
1108   case SP_FILE:
1109     if(!capture_input_new_file(capture_opts, buffer)) {
1110       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1111
1112       /* We weren't able to open the new capture file; user has been
1113          alerted. Close the sync pipe. */
1114       eth_close(source);
1115
1116       /* the child has send us a filename which we couldn't open.
1117          this probably means, the child is creating files faster than we can handle it.
1118          this should only be the case for very fast file switches
1119          we can't do much more than telling the child to stop
1120          (this is the "emergency brake" if user e.g. wants to switch files every second) */
1121       sync_pipe_stop(capture_opts);
1122     }
1123     break;
1124   case SP_PACKET_COUNT:
1125     nread = atoi(buffer);
1126     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1127     capture_input_new_packets(capture_opts, nread);
1128     break;
1129   case SP_ERROR_MSG:
1130     /* convert primary message */
1131     pipe_convert_header(buffer, 4, &indicator, &primary_len);
1132     primary_msg = buffer+4;
1133     /* convert secondary message */
1134     pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1135     secondary_msg = primary_msg + primary_len + 4;
1136     /* message output */
1137     capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1138     /* the capture child will close the sync_pipe, nothing to do for now */
1139     /* (an error message doesn't mean we have to stop capturing) */
1140     break;
1141   case SP_BAD_FILTER:
1142     capture_input_cfilter_error_message(capture_opts, buffer);
1143     /* the capture child will close the sync_pipe, nothing to do for now */
1144     break;
1145   case SP_DROPS:
1146     capture_input_drops(capture_opts, atoi(buffer));
1147     break;
1148   default:
1149     g_assert_not_reached();
1150   }
1151
1152   return TRUE;
1153 }
1154
1155
1156
1157 /* the child process is going down, wait until it's completely terminated */
1158 static void
1159 sync_pipe_wait_for_child(capture_options *capture_opts)
1160 {
1161   int  wstatus;
1162
1163
1164   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1165   g_assert(capture_opts->fork_child != -1);
1166
1167 #ifdef _WIN32
1168   if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1169     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1170                 "Child capture process stopped unexpectedly (errno:%u)", errno);
1171   }
1172 #else
1173   if (wait(&wstatus) != -1) {
1174     if (WIFEXITED(wstatus)) {
1175       /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1176       /* the child will inform us about errors through the sync_pipe, which will popup */
1177       /* an error message, so don't popup another one */
1178
1179       /* If there are situations where the child won't send us such an error message, */
1180       /* this should be fixed in the child and not here! */
1181       if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1182         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1183                       "Child capture process exited: exit status %d",
1184                       WEXITSTATUS(wstatus));
1185       }
1186     } else if (WIFSTOPPED(wstatus)) {
1187       /* It stopped, rather than exiting.  "Should not happen." */
1188       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1189                     "Child capture process stopped: %s",
1190                     sync_pipe_signame(WSTOPSIG(wstatus)));
1191     } else if (WIFSIGNALED(wstatus)) {
1192       /* It died with a signal. */
1193       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1194                     "Child capture process died: %s%s",
1195                     sync_pipe_signame(WTERMSIG(wstatus)),
1196                     WCOREDUMP(wstatus) ? " - core dumped" : "");
1197     } else {
1198       /* What?  It had to either have exited, or stopped, or died with
1199          a signal; what happened here? */
1200       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1201                     "Child capture process died: wait status %#o", wstatus);
1202     }
1203   }
1204 #endif
1205
1206   /* No more child process. */
1207   capture_opts->fork_child = -1;
1208
1209   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1210 }
1211
1212
1213 #ifndef _WIN32
1214 /* convert signal to corresponding name */
1215 static const char *
1216 sync_pipe_signame(int sig)
1217 {
1218   const char *sigmsg;
1219   static char sigmsg_buf[6+1+3+1];
1220
1221   switch (sig) {
1222
1223   case SIGHUP:
1224     sigmsg = "Hangup";
1225     break;
1226
1227   case SIGINT:
1228     sigmsg = "Interrupted";
1229     break;
1230
1231   case SIGQUIT:
1232     sigmsg = "Quit";
1233     break;
1234
1235   case SIGILL:
1236     sigmsg = "Illegal instruction";
1237     break;
1238
1239   case SIGTRAP:
1240     sigmsg = "Trace trap";
1241     break;
1242
1243   case SIGABRT:
1244     sigmsg = "Abort";
1245     break;
1246
1247   case SIGFPE:
1248     sigmsg = "Arithmetic exception";
1249     break;
1250
1251   case SIGKILL:
1252     sigmsg = "Killed";
1253     break;
1254
1255   case SIGBUS:
1256     sigmsg = "Bus error";
1257     break;
1258
1259   case SIGSEGV:
1260     sigmsg = "Segmentation violation";
1261     break;
1262
1263   /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1264      Linux is POSIX compliant.  These are not POSIX-defined signals ---
1265      ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1266
1267         ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1268         were omitted from POSIX.1 because their behavior is
1269         implementation dependent and could not be adequately catego-
1270         rized.  Conforming implementations may deliver these sig-
1271         nals, but must document the circumstances under which they
1272         are delivered and note any restrictions concerning their
1273         delivery.''
1274
1275      So we only check for SIGSYS on those systems that happen to
1276      implement them (a system can be POSIX-compliant and implement
1277      them, it's just that POSIX doesn't *require* a POSIX-compliant
1278      system to implement them).
1279    */
1280
1281 #ifdef SIGSYS
1282   case SIGSYS:
1283     sigmsg = "Bad system call";
1284     break;
1285 #endif
1286
1287   case SIGPIPE:
1288     sigmsg = "Broken pipe";
1289     break;
1290
1291   case SIGALRM:
1292     sigmsg = "Alarm clock";
1293     break;
1294
1295   case SIGTERM:
1296     sigmsg = "Terminated";
1297     break;
1298
1299   default:
1300         /* Returning a static buffer is ok in the context we use it here */
1301     g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1302     sigmsg = sigmsg_buf;
1303     break;
1304   }
1305   return sigmsg;
1306 }
1307 #endif
1308
1309
1310 #ifdef _WIN32
1311 /* tell the child through the signal pipe that we want to quit the capture */
1312 static void
1313 signal_pipe_capquit_to_child(capture_options *capture_opts)
1314 {
1315     const char quit_msg[] = "QUIT";
1316     int ret;
1317
1318
1319     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1320
1321     /* it doesn't matter *what* we send here, the first byte will stop the capture */
1322     /* simply sending a "QUIT" string */
1323     /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1324     ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1325     if(ret == -1) {
1326         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1327               "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1328     }
1329 }
1330 #endif
1331
1332
1333 /* user wants to stop the capture run */
1334 void
1335 sync_pipe_stop(capture_options *capture_opts)
1336 {
1337   if (capture_opts->fork_child != -1) {
1338 #ifndef _WIN32
1339     /* send the SIGUSR1 signal to close the capture child gracefully. */
1340     kill(capture_opts->fork_child, SIGUSR1);
1341 #else
1342     /* Win32 doesn't have the kill() system call, use the special signal pipe
1343        instead to close the capture child gracefully. */
1344     signal_pipe_capquit_to_child(capture_opts);
1345 #endif
1346   }
1347 }
1348
1349
1350 /* Wireshark has to exit, force the capture child to close */
1351 void
1352 sync_pipe_kill(int fork_child)
1353 {
1354   if (fork_child != -1) {
1355 #ifndef _WIN32
1356       kill(fork_child, SIGTERM);        /* SIGTERM so it can clean up if necessary */
1357 #else
1358       /* Remark: This is not the preferred method of closing a process!
1359        * the clean way would be getting the process id of the child process,
1360        * then getting window handle hWnd of that process (using EnumChildWindows),
1361        * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1362        *
1363        * Unfortunately, I don't know how to get the process id from the
1364        * handle.  OpenProcess will get an handle (not a window handle)
1365        * from the process ID; it will not get a window handle from the
1366        * process ID.  (How could it?  A process can have more than one
1367        * window.  For that matter, a process might have *no* windows,
1368        * as a process running dumpcap, the normal child process program,
1369        * probably does.)
1370        *
1371        * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1372        * running in the same console; that's not necessarily the case for
1373        * us, as we might not be running in a console.
1374        * And this also will require to have the process id.
1375        */
1376       TerminateProcess((HANDLE) (fork_child), 0);
1377 #endif
1378   }
1379 }
1380
1381 #endif /* HAVE_LIBPCAP */