2 * Synchronisation between Ethereal capture parent and child instances
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
46 #ifdef HAVE_SYS_WAIT_H
47 # include <sys/wait.h>
50 #include "capture-pcap-util.h"
54 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
55 * macros) on UNIX systems that don't have them.
58 # define WIFEXITED(status) (((status) & 0177) == 0)
61 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
64 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
67 # define WEXITSTATUS(status) ((status) >> 8)
70 # define WTERMSIG(status) ((status) & 0177)
73 # define WCOREDUMP(status) ((status) & 0200)
76 # define WSTOPSIG(status) ((status) >> 8)
80 #include <epan/packet.h>
81 #include <epan/prefs.h>
85 #include <epan/filesystem.h>
88 #include "capture_sync.h"
89 #include "simple_dialog.h"
92 #include "capture-wpcap.h"
95 #include "file_util.h"
99 #include <process.h> /* For spawning child process */
103 /*#define DEBUG_DUMPCAP*/
106 static const char *sync_pipe_signame(int);
110 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
111 static void sync_pipe_wait_for_child(capture_options *capture_opts);
114 * Maximum length of sync pipe message data. Must be < 2^24, as the
115 * message length is 3 bytes.
116 * XXX - this must be large enough to handle a Really Big Filter
117 * Expression, as the error message for an incorrect filter expression
118 * is a bit larger than the filter expression.
120 #define SP_MAX_MSG_LEN 4096
123 /* write a message to the recipient pipe in the standard format
124 (3 digit message length (excluding length and indicator field),
125 1 byte message indicator and the rest is the message) */
127 pipe_write_block(int pipe, char indicator, int len, const char *msg)
129 guchar header[3+1]; /* indicator + 3-byte len */
132 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d enter", pipe);
134 g_assert(indicator < '0' || indicator > '9');
135 g_assert(len <= SP_MAX_MSG_LEN);
137 /* write header (indicator + 3-byte len) */
138 header[0] = indicator;
139 header[1] = (len >> 16) & 0xFF;
140 header[2] = (len >> 8) & 0xFF;
141 header[3] = (len >> 0) & 0xFF;
143 ret = write(pipe, header, sizeof header);
145 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
146 "write %d header: error %s", pipe, strerror(errno));
150 /* write value (if we have one) */
152 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
153 "write %d indicator: %c value len: %u msg: %s", pipe, indicator,
155 ret = write(pipe, msg, len);
157 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
158 "write %d value: error %s", pipe, strerror(errno));
162 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
163 "write %d indicator: %c no value", pipe, indicator);
166 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d leave", pipe);
172 sync_pipe_errmsg_to_parent(const char *errmsg)
174 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
176 pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
183 signal_pipe_capquit_to_child(capture_options *capture_opts)
186 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
188 pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
194 /* read a message from the sending pipe in the standard format
195 (1-byte message indicator, 3-byte message length (excluding length
196 and indicator field), and the rest is the message) */
198 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
205 /* read header (indicator and 3-byte length) */
209 newly = read(pipe, &header[offset], required);
212 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
213 "read %d header empty (capture closed)", pipe);
218 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
219 "read %d header error: %s", pipe, strerror(errno));
227 /* convert header values */
228 *indicator = header[0];
229 required = header[1]<<16 | header[2]<<8 | header[3];
231 /* only indicator with no value? */
233 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
234 "read %d indicator: %c empty value", pipe, *indicator);
239 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
240 "read %d length error, required %d > len %d, indicator: %u",
241 pipe, required, len, *indicator);
249 newly = read(pipe, &msg[offset], required);
252 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
253 "read %d value error: %s, indicator: %u", pipe,
254 strerror(errno), *indicator);
262 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
263 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
270 /* Add a string pointer to a NULL-terminated array of string pointers. */
272 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
274 /* Grow the array; "*argc" currently contains the number of string
275 pointers, *not* counting the NULL pointer at the end, so we have
276 to add 2 in order to get the new size of the array, including the
277 new pointer and the terminating NULL pointer. */
278 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
280 /* Stuff the pointer into the penultimate element of the array, which
281 is the one at the index specified by "*argc". */
284 /* Now bump the count. */
287 /* We overwrite the NULL pointer; put it back right after the
297 /* Quote the argument element if necessary, so that it will get
298 * reconstructed correctly in the C runtime startup code. Note that
299 * the unquoting algorithm in the C runtime is really weird, and
300 * rather different than what Unix shells do. See stdargv.c in the C
301 * runtime sources (in the Platform SDK, in src/crt).
303 * Stolen from GLib's protect_argv(), an internal routine that quotes
304 * string in an argument list so that they arguments will be handled
305 * correctly in the command-line string passed to CreateProcess()
306 * if that string is constructed by gluing those strings together.
309 protect_arg (const gchar *argv)
312 const gchar *p = argv;
315 gboolean need_dblquotes = FALSE;
318 if (*p == ' ' || *p == '\t')
319 need_dblquotes = TRUE;
322 else if (*p == '\\') {
325 while (*pp && *pp == '\\')
334 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
343 else if (*p == '\\') {
346 while (*pp && *pp == '\\')
365 #define ARGV_NUMBER_LEN 24
368 sync_pipe_start(capture_options *capture_opts) {
369 char ssnap[ARGV_NUMBER_LEN];
370 char scount[ARGV_NUMBER_LEN];
371 char sfilesize[ARGV_NUMBER_LEN];
372 char sfile_duration[ARGV_NUMBER_LEN];
373 char sring_num_files[ARGV_NUMBER_LEN];
374 char sautostop_files[ARGV_NUMBER_LEN];
375 char sautostop_filesize[ARGV_NUMBER_LEN];
376 char sautostop_duration[ARGV_NUMBER_LEN];
378 char buffer_size[ARGV_NUMBER_LEN];
379 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
380 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
381 HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
382 HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
383 GString *args = g_string_sized_new(200);
385 SECURITY_ATTRIBUTES sa;
387 PROCESS_INFORMATION pi;
391 int sync_pipe[2]; /* pipe used to send messages from child to parent */
392 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
394 int sync_pipe_read_fd;
400 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
401 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
403 capture_opts->fork_child = -1;
405 /* Allocate the string pointer array with enough space for the
406 terminating NULL pointer. */
408 argv = g_malloc(sizeof (char *));
411 /* take ethereal's absolute program path and replace ethereal with dumpcap */
412 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap",
415 /* Make that the first argument in the argument list (argv[0]). */
416 argv = sync_pipe_add_arg(argv, &argc, exename);
418 argv = sync_pipe_add_arg(argv, &argc, "-i");
419 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
421 if (capture_opts->has_snaplen) {
422 argv = sync_pipe_add_arg(argv, &argc, "-s");
423 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
424 argv = sync_pipe_add_arg(argv, &argc, ssnap);
427 if (capture_opts->linktype != -1) {
428 argv = sync_pipe_add_arg(argv, &argc, "-y");
429 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
430 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
432 /* XXX - just treat it as a number */
433 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
435 argv = sync_pipe_add_arg(argv, &argc, ssnap);
438 if(capture_opts->multi_files_on) {
439 if (capture_opts->has_autostop_filesize) {
440 argv = sync_pipe_add_arg(argv, &argc, "-b");
441 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
442 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
445 if (capture_opts->has_file_duration) {
446 argv = sync_pipe_add_arg(argv, &argc, "-b");
447 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
448 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
451 if (capture_opts->has_ring_num_files) {
452 argv = sync_pipe_add_arg(argv, &argc, "-b");
453 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
454 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
457 if (capture_opts->has_autostop_files) {
458 argv = sync_pipe_add_arg(argv, &argc, "-a");
459 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
460 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
463 if (capture_opts->has_autostop_filesize) {
464 argv = sync_pipe_add_arg(argv, &argc, "-a");
465 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
466 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
470 if (capture_opts->has_autostop_packets) {
471 argv = sync_pipe_add_arg(argv, &argc, "-c");
472 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
473 argv = sync_pipe_add_arg(argv, &argc, scount);
476 if (capture_opts->has_autostop_duration) {
477 argv = sync_pipe_add_arg(argv, &argc, "-a");
478 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
479 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
482 if (!capture_opts->promisc_mode)
483 argv = sync_pipe_add_arg(argv, &argc, "-p");
485 /* dumpcap should be running in capture child mode (hidden feature) */
487 argv = sync_pipe_add_arg(argv, &argc, "-Z");
491 argv = sync_pipe_add_arg(argv, &argc, "-B");
492 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
493 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
496 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
497 argv = sync_pipe_add_arg(argv, &argc, "-f");
498 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
501 if(capture_opts->save_file) {
502 argv = sync_pipe_add_arg(argv, &argc, "-w");
503 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
507 /* init SECURITY_ATTRIBUTES */
508 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
509 sa.bInheritHandle = TRUE;
510 sa.lpSecurityDescriptor = NULL;
512 /* Create a pipe for the child process */
513 /* (inrease this value if you have trouble while fast capture file switches) */
514 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
515 /* Couldn't create the pipe between parent and child. */
516 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
518 g_free( (gpointer) argv);
522 /* Create a pipe for the parent process */
523 if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
524 /* Couldn't create the signal pipe between parent and child. */
525 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
527 CloseHandle(sync_pipe_read);
528 CloseHandle(sync_pipe_write);
529 g_free( (gpointer) argv);
533 /* init STARTUPINFO */
534 memset(&si, 0, sizeof(si));
537 si.dwFlags = STARTF_USESHOWWINDOW;
538 si.wShowWindow = SW_SHOW;
540 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
541 si.wShowWindow = SW_HIDE; /* this hides the console window */
542 si.hStdInput = signal_pipe_read;
543 si.hStdOutput = sync_pipe_write;
544 si.hStdError = sync_pipe_write;
545 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
548 /* convert args array into a single string */
549 /* XXX - could change sync_pipe_add_arg() instead */
550 /* there is a drawback here: the length is internally limited to 1024 bytes */
551 for(i=0; argv[i] != 0; i++) {
552 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
553 quoted_arg = protect_arg(argv[i]);
554 g_string_append(args, quoted_arg);
559 if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
560 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
561 g_warning("Couldn't open dumpcap (Error: %u): %s", GetLastError(), args->str);
562 capture_opts->fork_child = -1;
564 capture_opts->fork_child = (int) pi.hProcess;
566 g_string_free(args, TRUE);
568 /* associate the operating system filehandle to a C run-time file handle */
569 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
570 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
572 /* associate the operating system filehandle to a C run-time file handle */
573 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
575 /* child own's the read side now, close our handle */
576 CloseHandle(signal_pipe_read);
578 if (pipe(sync_pipe) < 0) {
579 /* Couldn't create the pipe between parent and child. */
580 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
586 if ((capture_opts->fork_child = fork()) == 0) {
588 * Child process - run Ethereal with the right arguments to make
589 * it just pop up the live capture dialog box and capture with
590 * the specified capture parameters, writing to the specified file.
592 * args: -i interface specification
594 * -c count to capture
597 * -f "filter expression"
600 dup(sync_pipe[PIPE_WRITE]);
601 eth_close(sync_pipe[PIPE_READ]);
602 execv(exename, argv);
603 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
604 exename, strerror(errno));
605 sync_pipe_errmsg_to_parent(errmsg);
607 /* Exit with "_exit()", so that we don't close the connection
608 to the X server (and cause stuff buffered up by our parent but
609 not yet sent to be sent, as that stuff should only be sent by
614 sync_pipe_read_fd = sync_pipe[PIPE_READ];
619 /* Parent process - read messages from the child process over the
621 g_free( (gpointer) argv); /* free up arg array */
623 /* Close the write side of the pipe, so that only the child has it
624 open, and thus it completely closes, and thus returns to us
625 an EOF indication, if the child closes it (either deliberately
626 or by exiting abnormally). */
628 CloseHandle(sync_pipe_write);
630 eth_close(sync_pipe[PIPE_WRITE]);
633 if (capture_opts->fork_child == -1) {
634 /* We couldn't even create the child process. */
635 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
636 "Couldn't create child process: %s", strerror(errno));
637 eth_close(sync_pipe_read_fd);
639 eth_close(capture_opts->signal_pipe_write_fd);
644 /* we might wait for a moment till child is ready, so update screen now */
645 main_window_update();
647 /* We were able to set up to read the capture file;
648 arrange that our callback be called whenever it's possible
649 to read from the sync pipe, so that it's called when
650 the child process wants to tell us something. */
652 /* we have a running capture, now wait for the real capture filename */
653 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
654 &capture_opts->fork_child, sync_pipe_input_cb);
659 /* There's stuff to read from the sync pipe, meaning the child has sent
660 us a message, or the sync pipe has closed, meaning the child has
661 closed it (perhaps because it exited). */
663 sync_pipe_input_cb(gint source, gpointer user_data)
665 capture_options *capture_opts = (capture_options *)user_data;
666 char buffer[SP_MAX_MSG_LEN+1];
671 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
674 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
675 "sync_pipe_input_cb: child has closed sync_pipe");
677 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
678 "sync_pipe_input_cb: error reading from sync pipe");
680 /* The child has closed the sync pipe, meaning it's not going to be
681 capturing any more packets. Pick up its exit status, and
682 complain if it did anything other than exit with status 0.
684 XXX - what if we got an error from the sync pipe? Do we have
685 to kill the child? */
686 sync_pipe_wait_for_child(capture_opts);
689 eth_close(capture_opts->signal_pipe_write_fd);
691 capture_input_closed(capture_opts);
697 if(!capture_input_new_file(capture_opts, buffer)) {
698 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
700 /* We weren't able to open the new capture file; user has been
701 alerted. Close the sync pipe. */
704 /* the child has send us a filename which we couldn't open.
705 this probably means, the child is creating files faster than we can handle it.
706 this should only be the case for very fast file switches
707 we can't do much more than telling the child to stop
708 (this is the "emergency brake" if user e.g. wants to switch files every second) */
709 sync_pipe_stop(capture_opts);
712 case SP_PACKET_COUNT:
713 nread = atoi(buffer);
714 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
715 capture_input_new_packets(capture_opts, nread);
718 capture_input_error_message(capture_opts, buffer);
719 /* the capture child will close the sync_pipe, nothing to do for now */
722 capture_input_drops(capture_opts, atoi(buffer));
725 g_assert_not_reached();
733 /* the child process is going down, wait until it's completely terminated */
735 sync_pipe_wait_for_child(capture_options *capture_opts)
740 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
741 g_assert(capture_opts->fork_child != -1);
744 /* XXX - analyze the wait status and display more information
746 XXX - set "fork_child" to -1 if we find it exited? */
747 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
748 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
749 "Child capture process stopped unexpectedly");
752 if (wait(&wstatus) != -1) {
753 if (WIFEXITED(wstatus)) {
754 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
755 /* the child will inform us about errors through the sync_pipe, which will popup */
756 /* an error message, so don't popup another one */
758 /* XXX - if there are situations where the child won't send us such an error message, */
759 /* this should be fixed in the child and not here! */
760 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
761 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
762 "Child capture process exited: exit status %d",
763 WEXITSTATUS(wstatus));
765 } else if (WIFSTOPPED(wstatus)) {
766 /* It stopped, rather than exiting. "Should not happen." */
767 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
768 "Child capture process stopped: %s",
769 sync_pipe_signame(WSTOPSIG(wstatus)));
770 } else if (WIFSIGNALED(wstatus)) {
771 /* It died with a signal. */
772 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
773 "Child capture process died: %s%s",
774 sync_pipe_signame(WTERMSIG(wstatus)),
775 WCOREDUMP(wstatus) ? " - core dumped" : "");
777 /* What? It had to either have exited, or stopped, or died with
778 a signal; what happened here? */
779 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
780 "Child capture process died: wait status %#o", wstatus);
784 /* No more child process. */
785 capture_opts->fork_child = -1;
788 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
793 /* convert signal to corresponding name */
795 sync_pipe_signame(int sig)
798 static char sigmsg_buf[6+1+3+1];
807 sigmsg = "Interrupted";
815 sigmsg = "Illegal instruction";
819 sigmsg = "Trace trap";
827 sigmsg = "Arithmetic exception";
835 sigmsg = "Bus error";
839 sigmsg = "Segmentation violation";
842 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
843 Linux is POSIX compliant. These are not POSIX-defined signals ---
844 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
846 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
847 were omitted from POSIX.1 because their behavior is
848 implementation dependent and could not be adequately catego-
849 rized. Conforming implementations may deliver these sig-
850 nals, but must document the circumstances under which they
851 are delivered and note any restrictions concerning their
854 So we only check for SIGSYS on those systems that happen to
855 implement them (a system can be POSIX-compliant and implement
856 them, it's just that POSIX doesn't *require* a POSIX-compliant
857 system to implement them).
862 sigmsg = "Bad system call";
867 sigmsg = "Broken pipe";
871 sigmsg = "Alarm clock";
875 sigmsg = "Terminated";
879 /* XXX - returning a static buffer is ok in the context we use it here */
880 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
889 /* user wants to stop the capture run */
891 sync_pipe_stop(capture_options *capture_opts)
893 /* XXX - in which cases this will be 0? */
894 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
896 /* send the SIGUSR1 signal to close the capture child gracefully. */
897 kill(capture_opts->fork_child, SIGUSR1);
899 /* Win32 doesn't have the kill() system call, use the special signal pipe
900 instead to close the capture child gracefully. */
901 signal_pipe_capquit_to_child(capture_opts);
907 /* Ethereal has to exit, force the capture child to close */
909 sync_pipe_kill(capture_options *capture_opts)
911 /* XXX - in which cases this will be 0? */
912 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
914 kill(capture_opts->fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
916 /* XXX: this is not the preferred method of closing a process!
917 * the clean way would be getting the process id of the child process,
918 * then getting window handle hWnd of that process (using EnumChildWindows),
919 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
921 * Unfortunately, I don't know how to get the process id from the
922 * handle. OpenProcess will get an handle (not a window handle)
923 * from the process ID; it will not get a window handle from the
924 * process ID. (How could it? A process can have more than one
927 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
928 * running in the same console; that's not necessarily the case for
929 * us, as we might not be running in a console.
930 * And this also will require to have the process id.
932 TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
937 #endif /* HAVE_LIBPCAP */