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 */
104 static const char *sync_pipe_signame(int);
108 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
109 static void sync_pipe_wait_for_child(capture_options *capture_opts);
112 * Maximum length of sync pipe message data. Must be < 2^24, as the
113 * message length is 3 bytes.
114 * XXX - this must be large enough to handle a Really Big Filter
115 * Expression, as the error message for an incorrect filter expression
116 * is a bit larger than the filter expression.
118 #define SP_MAX_MSG_LEN 4096
121 /* write a message to the recipient pipe in the standard format
122 (3 digit message length (excluding length and indicator field),
123 1 byte message indicator and the rest is the message) */
125 pipe_write_block(int pipe, char indicator, int len, const char *msg)
127 guchar header[3+1]; /* indicator + 3-byte len */
130 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d enter", pipe);
132 g_assert(indicator < '0' || indicator > '9');
133 g_assert(len <= SP_MAX_MSG_LEN);
135 /* write header (indicator + 3-byte len) */
136 header[0] = indicator;
137 header[1] = (len >> 16) & 0xFF;
138 header[2] = (len >> 8) & 0xFF;
139 header[3] = (len >> 0) & 0xFF;
141 ret = write(pipe, header, sizeof header);
143 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
144 "write %d header: error %s", pipe, strerror(errno));
148 /* write value (if we have one) */
150 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
151 "write %d indicator: %c value len: %u msg: %s", pipe, indicator,
153 ret = write(pipe, msg, len);
155 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
156 "write %d value: error %s", pipe, strerror(errno));
160 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
161 "write %d indicator: %c no value", pipe, indicator);
164 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d leave", pipe);
170 sync_pipe_errmsg_to_parent(const char *errmsg)
172 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
174 pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
181 signal_pipe_capquit_to_child(capture_options *capture_opts)
184 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
186 pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
192 /* read a message from the sending pipe in the standard format
193 (1-byte message indicator, 3-byte message length (excluding length
194 and indicator field), and the rest is the message) */
196 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
203 /* read header (indicator and 3-byte length) */
207 newly = read(pipe, &header[offset], required);
210 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
211 "read %d header empty (capture closed)", pipe);
216 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
217 "read %d header error: %s", pipe, strerror(errno));
225 /* convert header values */
226 *indicator = header[0];
227 required = header[1]<<16 | header[2]<<8 | header[3];
229 /* only indicator with no value? */
231 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
232 "read %d indicator: %c empty value", pipe, *indicator);
237 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
238 "read %d length error, required %d > len %d, indicator: %u",
239 pipe, required, len, *indicator);
247 newly = read(pipe, &msg[offset], required);
250 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
251 "read %d value error: %s, indicator: %u", pipe,
252 strerror(errno), *indicator);
260 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
261 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
268 /* Add a string pointer to a NULL-terminated array of string pointers. */
270 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
272 /* Grow the array; "*argc" currently contains the number of string
273 pointers, *not* counting the NULL pointer at the end, so we have
274 to add 2 in order to get the new size of the array, including the
275 new pointer and the terminating NULL pointer. */
276 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
278 /* Stuff the pointer into the penultimate element of the array, which
279 is the one at the index specified by "*argc". */
282 /* Now bump the count. */
285 /* We overwrite the NULL pointer; put it back right after the
295 /* Quote the argument element if necessary, so that it will get
296 * reconstructed correctly in the C runtime startup code. Note that
297 * the unquoting algorithm in the C runtime is really weird, and
298 * rather different than what Unix shells do. See stdargv.c in the C
299 * runtime sources (in the Platform SDK, in src/crt).
301 * Stolen from GLib's protect_argv(), an internal routine that quotes
302 * string in an argument list so that they arguments will be handled
303 * correctly in the command-line string passed to CreateProcess()
304 * if that string is constructed by gluing those strings together.
307 protect_arg (gchar *argv)
313 gboolean need_dblquotes = FALSE;
316 if (*p == ' ' || *p == '\t')
317 need_dblquotes = TRUE;
320 else if (*p == '\\') {
323 while (*pp && *pp == '\\')
332 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
341 else if (*p == '\\') {
344 while (*pp && *pp == '\\')
363 #define ARGV_NUMBER_LEN 24
366 sync_pipe_start(capture_options *capture_opts) {
367 char ssnap[ARGV_NUMBER_LEN];
368 char scount[ARGV_NUMBER_LEN];
369 char sfilesize[ARGV_NUMBER_LEN];
370 char sfile_duration[ARGV_NUMBER_LEN];
371 char sring_num_files[ARGV_NUMBER_LEN];
372 char sautostop_files[ARGV_NUMBER_LEN];
373 char sautostop_filesize[ARGV_NUMBER_LEN];
374 char sautostop_duration[ARGV_NUMBER_LEN];
376 char buffer_size[ARGV_NUMBER_LEN];
378 char *savefilestring;
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) {
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);*/
549 * XXX - is this necessary? argv[0] should be the full path of
552 quoted_arg = protect_arg(exename);
553 g_string_append(args, quoted_arg);
556 /* convert args array into a single string */
557 /* XXX - could change sync_pipe_add_arg() instead */
558 /* there is a drawback here: the length is internally limited to 1024 bytes */
559 for(i=0; argv[i] != 0; i++) {
560 g_string_append_c(args, ' ');
561 quoted_arg = protect_arg(argv[i]);
562 g_string_append(args, quoted_arg);
567 if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
568 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
569 g_error("couldn't open dumpcap.exe!");
571 capture_opts->fork_child = (int) pi.hProcess;
572 g_string_free(args, TRUE);
574 /* associate the operating system filehandle to a C run-time file handle */
575 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
576 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
578 /* associate the operating system filehandle to a C run-time file handle */
579 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
582 g_free(filterstring);
585 g_free(savefilestring);
588 /* child own's the read side now, close our handle */
589 CloseHandle(signal_pipe_read);
591 if (pipe(sync_pipe) < 0) {
592 /* Couldn't create the pipe between parent and child. */
593 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
599 if ((capture_opts->fork_child = fork()) == 0) {
601 * Child process - run Ethereal with the right arguments to make
602 * it just pop up the live capture dialog box and capture with
603 * the specified capture parameters, writing to the specified file.
605 * args: -i interface specification
607 * -c count to capture
610 * -f "filter expression"
613 dup(sync_pipe[PIPE_WRITE]);
614 eth_close(sync_pipe[PIPE_READ]);
615 execv(exename, argv);
616 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
617 exename, strerror(errno));
618 sync_pipe_errmsg_to_parent(errmsg);
620 /* Exit with "_exit()", so that we don't close the connection
621 to the X server (and cause stuff buffered up by our parent but
622 not yet sent to be sent, as that stuff should only be sent by
627 sync_pipe_read_fd = sync_pipe[PIPE_READ];
632 /* Parent process - read messages from the child process over the
634 g_free( (gpointer) argv); /* free up arg array */
636 /* Close the write side of the pipe, so that only the child has it
637 open, and thus it completely closes, and thus returns to us
638 an EOF indication, if the child closes it (either deliberately
639 or by exiting abnormally). */
641 CloseHandle(sync_pipe_write);
643 eth_close(sync_pipe[PIPE_WRITE]);
646 if (capture_opts->fork_child == -1) {
647 /* We couldn't even create the child process. */
648 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
649 "Couldn't create child process: %s", strerror(errno));
650 eth_close(sync_pipe_read_fd);
652 eth_close(capture_opts->signal_pipe_write_fd);
657 /* we might wait for a moment till child is ready, so update screen now */
658 main_window_update();
660 /* We were able to set up to read the capture file;
661 arrange that our callback be called whenever it's possible
662 to read from the sync pipe, so that it's called when
663 the child process wants to tell us something. */
665 /* we have a running capture, now wait for the real capture filename */
666 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
667 &capture_opts->fork_child, sync_pipe_input_cb);
672 /* There's stuff to read from the sync pipe, meaning the child has sent
673 us a message, or the sync pipe has closed, meaning the child has
674 closed it (perhaps because it exited). */
676 sync_pipe_input_cb(gint source, gpointer user_data)
678 capture_options *capture_opts = (capture_options *)user_data;
679 char buffer[SP_MAX_MSG_LEN+1];
684 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
687 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
688 "sync_pipe_input_cb: child has closed sync_pipe");
690 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
691 "sync_pipe_input_cb: error reading from sync pipe");
693 /* The child has closed the sync pipe, meaning it's not going to be
694 capturing any more packets. Pick up its exit status, and
695 complain if it did anything other than exit with status 0.
697 XXX - what if we got an error from the sync pipe? Do we have
698 to kill the child? */
699 sync_pipe_wait_for_child(capture_opts);
702 eth_close(capture_opts->signal_pipe_write_fd);
704 capture_input_closed(capture_opts);
710 if(!capture_input_new_file(capture_opts, buffer)) {
711 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
713 /* We weren't able to open the new capture file; user has been
714 alerted. Close the sync pipe. */
717 /* the child has send us a filename which we couldn't open.
718 this probably means, the child is creating files faster than we can handle it.
719 this should only be the case for very fast file switches
720 we can't do much more than telling the child to stop
721 (this is the "emergency brake" if user e.g. wants to switch files every second) */
722 sync_pipe_stop(capture_opts);
725 case SP_PACKET_COUNT:
726 nread = atoi(buffer);
727 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
728 capture_input_new_packets(capture_opts, nread);
731 capture_input_error_message(capture_opts, buffer);
732 /* the capture child will close the sync_pipe, nothing to do for now */
735 capture_input_drops(capture_opts, atoi(buffer));
738 g_assert_not_reached();
746 /* the child process is going down, wait until it's completely terminated */
748 sync_pipe_wait_for_child(capture_options *capture_opts)
753 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
754 g_assert(capture_opts->fork_child != -1);
757 /* XXX - analyze the wait status and display more information
759 XXX - set "fork_child" to -1 if we find it exited? */
760 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
761 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
762 "Child capture process stopped unexpectedly");
765 if (wait(&wstatus) != -1) {
766 if (WIFEXITED(wstatus)) {
767 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
768 /* the child will inform us about errors through the sync_pipe, which will popup */
769 /* an error message, so don't popup another one */
771 /* XXX - if there are situations where the child won't send us such an error message, */
772 /* this should be fixed in the child and not here! */
773 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
774 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
775 "Child capture process exited: exit status %d",
776 WEXITSTATUS(wstatus));
778 } else if (WIFSTOPPED(wstatus)) {
779 /* It stopped, rather than exiting. "Should not happen." */
780 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
781 "Child capture process stopped: %s",
782 sync_pipe_signame(WSTOPSIG(wstatus)));
783 } else if (WIFSIGNALED(wstatus)) {
784 /* It died with a signal. */
785 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
786 "Child capture process died: %s%s",
787 sync_pipe_signame(WTERMSIG(wstatus)),
788 WCOREDUMP(wstatus) ? " - core dumped" : "");
790 /* What? It had to either have exited, or stopped, or died with
791 a signal; what happened here? */
792 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
793 "Child capture process died: wait status %#o", wstatus);
797 /* No more child process. */
798 capture_opts->fork_child = -1;
801 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
806 /* convert signal to corresponding name */
808 sync_pipe_signame(int sig)
811 static char sigmsg_buf[6+1+3+1];
820 sigmsg = "Interrupted";
828 sigmsg = "Illegal instruction";
832 sigmsg = "Trace trap";
840 sigmsg = "Arithmetic exception";
848 sigmsg = "Bus error";
852 sigmsg = "Segmentation violation";
855 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
856 Linux is POSIX compliant. These are not POSIX-defined signals ---
857 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
859 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
860 were omitted from POSIX.1 because their behavior is
861 implementation dependent and could not be adequately catego-
862 rized. Conforming implementations may deliver these sig-
863 nals, but must document the circumstances under which they
864 are delivered and note any restrictions concerning their
867 So we only check for SIGSYS on those systems that happen to
868 implement them (a system can be POSIX-compliant and implement
869 them, it's just that POSIX doesn't *require* a POSIX-compliant
870 system to implement them).
875 sigmsg = "Bad system call";
880 sigmsg = "Broken pipe";
884 sigmsg = "Alarm clock";
888 sigmsg = "Terminated";
892 /* XXX - returning a static buffer is ok in the context we use it here */
893 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
902 /* user wants to stop the capture run */
904 sync_pipe_stop(capture_options *capture_opts)
906 /* XXX - in which cases this will be 0? */
907 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
909 /* send the SIGUSR1 signal to close the capture child gracefully. */
910 kill(capture_opts->fork_child, SIGUSR1);
912 /* Win32 doesn't have the kill() system call, use the special signal pipe
913 instead to close the capture child gracefully. */
914 signal_pipe_capquit_to_child(capture_opts);
920 /* Ethereal has to exit, force the capture child to close */
922 sync_pipe_kill(capture_options *capture_opts)
924 /* XXX - in which cases this will be 0? */
925 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
927 kill(capture_opts->fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
929 /* XXX: this is not the preferred method of closing a process!
930 * the clean way would be getting the process id of the child process,
931 * then getting window handle hWnd of that process (using EnumChildWindows),
932 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
934 * Unfortunately, I don't know how to get the process id from the
935 * handle. OpenProcess will get an handle (not a window handle)
936 * from the process ID; it will not get a window handle from the
937 * process ID. (How could it? A process can have more than one
940 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
941 * running in the same console; that's not necessarily the case for
942 * us, as we might not be running in a console.
943 * And this also will require to have the process id.
945 TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
950 #endif /* HAVE_LIBPCAP */