#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
#include <signal.h>
#ifdef _WIN32
#include <wsutil/filesystem.h>
#include <wsutil/file_util.h>
#include <wsutil/report_err.h>
+#ifdef HAVE_EXTCAP
+#include "extcap.h"
+#endif
#include "log.h"
#ifdef _WIN32
static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
-static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
+static int sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp);
static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
char **err_msg);
-static void (*fetch_dumpcap_pid)(int) = NULL;
+static void (*fetch_dumpcap_pid)(ws_process_id) = NULL;
void
-capture_session_init(capture_session *cap_session, void *cf)
+capture_session_init(capture_session *cap_session, struct _capture_file *cf)
{
cap_session->cf = cf;
- cap_session->fork_child = -1; /* invalid process handle */
+ cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
#ifdef _WIN32
cap_session->signal_pipe_write_fd = -1;
#endif
cap_session->owner = getuid();
cap_session->group = getgid();
#endif
+ cap_session->count = 0;
cap_session->session_started = FALSE;
}
*argv = NULL;
/* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
- exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
+#ifdef _WIN32
+ exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
+#else
+ exename = g_strdup_printf("%s/dumpcap", progfile_dir);
+#endif
/* Make that the first argument in the argument list (argv[0]). */
argv = sync_pipe_add_arg(argv, argc, exename);
#define ARGV_NUMBER_LEN 24
/* a new capture run: start a new dumpcap task and hand over parameters through command line */
gboolean
-sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
+sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void (*update_cb)(void))
{
char ssnap[ARGV_NUMBER_LEN];
char scount[ARGV_NUMBER_LEN];
char ssampling[ARGV_NUMBER_LEN];
#endif
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
char buffer_size[ARGV_NUMBER_LEN];
#endif
#ifdef _WIN32
HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
+ int signal_pipe_write_fd;
HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
GString *args = g_string_sized_new(200);
gchar *quoted_arg;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
- cap_session->fork_child = -1;
+ cap_session->fork_child = WS_INVALID_PID;
+
+#ifdef HAVE_EXTCAP
+ if (!extcaps_init_initerfaces(capture_opts)) {
+ report_failure("Unable to init extcaps. (tmp fifo already exists?)");
+ return FALSE;
+ }
+
+#endif
argv = init_pipe_args(&argc);
if (!argv) {
interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
argv = sync_pipe_add_arg(argv, &argc, "-i");
- argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
+#ifdef HAVE_EXTCAP
+ if (interface_opts.extcap_fifo != NULL)
+ argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
+ else
+#endif
+ argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
argv = sync_pipe_add_arg(argv, &argc, "-f");
}
if (interface_opts.linktype != -1) {
- argv = sync_pipe_add_arg(argv, &argc, "-y");
- argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
+ const char *linktype = linktype_val_to_name(interface_opts.linktype);
+ if ( linktype != NULL )
+ {
+ argv = sync_pipe_add_arg(argv, &argc, "-y");
+ argv = sync_pipe_add_arg(argv, &argc, linktype);
+ }
}
if (!interface_opts.promisc_mode) {
argv = sync_pipe_add_arg(argv, &argc, "-p");
}
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
argv = sync_pipe_add_arg(argv, &argc, "-B");
+ if(interface_opts.buffer_size == 0x00)
+ interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
argv = sync_pipe_add_arg(argv, &argc, buffer_size);
}
return FALSE;
}
+ /*
+ * Associate a C run-time file handle with the Windows HANDLE for the
+ * read side of the message pipe.
+ *
+ * (See http://www.flounder.com/handles.htm for information on various
+ * types of file handle in C/C++ on Windows.)
+ */
+ sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
+ if (sync_pipe_read_fd == -1) {
+ /* Couldn't create the pipe between parent and child. */
+ report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
+ CloseHandle(sync_pipe_read);
+ CloseHandle(sync_pipe_write);
+ for (i = 0; i < argc; i++) {
+ g_free( (gpointer) argv[i]);
+ }
+ g_free(argv);
+ return FALSE;
+ }
+
/* Create the signal pipe */
signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
/* Couldn't create the signal pipe between parent and child. */
report_failure("Couldn't create signal pipe: %s",
win32strerror(GetLastError()));
+ ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
+ CloseHandle(sync_pipe_write);
for (i = 0; i < argc; i++) {
g_free( (gpointer) argv[i]);
}
return FALSE;
}
+ /*
+ * Associate a C run-time file handle with the Windows HANDLE for the
+ * read side of the message pipe.
+ *
+ * (See http://www.flounder.com/handles.htm for information on various
+ * types of file handle in C/C++ on Windows.)
+ */
+ signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
+ if (sync_pipe_read_fd == -1) {
+ /* Couldn't create the pipe between parent and child. */
+ report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
+ ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
+ CloseHandle(sync_pipe_write);
+ CloseHandle(signal_pipe);
+ for (i = 0; i < argc; i++) {
+ g_free( (gpointer) argv[i]);
+ }
+ g_free(argv);
+ return FALSE;
+ }
+
/* init STARTUPINFO */
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
#else
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; /* this hides the console window */
- si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+#if defined(_WIN32)
+ /* needs first a check if NULL *
+ * otherwise wouldn't work with non extcap interfaces */
+ if(interface_opts.extcap_fifo != NULL)
+ {
+ if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
+ {
+ si.hStdInput = extcap_get_win32_handle();
+ }
+ }
+ else
+#endif
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = sync_pipe_write;
/*si.hStdError = (HANDLE) _get_osfhandle(2);*/
}
/* call dumpcap */
- if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
+ if(!CreateProcess(utf_8to16(argv[0]), utf_8to16(args->str), NULL, NULL, TRUE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
report_failure("Couldn't run %s in child process: %s",
args->str, win32strerror(GetLastError()));
- CloseHandle(sync_pipe_read);
+ ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
CloseHandle(sync_pipe_write);
+ CloseHandle(signal_pipe);
for (i = 0; i < argc; i++) {
g_free( (gpointer) argv[i]);
}
g_free( (gpointer) argv);
return FALSE;
}
- cap_session->fork_child = (int) pi.hProcess;
+ cap_session->fork_child = pi.hProcess;
+ /* We may need to store this and close it later */
+ CloseHandle(pi.hThread);
g_string_free(args, TRUE);
- /* associate the operating system filehandle to a C run-time file handle */
- /* (good file handle infos at: http://www.flounder.com/handles.htm) */
- sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
-
- /* associate the operating system filehandle to a C run-time file handle */
- cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
+ cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
#else /* _WIN32 */
if (pipe(sync_pipe) < 0) {
ws_close(sync_pipe[PIPE_WRITE]);
#endif
- if (cap_session->fork_child == -1) {
+ if (cap_session->fork_child == WS_INVALID_PID) {
/* We couldn't even create the child process. */
report_failure("Couldn't create child process: %s", g_strerror(errno));
ws_close(sync_pipe_read_fd);
cap_session->fork_child_status = 0;
cap_session->capture_opts = capture_opts;
+ cap_session->cap_data_info = cap_data;
/* we might wait for a moment till child is ready, so update screen now */
if (update_cb) update_cb();
* standard output and one for its standard error.
*
* On success, *msg is unchanged and 0 is returned; data_read_fd,
- * messsage_read_fd, and fork_child point to the standard output pipe's
+ * message_read_fd, and fork_child point to the standard output pipe's
* file descriptor, the standard error pipe's file descriptor, and
* the child's PID/handle, respectively.
*
#define PIPE_BUF_SIZE 5120
static int
sync_pipe_open_command(char** argv, int *data_read_fd,
- int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
+ int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
{
enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
#ifdef _WIN32
int data_pipe[2]; /* pipe used to send data from child to parent */
#endif
int i;
- *fork_child = -1;
+ *fork_child = WS_INVALID_PID;
*data_read_fd = -1;
*message_read_fd = -1;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
return -1;
}
+ /*
+ * Associate a C run-time file handle with the Windows HANDLE for the
+ * read side of the message pipe.
+ *
+ * (See http://www.flounder.com/handles.htm for information on various
+ * types of file handle in C/C++ on Windows.)
+ */
+ *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
+ if (*message_read_fd == -1) {
+ *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
+ CloseHandle(sync_pipe[PIPE_READ]);
+ CloseHandle(sync_pipe[PIPE_WRITE]);
+ for (i = 0; argv[i] != NULL; i++) {
+ g_free( (gpointer) argv[i]);
+ }
+ g_free( (gpointer) argv);
+ return -1;
+ }
+
/* Create a pipe for the child process to send us data */
/* (increase this value if you have trouble while fast capture file switches) */
if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
/* Couldn't create the message pipe between parent and child. */
*msg = g_strdup_printf("Couldn't create data pipe: %s",
win32strerror(GetLastError()));
- CloseHandle(sync_pipe[PIPE_READ]);
+ ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
+ CloseHandle(sync_pipe[PIPE_WRITE]);
+ for (i = 0; argv[i] != NULL; i++) {
+ g_free( (gpointer) argv[i]);
+ }
+ g_free( (gpointer) argv);
+ return -1;
+ }
+
+ /*
+ * Associate a C run-time file handle with the Windows HANDLE for the
+ * read side of the data pipe.
+ *
+ * (See http://www.flounder.com/handles.htm for information on various
+ * types of file handle in C/C++ on Windows.)
+ */
+ *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
+ if (*data_read_fd == -1) {
+ *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
+ CloseHandle(data_pipe[PIPE_READ]);
+ CloseHandle(data_pipe[PIPE_WRITE]);
+ ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
CloseHandle(sync_pipe[PIPE_WRITE]);
for (i = 0; argv[i] != NULL; i++) {
g_free( (gpointer) argv[i]);
#else
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; /* this hides the console window */
- si.hStdInput = NULL;
+ si.hStdInput = NULL; /* handle for named pipe*/
+
si.hStdOutput = data_pipe[PIPE_WRITE];
si.hStdError = sync_pipe[PIPE_WRITE];
#endif
}
/* call dumpcap */
- if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
+ if(!CreateProcess(utf_8to16(argv[0]), utf_8to16(args->str), NULL, NULL, TRUE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
*msg = g_strdup_printf("Couldn't run %s in child process: %s",
args->str, win32strerror(GetLastError()));
- CloseHandle(data_pipe[PIPE_READ]);
+ ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
CloseHandle(data_pipe[PIPE_WRITE]);
- CloseHandle(sync_pipe[PIPE_READ]);
+ ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
CloseHandle(sync_pipe[PIPE_WRITE]);
for (i = 0; argv[i] != NULL; i++) {
g_free( (gpointer) argv[i]);
g_free( (gpointer) argv);
return -1;
}
- *fork_child = (int) pi.hProcess;
+ *fork_child = pi.hProcess;
+ /* We may need to store this and close it later */
+ CloseHandle(pi.hThread);
g_string_free(args, TRUE);
-
- /* associate the operating system filehandles to C run-time file handles */
- /* (good file handle infos at: http://www.flounder.com/handles.htm) */
- *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
- *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
#else /* _WIN32 */
/* Create a pipe for the child process to send us messages */
if (pipe(sync_pipe) < 0) {
ws_close(sync_pipe[PIPE_WRITE]);
#endif
- if (*fork_child == -1) {
+ if (*fork_child == WS_INVALID_PID) {
/* We couldn't even create the child process. */
*msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
ws_close(*data_read_fd);
*/
static int
sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
- int *fork_child, gchar **msgp)
+ ws_process_id *fork_child, gchar **msgp)
{
ws_close(*data_read_fd);
if (message_read_fd != NULL)
gchar **secondary_msg, void(*update_cb)(void))
{
gchar *msg;
- int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
+ int data_pipe_read_fd, sync_pipe_read_fd, ret;
+ ws_process_id fork_child;
char *wait_msg;
gchar buffer[PIPE_BUF_SIZE+1] = {0};
ssize_t nread;
}
}
*secondary_msg = NULL;
+ *data = NULL;
return -1;
}
*/
*primary_msg = NULL;
*secondary_msg = NULL;
- *data = data_buf->str;
- g_string_free(data_buf, FALSE);
+ *data = g_string_free(data_buf, FALSE);
}
break;
* must be freed with g_free().
*/
int
-sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
+sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gchar* auth,
gchar **data, gchar **primary_msg,
gchar **secondary_msg, void (*update_cb)(void))
{
argv = sync_pipe_add_arg(argv, &argc, "-L");
if (monitor_mode)
argv = sync_pipe_add_arg(argv, &argc, "-I");
+ if (auth) {
+ argv = sync_pipe_add_arg(argv, &argc, "-A");
+ argv = sync_pipe_add_arg(argv, &argc, auth);
+ }
#ifndef DEBUG_CHILD
/* Run dumpcap in capture child mode */
* that must be g_free()d, and -1 will be returned.
*/
int
-sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
+sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
{
int argc;
char **argv;
case, the child will get an error when writing to the broken pipe
the next time, cleaning itself up then. */
ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
+ ws_close(message_read_fd);
+ ws_close(*data_read_fd);
if(nread == 0) {
/* We got an EOF from the sync pipe. That means that it exited
before giving us any data to read. If ret is -1, we report
/* Close down the stats process */
int
-sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
+sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
{
#ifndef _WIN32
/*
}
/* No more child process. */
- cap_session->fork_child = -1;
+ cap_session->fork_child = WS_INVALID_PID;
cap_session->fork_child_status = ret;
#ifdef _WIN32
ws_close(cap_session->signal_pipe_write_fd);
+#endif
+#ifdef HAVE_EXTCAP
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
+ extcap_cleanup(cap_session->capture_opts);
#endif
capture_input_closed(cap_session, primary_msg);
g_free(primary_msg);
case SP_PACKET_COUNT:
npackets = atoi(buffer);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
+ cap_session->count += npackets;
capture_input_new_packets(cap_session, npackets);
break;
case SP_ERROR_MSG:
* must be freed with g_free().
*/
static int
-sync_pipe_wait_for_child(int fork_child, gchar **msgp)
+sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
{
int fork_child_status;
- int ret;
+#ifndef _WIN32
+ int retry_waitpid = 3;
+#endif
+ int ret = -1;
GTimeVal start_time;
GTimeVal end_time;
float elapsed;
g_get_current_time(&start_time);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
- g_assert(fork_child != -1);
+ g_assert(fork_child != WS_INVALID_PID);
*msgp = NULL; /* assume no error */
#ifdef _WIN32
- if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
+ if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
*msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
ret = -1;
} else {
}
}
#else
- if (waitpid(fork_child, &fork_child_status, 0) != -1) {
- if (WIFEXITED(fork_child_status)) {
- /*
- * The child exited; return its exit status. Do not treat this as
- * an error.
- */
- ret = WEXITSTATUS(fork_child_status);
- } else if (WIFSTOPPED(fork_child_status)) {
- /* It stopped, rather than exiting. "Should not happen." */
- *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
- sync_pipe_signame(WSTOPSIG(fork_child_status)));
- ret = -1;
- } else if (WIFSIGNALED(fork_child_status)) {
- /* It died with a signal. */
- *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
- sync_pipe_signame(WTERMSIG(fork_child_status)),
- WCOREDUMP(fork_child_status) ? " - core dumped" : "");
- ret = -1;
+ while (--retry_waitpid >= 0) {
+ if (waitpid(fork_child, &fork_child_status, 0) != -1) {
+ /* waitpid() succeeded */
+ if (WIFEXITED(fork_child_status)) {
+ /*
+ * The child exited; return its exit status. Do not treat this as
+ * an error.
+ */
+ ret = WEXITSTATUS(fork_child_status);
+ } else if (WIFSTOPPED(fork_child_status)) {
+ /* It stopped, rather than exiting. "Should not happen." */
+ *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
+ sync_pipe_signame(WSTOPSIG(fork_child_status)));
+ ret = -1;
+ } else if (WIFSIGNALED(fork_child_status)) {
+ /* It died with a signal. */
+ *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
+ sync_pipe_signame(WTERMSIG(fork_child_status)),
+ WCOREDUMP(fork_child_status) ? " - core dumped" : "");
+ ret = -1;
+ } else {
+ /* What? It had to either have exited, or stopped, or died with
+ a signal; what happened here? */
+ *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
+ fork_child_status);
+ ret = -1;
+ }
} else {
- /* What? It had to either have exited, or stopped, or died with
- a signal; what happened here? */
- *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
- fork_child_status);
- ret = -1;
+ /* waitpid() failed */
+ if (errno == EINTR) {
+ /*
+ * Signal interrupted waitpid().
+ *
+ * If it's SIGALRM, we just want to keep waiting, in case
+ * there's some timer using it (e.g., in a GUI toolkit).
+ *
+ * If you ^C TShark (or Wireshark), that should deliver
+ * SIGINT to dumpcap as well. dumpcap catches SIGINT,
+ * and should clean up and exit, so we should eventually
+ * see that and clean up and terminate.
+ *
+ * If we're sent a SIGTERM, we should (and do) catch it,
+ * and TShark, at least, calls sync_pipe_stop(). which
+ * kills dumpcap, so we should eventually see that and
+ * clean up and terminate.
+ */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
+ continue;
+ } else if (errno == ECHILD) {
+ /*
+ * The process identified by fork_child either doesn't
+ * exist any more or isn't our child process (anymore?).
+ *
+ * echld might have already reaped the child.
+ */
+ ret = fetch_dumpcap_pid ? 0 : -1;
+ } else {
+ /* Unknown error. */
+ *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
+ ret = -1;
+ }
}
- } else if (errno != ECHILD) {
- *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
- ret = -1;
- } else {
- /* errno == ECHILD ; echld might have already reaped the child */
- ret = fetch_dumpcap_pid ? 0 : -1;
+ break;
}
#endif
DWORD childstatus;
gboolean terminate = TRUE;
#endif
-
- if (cap_session->fork_child != -1) {
+ if (cap_session->fork_child != WS_INVALID_PID) {
#ifndef _WIN32
/* send the SIGINT signal to close the capture child gracefully. */
int sts = kill(cap_session->fork_child, SIGINT);
/* Wireshark has to exit, force the capture child to close */
void
-sync_pipe_kill(int fork_child)
+sync_pipe_kill(ws_process_id fork_child)
{
- if (fork_child != -1) {
+ if (fork_child != WS_INVALID_PID) {
#ifndef _WIN32
int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
if (sts != 0) {
* And this also will require to have the process id.
*/
TerminateProcess((HANDLE) (fork_child), 0);
+
#endif
}
}
-void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
+void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
fetch_dumpcap_pid = cb;
}