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
294 #define ARGV_NUMBER_LEN 24
297 sync_pipe_start(capture_options *capture_opts) {
298 char ssnap[ARGV_NUMBER_LEN];
299 char scount[ARGV_NUMBER_LEN];
300 char sfilesize[ARGV_NUMBER_LEN];
301 char sfile_duration[ARGV_NUMBER_LEN];
302 char sring_num_files[ARGV_NUMBER_LEN];
303 char sautostop_files[ARGV_NUMBER_LEN];
304 char sautostop_filesize[ARGV_NUMBER_LEN];
305 char sautostop_duration[ARGV_NUMBER_LEN];
307 char buffer_size[ARGV_NUMBER_LEN];
309 char *savefilestring;
310 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
311 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
312 HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
313 HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
314 GString *args = g_string_sized_new(200);
315 SECURITY_ATTRIBUTES sa;
317 PROCESS_INFORMATION pi;
321 int sync_pipe[2]; /* pipe used to send messages from child to parent */
322 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
324 int sync_pipe_read_fd;
330 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
331 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
333 capture_opts->fork_child = -1;
335 /* Allocate the string pointer array with enough space for the
336 terminating NULL pointer. */
338 argv = g_malloc(sizeof (char *));
341 /* take ethereal's absolute program path and replace ethereal with dumpcap */
342 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap",
345 /* Make that the first argument in the argument list (argv[0]). */
346 argv = sync_pipe_add_arg(argv, &argc, exename);
348 argv = sync_pipe_add_arg(argv, &argc, "-i");
349 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
351 if (capture_opts->has_snaplen) {
352 argv = sync_pipe_add_arg(argv, &argc, "-s");
353 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
354 argv = sync_pipe_add_arg(argv, &argc, ssnap);
357 if (capture_opts->linktype != -1) {
358 argv = sync_pipe_add_arg(argv, &argc, "-y");
359 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
360 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
362 /* XXX - just treat it as a number */
363 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
365 argv = sync_pipe_add_arg(argv, &argc, ssnap);
368 if(capture_opts->multi_files_on) {
369 if (capture_opts->has_autostop_filesize) {
370 argv = sync_pipe_add_arg(argv, &argc, "-b");
371 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
372 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
375 if (capture_opts->has_file_duration) {
376 argv = sync_pipe_add_arg(argv, &argc, "-b");
377 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
378 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
381 if (capture_opts->has_ring_num_files) {
382 argv = sync_pipe_add_arg(argv, &argc, "-b");
383 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
384 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
387 if (capture_opts->has_autostop_files) {
388 argv = sync_pipe_add_arg(argv, &argc, "-a");
389 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
390 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
393 if (capture_opts->has_autostop_filesize) {
394 argv = sync_pipe_add_arg(argv, &argc, "-a");
395 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
396 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
400 if (capture_opts->has_autostop_packets) {
401 argv = sync_pipe_add_arg(argv, &argc, "-c");
402 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
403 argv = sync_pipe_add_arg(argv, &argc, scount);
406 if (capture_opts->has_autostop_duration) {
407 argv = sync_pipe_add_arg(argv, &argc, "-a");
408 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
409 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
412 if (!capture_opts->promisc_mode)
413 argv = sync_pipe_add_arg(argv, &argc, "-p");
415 /* dumpcap should be running in capture child mode (hidden feature) */
417 argv = sync_pipe_add_arg(argv, &argc, "-Z");
421 argv = sync_pipe_add_arg(argv, &argc, "-B");
422 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
423 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
425 /* Convert filter string to a quote delimited string and pass to child */
427 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
428 argv = sync_pipe_add_arg(argv, &argc, "-f");
429 filterstring = g_strdup_printf("\"%s\"", capture_opts->cfilter);
430 argv = sync_pipe_add_arg(argv, &argc, filterstring);
433 /* Convert save file name to a quote delimited string and pass to child */
434 savefilestring = NULL;
435 if(capture_opts->save_file) {
436 argv = sync_pipe_add_arg(argv, &argc, "-w");
437 savefilestring = g_strdup_printf("\"%s\"", capture_opts->save_file);
438 argv = sync_pipe_add_arg(argv, &argc, savefilestring);
441 /* init SECURITY_ATTRIBUTES */
442 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
443 sa.bInheritHandle = TRUE;
444 sa.lpSecurityDescriptor = NULL;
446 /* Create a pipe for the child process */
447 /* (inrease this value if you have trouble while fast capture file switches) */
448 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
449 /* Couldn't create the pipe between parent and child. */
450 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
452 g_free( (gpointer) argv);
456 /* Create a pipe for the parent process */
457 if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
458 /* Couldn't create the signal pipe between parent and child. */
459 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
461 CloseHandle(sync_pipe_read);
462 CloseHandle(sync_pipe_write);
463 g_free( (gpointer) argv);
467 /* init STARTUPINFO */
468 memset(&si, 0, sizeof(si));
471 si.dwFlags = STARTF_USESHOWWINDOW;
472 si.wShowWindow = SW_SHOW;
474 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
475 si.wShowWindow = SW_HIDE; /* this hides the console window */
476 si.hStdInput = signal_pipe_read;
477 si.hStdOutput = sync_pipe_write;
478 si.hStdError = sync_pipe_write;
479 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
482 g_string_append(args, exename);
484 /* convert args array into a single string */
485 /* XXX - could change sync_pipe_add_arg() instead */
486 /* there is a drawback here: the length is internally limited to 1024 bytes */
487 for(i=0; argv[i] != 0; i++) {
488 g_string_append_c(args, ' ');
489 g_string_append(args, argv[i]);
493 if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
494 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
495 g_error("couldn't open dumpcap.exe!");
497 capture_opts->fork_child = (int) pi.hProcess;
498 g_string_free(args, TRUE);
500 /* associate the operating system filehandle to a C run-time file handle */
501 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
502 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
504 /* associate the operating system filehandle to a C run-time file handle */
505 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
508 g_free(filterstring);
511 g_free(savefilestring);
514 /* child own's the read side now, close our handle */
515 CloseHandle(signal_pipe_read);
517 if (pipe(sync_pipe) < 0) {
518 /* Couldn't create the pipe between parent and child. */
519 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
525 if (capture_opts->cfilter != NULL && capture_opts->cfilter != 0) {
526 argv = sync_pipe_add_arg(argv, &argc, "-f");
527 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
530 if(capture_opts->save_file) {
531 argv = sync_pipe_add_arg(argv, &argc, "-w");
532 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
535 if ((capture_opts->fork_child = fork()) == 0) {
537 * Child process - run Ethereal with the right arguments to make
538 * it just pop up the live capture dialog box and capture with
539 * the specified capture parameters, writing to the specified file.
541 * args: -i interface specification
543 * -c count to capture
546 * -f "filter expression"
549 dup(sync_pipe[PIPE_WRITE]);
550 eth_close(sync_pipe[PIPE_READ]);
551 execvp(exename, argv);
552 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
553 exename, strerror(errno));
554 sync_pipe_errmsg_to_parent(errmsg);
556 /* Exit with "_exit()", so that we don't close the connection
557 to the X server (and cause stuff buffered up by our parent but
558 not yet sent to be sent, as that stuff should only be sent by
563 sync_pipe_read_fd = sync_pipe[PIPE_READ];
568 /* Parent process - read messages from the child process over the
570 g_free( (gpointer) argv); /* free up arg array */
572 /* Close the write side of the pipe, so that only the child has it
573 open, and thus it completely closes, and thus returns to us
574 an EOF indication, if the child closes it (either deliberately
575 or by exiting abnormally). */
577 CloseHandle(sync_pipe_write);
579 eth_close(sync_pipe[PIPE_WRITE]);
582 if (capture_opts->fork_child == -1) {
583 /* We couldn't even create the child process. */
584 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
585 "Couldn't create child process: %s", strerror(errno));
586 eth_close(sync_pipe_read_fd);
588 eth_close(capture_opts->signal_pipe_write_fd);
593 /* we might wait for a moment till child is ready, so update screen now */
594 main_window_update();
596 /* We were able to set up to read the capture file;
597 arrange that our callback be called whenever it's possible
598 to read from the sync pipe, so that it's called when
599 the child process wants to tell us something. */
601 /* we have a running capture, now wait for the real capture filename */
602 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
603 &capture_opts->fork_child, sync_pipe_input_cb);
608 /* There's stuff to read from the sync pipe, meaning the child has sent
609 us a message, or the sync pipe has closed, meaning the child has
610 closed it (perhaps because it exited). */
612 sync_pipe_input_cb(gint source, gpointer user_data)
614 capture_options *capture_opts = (capture_options *)user_data;
615 char buffer[SP_MAX_MSG_LEN+1];
620 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
623 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
624 "sync_pipe_input_cb: child has closed sync_pipe");
626 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
627 "sync_pipe_input_cb: error reading from sync pipe");
629 /* The child has closed the sync pipe, meaning it's not going to be
630 capturing any more packets. Pick up its exit status, and
631 complain if it did anything other than exit with status 0.
633 XXX - what if we got an error from the sync pipe? Do we have
634 to kill the child? */
635 sync_pipe_wait_for_child(capture_opts);
638 eth_close(capture_opts->signal_pipe_write_fd);
640 capture_input_closed(capture_opts);
646 if(!capture_input_new_file(capture_opts, buffer)) {
647 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
649 /* We weren't able to open the new capture file; user has been
650 alerted. Close the sync pipe. */
653 /* the child has send us a filename which we couldn't open.
654 this probably means, the child is creating files faster than we can handle it.
655 this should only be the case for very fast file switches
656 we can't do much more than telling the child to stop
657 (this is the "emergency brake" if user e.g. wants to switch files every second) */
658 sync_pipe_stop(capture_opts);
661 case SP_PACKET_COUNT:
662 nread = atoi(buffer);
663 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
664 capture_input_new_packets(capture_opts, nread);
667 capture_input_error_message(capture_opts, buffer);
668 /* the capture child will close the sync_pipe, nothing to do for now */
671 capture_input_drops(capture_opts, atoi(buffer));
674 g_assert_not_reached();
682 /* the child process is going down, wait until it's completely terminated */
684 sync_pipe_wait_for_child(capture_options *capture_opts)
689 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
690 g_assert(capture_opts->fork_child != -1);
693 /* XXX - analyze the wait status and display more information
695 XXX - set "fork_child" to -1 if we find it exited? */
696 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
697 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
698 "Child capture process stopped unexpectedly");
701 if (wait(&wstatus) != -1) {
702 if (WIFEXITED(wstatus)) {
703 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
704 /* the child will inform us about errors through the sync_pipe, which will popup */
705 /* an error message, so don't popup another one */
707 /* XXX - if there are situations where the child won't send us such an error message, */
708 /* this should be fixed in the child and not here! */
709 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
710 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
711 "Child capture process exited: exit status %d",
712 WEXITSTATUS(wstatus));
714 } else if (WIFSTOPPED(wstatus)) {
715 /* It stopped, rather than exiting. "Should not happen." */
716 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
717 "Child capture process stopped: %s",
718 sync_pipe_signame(WSTOPSIG(wstatus)));
719 } else if (WIFSIGNALED(wstatus)) {
720 /* It died with a signal. */
721 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
722 "Child capture process died: %s%s",
723 sync_pipe_signame(WTERMSIG(wstatus)),
724 WCOREDUMP(wstatus) ? " - core dumped" : "");
726 /* What? It had to either have exited, or stopped, or died with
727 a signal; what happened here? */
728 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
729 "Child capture process died: wait status %#o", wstatus);
733 /* No more child process. */
734 capture_opts->fork_child = -1;
737 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
742 /* convert signal to corresponding name */
744 sync_pipe_signame(int sig)
747 static char sigmsg_buf[6+1+3+1];
756 sigmsg = "Interrupted";
764 sigmsg = "Illegal instruction";
768 sigmsg = "Trace trap";
776 sigmsg = "Arithmetic exception";
784 sigmsg = "Bus error";
788 sigmsg = "Segmentation violation";
791 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
792 Linux is POSIX compliant. These are not POSIX-defined signals ---
793 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
795 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
796 were omitted from POSIX.1 because their behavior is
797 implementation dependent and could not be adequately catego-
798 rized. Conforming implementations may deliver these sig-
799 nals, but must document the circumstances under which they
800 are delivered and note any restrictions concerning their
803 So we only check for SIGSYS on those systems that happen to
804 implement them (a system can be POSIX-compliant and implement
805 them, it's just that POSIX doesn't *require* a POSIX-compliant
806 system to implement them).
811 sigmsg = "Bad system call";
816 sigmsg = "Broken pipe";
820 sigmsg = "Alarm clock";
824 sigmsg = "Terminated";
828 /* XXX - returning a static buffer is ok in the context we use it here */
829 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
838 /* user wants to stop the capture run */
840 sync_pipe_stop(capture_options *capture_opts)
842 /* XXX - in which cases this will be 0? */
843 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
845 /* send the SIGUSR1 signal to close the capture child gracefully. */
846 kill(capture_opts->fork_child, SIGUSR1);
848 /* Win32 doesn't have the kill() system call, use the special signal pipe
849 instead to close the capture child gracefully. */
850 signal_pipe_capquit_to_child(capture_opts);
856 /* Ethereal has to exit, force the capture child to close */
858 sync_pipe_kill(capture_options *capture_opts)
860 /* XXX - in which cases this will be 0? */
861 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
863 kill(capture_opts->fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
865 /* XXX: this is not the preferred method of closing a process!
866 * the clean way would be getting the process id of the child process,
867 * then getting window handle hWnd of that process (using EnumChildWindows),
868 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
870 * Unfortunately, I don't know how to get the process id from the
871 * handle. OpenProcess will get an handle (not a window handle)
872 * from the process ID; it will not get a window handle from the
873 * process ID. (How could it? A process can have more than one
876 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
877 * running in the same console; that's not necessarily the case for
878 * us, as we might not be running in a console.
879 * And this also will require to have the process id.
881 TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
886 #endif /* HAVE_LIBPCAP */