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.
44 #ifdef HAVE_SYS_WAIT_H
45 # include <sys/wait.h>
50 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
51 * macros) on UNIX systems that don't have them.
54 # define WIFEXITED(status) (((status) & 0177) == 0)
57 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
60 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
63 # define WEXITSTATUS(status) ((status) >> 8)
66 # define WTERMSIG(status) ((status) & 0177)
69 # define WCOREDUMP(status) ((status) & 0200)
72 # define WSTOPSIG(status) ((status) >> 8)
76 #include <epan/packet.h>
77 #include <epan/prefs.h>
83 #include "capture_sync.h"
84 #include "simple_dialog.h"
87 #include "capture-wpcap.h"
96 #include <process.h> /* For spawning child process */
99 /* Win32 needs the O_BINARY flag for open() */
106 static 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, gboolean always_report);
113 /* Size of buffer to hold decimal representation of
114 signed/unsigned 64-bit int */
115 #define SP_DECISIZE 20
118 * Indications sent out on the sync pipe.
120 #define SP_CAPSTART ';' /* capture start message */
121 #define SP_PACKET_COUNT '*' /* followed by count of packets captured since last message */
122 #define SP_ERROR_MSG '!' /* followed by length of error message that follows */
123 #define SP_DROPS '#' /* followed by count of packets dropped in capture */
124 #define SP_FILE ':' /* followed by length of the name of the last opened file that follows */
129 sync_pipe_capstart_to_parent(void)
131 static const char capstart_msg = SP_CAPSTART;
133 write(1, &capstart_msg, 1);
137 sync_pipe_packet_count_to_parent(int packet_count)
139 char tmp[SP_DECISIZE+1+1];
140 sprintf(tmp, "%d%c", packet_count, SP_PACKET_COUNT);
141 write(1, tmp, strlen(tmp));
145 sync_pipe_filename_to_parent(const char *filename)
147 int msglen = strlen(filename);
148 char lenbuf[SP_DECISIZE+1+1];
150 sprintf(lenbuf, "%u%c", msglen, SP_FILE);
151 write(1, lenbuf, strlen(lenbuf));
152 write(1, filename, msglen);
156 sync_pipe_errmsg_to_parent(const char *errmsg)
158 int msglen = strlen(errmsg);
159 char lenbuf[SP_DECISIZE+1+1];
161 sprintf(lenbuf, "%u%c", msglen, SP_ERROR_MSG);
162 write(1, lenbuf, strlen(lenbuf));
163 write(1, errmsg, msglen);
167 sync_pipe_drops_to_parent(int drops)
169 char tmp[SP_DECISIZE+1+1];
170 sprintf(tmp, "%d%c", drops, SP_DROPS);
171 write(1, tmp, strlen(tmp));
175 /* Add a string pointer to a NULL-terminated array of string pointers. */
177 sync_pipe_add_arg(char **args, int *argc, char *arg)
179 /* Grow the array; "*argc" currently contains the number of string
180 pointers, *not* counting the NULL pointer at the end, so we have
181 to add 2 in order to get the new size of the array, including the
182 new pointer and the terminating NULL pointer. */
183 args = g_realloc(args, (*argc + 2) * sizeof (char *));
185 /* Stuff the pointer into the penultimate element of the array, which
186 is the one at the index specified by "*argc". */
189 /* Now bump the count. */
192 /* We overwrite the NULL pointer; put it back right after the
200 /* Given a string, return a pointer to a quote-encapsulated version of
201 the string, so we can pass it as an argument with "spawnvp" even
202 if it contains blanks. */
204 sync_pipe_quote_encapsulate(const char *string)
206 char *encapsulated_string;
208 encapsulated_string = g_new(char, strlen(string) + 3);
209 sprintf(encapsulated_string, "\"%s\"", string);
210 return encapsulated_string;
217 sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
224 char scount[24]; /* need a constant for len of numbers */
225 char sfilesize[24]; /* need a constant for len of numbers */
226 char sfile_duration[24]; /* need a constant for len of numbers */
227 char sring_num_files[24]; /* need a constant for len of numbers */
228 char sautostop_files[24]; /* need a constant for len of numbers */
229 char sautostop_filesize[24]; /* need a constant for len of numbers */
230 char sautostop_duration[24]; /* need a constant for len of numbers */
231 char save_file_fd_str[24];
239 char sync_pipe_fd[24];
243 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
244 int sync_pipe[2]; /* pipes used to sync between instances */
247 /*g_warning("sync_pipe_do_capture");
248 capture_opts_info(capture_opts);*/
250 capture_opts->fork_child = -1;
252 /* Allocate the string pointer array with enough space for the
253 terminating NULL pointer. */
255 argv = g_malloc(sizeof (char *));
258 /* Now add those arguments used on all platforms. */
259 argv = sync_pipe_add_arg(argv, &argc, CHILD_NAME);
261 argv = sync_pipe_add_arg(argv, &argc, "-i");
262 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
264 argv = sync_pipe_add_arg(argv, &argc, "-w");
265 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
267 argv = sync_pipe_add_arg(argv, &argc, "-W");
268 sprintf(save_file_fd_str,"%d",capture_opts->save_file_fd); /* in lieu of itoa */
269 argv = sync_pipe_add_arg(argv, &argc, save_file_fd_str);
271 if (capture_opts->has_snaplen) {
272 argv = sync_pipe_add_arg(argv, &argc, "-s");
273 sprintf(ssnap,"%d",capture_opts->snaplen);
274 argv = sync_pipe_add_arg(argv, &argc, ssnap);
277 if (capture_opts->linktype != -1) {
278 argv = sync_pipe_add_arg(argv, &argc, "-y");
279 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
280 sprintf(ssnap,"%s",pcap_datalink_val_to_name(capture_opts->linktype));
282 /* XXX - just treat it as a number */
283 sprintf(ssnap,"%d",capture_opts->linktype);
285 argv = sync_pipe_add_arg(argv, &argc, ssnap);
288 if(capture_opts->multi_files_on) {
289 if (capture_opts->has_autostop_filesize) {
290 argv = sync_pipe_add_arg(argv, &argc, "-b");
291 sprintf(sfilesize,"filesize:%d",capture_opts->autostop_filesize);
292 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
295 if (capture_opts->has_file_duration) {
296 argv = sync_pipe_add_arg(argv, &argc, "-b");
297 sprintf(sfile_duration,"duration:%d",capture_opts->file_duration);
298 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
301 if (capture_opts->has_ring_num_files) {
302 argv = sync_pipe_add_arg(argv, &argc, "-b");
303 sprintf(sring_num_files,"files:%d",capture_opts->ring_num_files);
304 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
307 if (capture_opts->has_autostop_files) {
308 argv = sync_pipe_add_arg(argv, &argc, "-a");
309 sprintf(sautostop_files,"files:%d",capture_opts->autostop_files);
310 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
313 if (capture_opts->has_autostop_filesize) {
314 argv = sync_pipe_add_arg(argv, &argc, "-a");
315 sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize);
316 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
320 if (capture_opts->has_autostop_packets) {
321 argv = sync_pipe_add_arg(argv, &argc, "-c");
322 sprintf(scount,"%d",capture_opts->autostop_packets);
323 argv = sync_pipe_add_arg(argv, &argc, scount);
326 if (capture_opts->has_autostop_duration) {
327 argv = sync_pipe_add_arg(argv, &argc, "-a");
328 sprintf(sautostop_duration,"duration:%d",capture_opts->autostop_duration);
329 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
332 if (!capture_opts->show_info) {
333 argv = sync_pipe_add_arg(argv, &argc, "-H");
336 if (!capture_opts->promisc_mode)
337 argv = sync_pipe_add_arg(argv, &argc, "-p");
340 /* Create a pipe for the child process */
341 if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
342 /* Couldn't create the pipe between parent and child. */
344 unlink(capture_opts->save_file);
345 g_free(capture_opts->save_file);
346 capture_opts->save_file = NULL;
347 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
352 /* Convert font name to a quote-encapsulated string and pass to child */
353 argv = sync_pipe_add_arg(argv, &argc, "-m");
354 fontstring = sync_pipe_quote_encapsulate(prefs.PREFS_GUI_FONT_NAME);
355 argv = sync_pipe_add_arg(argv, &argc, fontstring);
357 /* Convert pipe write handle to a string and pass to child */
358 argv = sync_pipe_add_arg(argv, &argc, "-Z");
359 itoa(sync_pipe[PIPE_WRITE], sync_pipe_fd, 10);
360 argv = sync_pipe_add_arg(argv, &argc, sync_pipe_fd);
362 /* Convert filter string to a quote delimited string and pass to child */
364 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
365 argv = sync_pipe_add_arg(argv, &argc, "-f");
366 filterstring = sync_pipe_quote_encapsulate(capture_opts->cfilter);
367 argv = sync_pipe_add_arg(argv, &argc, filterstring);
371 capture_opts->fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
374 g_free(filterstring);
377 if (pipe(sync_pipe) < 0) {
378 /* Couldn't create the pipe between parent and child. */
380 unlink(capture_opts->save_file);
381 g_free(capture_opts->save_file);
382 capture_opts->save_file = NULL;
383 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
388 argv = sync_pipe_add_arg(argv, &argc, "-m");
389 argv = sync_pipe_add_arg(argv, &argc, prefs.PREFS_GUI_FONT_NAME);
391 if (capture_opts->cfilter != NULL && capture_opts->cfilter != 0) {
392 argv = sync_pipe_add_arg(argv, &argc, "-f");
393 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
396 if ((capture_opts->fork_child = fork()) == 0) {
398 * Child process - run Ethereal with the right arguments to make
399 * it just pop up the live capture dialog box and capture with
400 * the specified capture parameters, writing to the specified file.
402 * args: -i interface specification
404 * -W file descriptor to write
405 * -c count to capture
408 * -f "filter expression"
411 dup(sync_pipe[PIPE_WRITE]);
412 close(sync_pipe[PIPE_READ]);
413 execvp(ethereal_path, argv);
414 snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
415 ethereal_path, strerror(errno));
416 sync_pipe_errmsg_to_parent(errmsg);
418 /* Exit with "_exit()", so that we don't close the connection
419 to the X server (and cause stuff buffered up by our parent but
420 not yet sent to be sent, as that stuff should only be sent by
426 /* Parent process - read messages from the child process over the
428 g_free(argv); /* free up arg array */
430 /* Close the write side of the pipe, so that only the child has it
431 open, and thus it completely closes, and thus returns to us
432 an EOF indication, if the child closes it (either deliberately
433 or by exiting abnormally). */
434 close(sync_pipe[PIPE_WRITE]);
436 /* Close the save file FD, as we won't be using it - we'll be opening
437 it and reading the save file through Wiretap. */
438 if(capture_opts->save_file_fd != -1) {
439 close(capture_opts->save_file_fd);
442 if (capture_opts->fork_child == -1) {
443 /* We couldn't even create the child process. */
445 close(sync_pipe[PIPE_READ]);
446 unlink(capture_opts->save_file);
447 g_free(capture_opts->save_file);
448 capture_opts->save_file = NULL;
449 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
450 "Couldn't create child process: %s", strerror(error));
454 /* Read a byte count from "sync_pipe[PIPE_READ]", terminated with a
455 colon; if the count is 0, the child process created the
456 capture file and we should start reading from it, otherwise
457 the capture couldn't start and the count is a count of bytes
458 of error message, and we should display the message. */
461 i = read(sync_pipe[PIPE_READ], &c, 1);
463 /* EOF - the child process died.
464 Close the read side of the sync pipe, remove the capture file,
465 and report the failure. */
466 close(sync_pipe[PIPE_READ]);
467 unlink(capture_opts->save_file);
468 g_free(capture_opts->save_file);
469 capture_opts->save_file = NULL;
470 sync_pipe_wait_for_child(capture_opts, TRUE);
473 if (c == SP_CAPSTART || c == SP_ERROR_MSG)
476 /* Child process handed us crap.
477 Close the read side of the sync pipe, remove the capture file,
478 and report the failure. */
479 close(sync_pipe[PIPE_READ]);
480 unlink(capture_opts->save_file);
481 g_free(capture_opts->save_file);
482 capture_opts->save_file = NULL;
483 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
484 "Capture child process sent us a bad message");
487 byte_count = byte_count*10 + c - '0';
489 if (c != SP_CAPSTART) {
490 /* Failure - the child process sent us a message indicating
491 what the problem was. */
492 if (byte_count == 0) {
493 /* Zero-length message? */
494 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
495 "Capture child process failed, but its error message was empty.");
497 msg = g_malloc(byte_count + 1);
499 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
500 "Capture child process failed, but its error message was too big.");
502 i = read(sync_pipe[PIPE_READ], msg, byte_count);
503 msg[byte_count] = '\0';
505 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
506 "Capture child process failed: Error %s reading its error message.",
509 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
510 "Capture child process failed: EOF reading its error message.");
511 sync_pipe_wait_for_child(capture_opts, FALSE);
513 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, msg);
517 /* Close the sync pipe. */
518 close(sync_pipe[PIPE_READ]);
520 /* Get rid of the save file - the capture never started. */
521 unlink(capture_opts->save_file);
522 g_free(capture_opts->save_file);
523 capture_opts->save_file = NULL;
528 if(capture_opts->sync_mode) {
529 /* The child process started a capture.
530 Attempt to open the capture file and set up to read it. */
531 switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
533 /* We were able to open and set up to read the capture file;
534 arrange that our callback be called whenever it's possible
535 to read from the sync pipe, so that it's called when
536 the child process wants to tell us something. */
537 pipe_input_set_handler(sync_pipe[PIPE_READ], (gpointer) capture_opts, &capture_opts->fork_child, sync_pipe_input_cb);
542 /* We weren't able to open the capture file; user has been
543 alerted. Close the sync pipe. */
545 close(sync_pipe[PIPE_READ]);
547 /* Don't unlink the save file - leave it around, for debugging
549 g_free(capture_opts->save_file);
550 capture_opts->save_file = NULL;
555 g_assert_not_reached();
558 pipe_input_set_handler(sync_pipe[PIPE_READ], (gpointer) capture_opts, &capture_opts->fork_child, sync_pipe_input_cb);
565 sync_pipe_closed(capture_options *capture_opts)
570 /* The child has closed the sync pipe, meaning it's not going to be
571 capturing any more packets. Pick up its exit status, and
572 complain if it did anything other than exit with status 0. */
573 sync_pipe_wait_for_child(capture_opts, FALSE);
575 if(capture_opts->sync_mode) {
576 /* Read what remains of the capture file, and finish the capture.
577 XXX - do something if this fails? */
578 switch (cf_finish_tail(capture_opts->cf, &err)) {
581 if(cf_packet_count(capture_opts->cf) == 0) {
582 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
583 "%sNo packets captured!%s\n\n"
584 "As no data was captured, closing the %scapture file!",
585 simple_dialog_primary_start(), simple_dialog_primary_end(),
586 cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
587 cf_close(capture_opts->cf);
591 /* Just because we got an error, that doesn't mean we were unable
592 to read any of the file; we handle what we could get from the
596 case CF_READ_ABORTED:
597 /* Exit by leaving the main loop, so that any quit functions
598 we registered get called. */
602 /* We're not doing a capture any more, so we don't have a save
604 g_free(capture_opts->save_file);
605 capture_opts->save_file = NULL;
607 /* this is a normal mode capture, read in the capture file data */
608 capture_read(capture_opts, cf_is_tempfile(capture_opts->cf), cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
613 /* There's stuff to read from the sync pipe, meaning the child has sent
614 us a message, or the sync pipe has closed, meaning the child has
615 closed it (perhaps because it exited). */
617 sync_pipe_input_cb(gint source, gpointer user_data)
619 capture_options *capture_opts = (capture_options *)user_data;
621 char buffer[BUFSIZE+1], *p = buffer, *q = buffer, *msg, *r;
622 int nread, msglen, chars_to_copy;
627 /* we are a capture parent */
628 g_assert(!capture_opts->capture_child);
630 if ((nread = read(source, buffer, BUFSIZE)) <= 0) {
631 /* The child has closed the sync pipe, meaning it's not going to be
632 capturing any more packets. Pick up its exit status, and
633 complain if it did anything other than exit with status 0. */
634 sync_pipe_closed(capture_opts);
638 buffer[nread] = '\0';
641 /* look for (possibly multiple) indications */
643 case SP_PACKET_COUNT :
650 cf_set_drops_known(capture_opts->cf, TRUE);
651 cf_set_drops(capture_opts->cf, atoi(p));
662 /* Read the entire message.
663 XXX - if the child hasn't sent it all yet, this could cause us
664 to hang until they do. */
665 msg = g_malloc(msglen + 1);
667 while (msglen != 0) {
670 if ((nread = read(source, buffer, BUFSIZE)) <= 0)
675 chars_to_copy = MIN(msglen, nread);
676 memcpy(r, q, chars_to_copy);
679 nread -= chars_to_copy;
680 msglen -= chars_to_copy;
683 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, msg);
692 /* Read the entire message.
693 XXX - if the child hasn't sent it all yet, this could cause us
694 to hang until they do. */
695 msg = g_malloc(msglen + 1);
697 while (msglen != 0) {
700 if ((nread = read(source, buffer, BUFSIZE)) <= 0)
705 chars_to_copy = MIN(msglen, nread);
706 memcpy(r, q, chars_to_copy);
709 nread -= chars_to_copy;
710 msglen -= chars_to_copy;
714 /* save the new filename */
715 if(capture_opts->save_file != NULL) {
716 g_free(capture_opts->save_file);
718 capture_opts->save_file = g_strdup(msg);
728 if(capture_opts->sync_mode) {
729 /* Read from the capture file the number of records the child told us
731 XXX - do something if this fails? */
732 switch (cf_continue_tail(capture_opts->cf, to_read, &err)) {
736 /* Just because we got an error, that doesn't mean we were unable
737 to read any of the file; we handle what we could get from the
740 XXX - abort on a read error? */
743 case CF_READ_ABORTED:
744 /* Kill the child capture process; the user wants to exit, and we
745 shouldn't just leave it running. */
746 capture_kill_child(capture_opts);
755 /* the child process is going down, wait until it's completely terminated */
757 sync_pipe_wait_for_child(capture_options *capture_opts, gboolean always_report)
762 g_assert(capture_opts->fork_child != -1);
765 /* XXX - analyze the wait status and display more information
767 XXX - set "fork_child" to -1 if we find it exited? */
768 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
769 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
770 "Child capture process stopped unexpectedly");
773 if (wait(&wstatus) != -1) {
774 if (WIFEXITED(wstatus)) {
775 /* The child exited; display its exit status, if it's not zero,
776 and even if it's zero if "always_report" is true. */
777 if (always_report || WEXITSTATUS(wstatus) != 0) {
778 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
779 "Child capture process exited: exit status %d",
780 WEXITSTATUS(wstatus));
782 } else if (WIFSTOPPED(wstatus)) {
783 /* It stopped, rather than exiting. "Should not happen." */
784 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
785 "Child capture process stopped: %s",
786 sync_pipe_signame(WSTOPSIG(wstatus)));
787 } else if (WIFSIGNALED(wstatus)) {
788 /* It died with a signal. */
789 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
790 "Child capture process died: %s%s",
791 sync_pipe_signame(WTERMSIG(wstatus)),
792 WCOREDUMP(wstatus) ? " - core dumped" : "");
794 /* What? It had to either have exited, or stopped, or died with
795 a signal; what happened here? */
796 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
797 "Child capture process died: wait status %#o", wstatus);
801 /* No more child process. */
802 capture_opts->fork_child = -1;
809 sync_pipe_signame(int sig)
812 static char sigmsg_buf[6+1+3+1];
821 sigmsg = "Interrupted";
829 sigmsg = "Illegal instruction";
833 sigmsg = "Trace trap";
841 sigmsg = "Arithmetic exception";
849 sigmsg = "Bus error";
853 sigmsg = "Segmentation violation";
856 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
857 Linux is POSIX compliant. These are not POSIX-defined signals ---
858 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
860 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
861 were omitted from POSIX.1 because their behavior is
862 implementation dependent and could not be adequately catego-
863 rized. Conforming implementations may deliver these sig-
864 nals, but must document the circumstances under which they
865 are delivered and note any restrictions concerning their
868 So we only check for SIGSYS on those systems that happen to
869 implement them (a system can be POSIX-compliant and implement
870 them, it's just that POSIX doesn't *require* a POSIX-compliant
871 system to implement them).
876 sigmsg = "Bad system call";
881 sigmsg = "Broken pipe";
885 sigmsg = "Alarm clock";
889 sigmsg = "Terminated";
893 sprintf(sigmsg_buf, "Signal %d", sig);
903 sync_pipe_stop(capture_options *capture_opts)
905 /* XXX - in which cases this will be 0? */
906 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
908 kill(capture_opts->fork_child, SIGUSR1);
910 /* XXX: this is not the preferred method of closing a process!
911 * the clean way would be getting the process id of the child process,
912 * then getting window handle hWnd of that process (using EnumChildWindows),
913 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
915 * Unfortunately, I don't know how to get the process id from the
916 * handle. OpenProcess will get an handle (not a window handle)
917 * from the process ID; it will not get a window handle from the
918 * process ID. (How could it? A process can have more than one
921 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
922 * running in the same console; that's not necessarily the case for
923 * us, as we might not be running in a console.
924 * And this also will require to have the process id.
926 TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
933 sync_pipe_kill(capture_options *capture_opts)
935 /* XXX - in which cases this will be 0? */
936 if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
938 kill(capture_opts->fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
940 /* XXX: this is not the preferred method of closing a process!
941 * the clean way would be getting the process id of the child process,
942 * then getting window handle hWnd of that process (using EnumChildWindows),
943 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
945 * Unfortunately, I don't know how to get the process id from the
946 * handle. OpenProcess will get an handle (not a window handle)
947 * from the process ID; it will not get a window handle from the
948 * process ID. (How could it? A process can have more than one
951 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
952 * running in the same console; that's not necessarily the case for
953 * us, as we might not be running in a console.
954 * And this also will require to have the process id.
956 TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
961 #endif /* HAVE_LIBPCAP */