static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
-static int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
+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;
+void
+capture_session_init(capture_session *cap_session, void *cf)
+{
+ cap_session->cf = cf;
+ cap_session->fork_child = -1; /* invalid process handle */
+#ifdef _WIN32
+ cap_session->signal_pipe_write_fd = -1;
+#endif
+ cap_session->state = CAPTURE_STOPPED;
+#ifndef _WIN32
+ cap_session->owner = getuid();
+ cap_session->group = getgid();
+#endif
+ cap_session->session_started = FALSE;
+}
+
/* Append an arg (realloc) to an argc/argv array */
/* (add a string pointer to a NULL-terminated array of string pointers) */
-static const char **
-sync_pipe_add_arg(const char **args, int *argc, const char *arg)
+static char **
+sync_pipe_add_arg(char **args, int *argc, const char *arg)
{
/* Grow the array; "*argc" currently contains the number of string
pointers, *not* counting the NULL pointer at the end, so we have
to add 2 in order to get the new size of the array, including the
new pointer and the terminating NULL pointer. */
- args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
+ args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
/* Stuff the pointer into the penultimate element of the array, which
is the one at the index specified by "*argc". */
#endif
/* Initialize an argument list and add dumpcap to it. */
-static const char **
+static char **
init_pipe_args(int *argc) {
- const char **argv;
+ char **argv;
const char *progfile_dir;
char *exename;
/* Allocate the string pointer array with enough space for the
terminating NULL pointer. */
*argc = 0;
- argv = g_malloc(sizeof (char *));
+ argv = (char **)g_malloc(sizeof (char *));
*argv = NULL;
/* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
#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) {
+sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
+{
char ssnap[ARGV_NUMBER_LEN];
- char sdlt[ARGV_NUMBER_LEN];
char scount[ARGV_NUMBER_LEN];
char sfilesize[ARGV_NUMBER_LEN];
char sfile_duration[ARGV_NUMBER_LEN];
#endif
int sync_pipe_read_fd;
int argc;
- const char **argv;
+ char **argv;
int i;
guint j;
interface_options interface_opts;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
- capture_opts->fork_child = -1;
+ cap_session->fork_child = -1;
argv = init_pipe_args(&argc);
if (!argv) {
argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
}
+ if (capture_opts->group_read_access) {
+ argv = sync_pipe_add_arg(argv, &argc, "-g");
+ }
+
for (j = 0; j < capture_opts->ifaces->len; j++) {
interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
if (interface_opts.linktype != -1) {
argv = sync_pipe_add_arg(argv, &argc, "-y");
- g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
- argv = sync_pipe_add_arg(argv, &argc, sdlt);
+ argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
}
if (!interface_opts.promisc_mode) {
}
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
- if (interface_opts.buffer_size != 1) {
+ if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
argv = sync_pipe_add_arg(argv, &argc, "-B");
g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
argv = sync_pipe_add_arg(argv, &argc, buffer_size);
g_free( (gpointer) argv);
return FALSE;
}
- capture_opts->fork_child = (int) pi.hProcess;
+ cap_session->fork_child = (int) pi.hProcess;
g_string_free(args, TRUE);
/* associate the operating system filehandle to a C run-time file handle */
sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
/* associate the operating system filehandle to a C run-time file handle */
- capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
+ cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
#else /* _WIN32 */
if (pipe(sync_pipe) < 0) {
return FALSE;
}
- if ((capture_opts->fork_child = fork()) == 0) {
+ if ((cap_session->fork_child = fork()) == 0) {
/*
* Child process - run dumpcap with the right arguments to make
* it just capture with the specified capture parameters
*/
dup2(sync_pipe[PIPE_WRITE], 2);
ws_close(sync_pipe[PIPE_READ]);
- execv(argv[0], (gpointer)argv);
+ execv(argv[0], argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], g_strerror(errno));
sync_pipe_errmsg_to_parent(2, errmsg, "");
_exit(1);
}
+ if (fetch_dumpcap_pid && cap_session->fork_child > 0)
+ fetch_dumpcap_pid(cap_session->fork_child);
+
sync_pipe_read_fd = sync_pipe[PIPE_READ];
#endif
ws_close(sync_pipe[PIPE_WRITE]);
#endif
- if (capture_opts->fork_child == -1) {
+ if (cap_session->fork_child == -1) {
/* 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);
#ifdef _WIN32
- ws_close(capture_opts->signal_pipe_write_fd);
+ ws_close(cap_session->signal_pipe_write_fd);
#endif
return FALSE;
}
- capture_opts->fork_child_status = 0;
+ cap_session->fork_child_status = 0;
+ cap_session->capture_opts = capture_opts;
/* we might wait for a moment till child is ready, so update screen now */
- main_window_update();
+ if (update_cb) update_cb();
/* We were able to set up to read the capture file;
arrange that our callback be called whenever it's possible
the child process wants to tell us something. */
/* we have a running capture, now wait for the real capture filename */
- pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
- &capture_opts->fork_child, sync_pipe_input_cb);
+ pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
+ &cap_session->fork_child, sync_pipe_input_cb);
return TRUE;
}
/* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
#define PIPE_BUF_SIZE 5120
static int
-sync_pipe_open_command(const char** argv, int *data_read_fd,
- int *message_read_fd, int *fork_child, gchar **msg)
+sync_pipe_open_command(char** argv, int *data_read_fd,
+ int *message_read_fd, int *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
dup2(sync_pipe[PIPE_WRITE], 2);
ws_close(sync_pipe[PIPE_READ]);
ws_close(sync_pipe[PIPE_WRITE]);
- execv(argv[0], (gpointer)argv);
+ execv(argv[0], argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], g_strerror(errno));
sync_pipe_errmsg_to_parent(2, errmsg, "");
_exit(1);
}
+ if (fetch_dumpcap_pid && *fork_child > 0)
+ fetch_dumpcap_pid(*fork_child);
+
*data_read_fd = data_pipe[PIPE_READ];
*message_read_fd = sync_pipe[PIPE_READ];
#endif
}
/* we might wait for a moment till child is ready, so update screen now */
- main_window_update();
+ if (update_cb) update_cb();
return 0;
}
/* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
#define PIPE_BUF_SIZE 5120
static int
-sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
- gchar **secondary_msg)
+sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
+ gchar **secondary_msg, void(*update_cb)(void))
{
gchar *msg;
int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
char *wait_msg;
gchar buffer[PIPE_BUF_SIZE+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_msg_len;
char *primary_msg_text;
char *secondary_msg_text;
char *combined_msg;
GString *data_buf = NULL;
- int count;
+ ssize_t count;
ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
- &fork_child, &msg);
+ &fork_child, &msg, update_cb);
if (ret == -1) {
*primary_msg = msg;
*secondary_msg = NULL;
*/
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
primary_msg_text = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+ pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
&secondary_msg_len);
secondary_msg_text = primary_msg_text + primary_msg_len + 4;
/* the capture child will close the sync_pipe, nothing to do */
return ret;
}
+/* centralised logging and timing for sync_pipe_run_command_actual(),
+* redirects to sync_pipe_run_command_actual()
+*/
+static int
+sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
+ gchar **secondary_msg, void (*update_cb)(void))
+{
+ int ret, i;
+ GTimeVal start_time;
+ GTimeVal end_time;
+ float elapsed;
+ int logging_enabled;
+
+ /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
+ logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
+ if(logging_enabled){
+ g_get_current_time(&start_time);
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
+ for(i=0; argv[i] != 0; i++) {
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
+ }
+ }
+ /* do the actual sync pipe run command */
+ ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
+
+ if(logging_enabled){
+ g_get_current_time(&end_time);
+ elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
+ ((end_time.tv_usec - start_time.tv_usec) / 1e6));
+
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
+
+ }
+ return ret;
+}
+
+
int
-sync_interface_set_80211_chan(gchar *iface, char *freq, gchar *type,
+sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
gchar **data, gchar **primary_msg,
- gchar **secondary_msg)
+ gchar **secondary_msg, void (*update_cb)(void))
{
int argc, ret;
- const char **argv;
+ char **argv;
gchar *opt;
argv = init_pipe_args(&argc);
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
- ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
+ ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
g_free(opt);
return ret;
}
*/
int
sync_interface_list_open(gchar **data, gchar **primary_msg,
- gchar **secondary_msg)
+ gchar **secondary_msg, void (*update_cb)(void))
{
int argc;
- const char **argv;
+ char **argv;
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
argv = init_pipe_args(&argc);
if (!argv) {
- *primary_msg = g_strdup("We don't know where to find dumpcap.");
+ *primary_msg = g_strdup("We don't know where to find dumpcap..");
*secondary_msg = NULL;
*data = NULL;
return -1;
argv = sync_pipe_add_arg(argv, &argc, "-Z");
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
- return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
+ return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
}
/*
int
sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
gchar **data, gchar **primary_msg,
- gchar **secondary_msg)
+ gchar **secondary_msg, void (*update_cb)(void))
{
int argc;
- const char **argv;
+ char **argv;
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
argv = init_pipe_args(&argc);
argv = sync_pipe_add_arg(argv, &argc, "-Z");
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
- return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
+ return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
}
/*
* 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)
+sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
{
int argc;
- const char **argv;
+ char **argv;
int message_read_fd, ret;
char *wait_msg;
gchar buffer[PIPE_BUF_SIZE+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_msg_len;
char *primary_msg_text;
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
- fork_child, msg);
+ fork_child, msg, update_cb);
if (ret == -1)
return -1;
*/
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
primary_msg_text = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+ pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
&secondary_msg_len);
/*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
/* the capture child will close the sync_pipe, nothing to do */
int
sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
{
+#ifndef _WIN32
+ /*
+ * Don't bother waiting for the child. sync_pipe_close_command
+ * does this for us on Windows.
+ */
+ sync_pipe_kill(*fork_child);
+#endif
return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
}
/* read a number of bytes from a pipe */
/* (blocks until enough bytes read or an error occurs) */
-static int
+static ssize_t
pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
{
- int newly;
- int offset = 0;
+ ssize_t newly;
+ ssize_t offset = 0;
int error;
while(required) {
return newly;
}
- required -= newly;
+ required -= (int)newly;
offset += newly;
}
/* Read a line from a pipe, similar to fgets */
int
sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
- int newly;
+ ssize_t newly;
int offset = -1;
while(offset < max - 1) {
if (newly == 0) {
/* EOF - not necessarily an error */
break;
- } else if (newly < 0) {
+ } else if (newly == -1) {
/* error */
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
"read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
- return newly;
+ return -1;
} else if (bytes[offset] == '\n') {
break;
}
/* convert header values */
*indicator = header[0];
- *block_len = header[1]<<16 | header[2]<<8 | header[3];
+ *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
}
/* read a message from the sending pipe in the standard format
(1-byte message indicator, 3-byte message length (excluding length
and indicator field), and the rest is the message) */
-static int
+static ssize_t
pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
char **err_msg)
{
int required;
- int newly;
- guchar header[4];
+ ssize_t newly;
+ gchar header[4];
/* read header (indicator and 3-byte length) */
newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
return 0;
}
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
- "read %d failed to read header: %u", pipe_fd, newly);
+ "read %d failed to read header: %lu", pipe_fd, (long)newly);
if (newly != -1) {
/*
* Short read, but not an immediate EOF.
*/
- *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
- newly);
+ *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
+ (long)newly);
}
return -1;
}
/* convert header values */
- pipe_convert_header(header, 4, indicator, &required);
+ pipe_convert_header((guchar*)header, 4, indicator, &required);
/* only indicator with no value? */
if(required == 0) {
/* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
memcpy(msg, header, sizeof(header));
newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
+ if (newly < 0) { /* error */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
+ "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
+ }
*err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
msg);
return -1;
static gboolean
sync_pipe_input_cb(gint source, gpointer user_data)
{
- capture_options *capture_opts = (capture_options *)user_data;
+ capture_session *cap_session = (capture_session *)user_data;
int ret;
char buffer[SP_MAX_MSG_LEN+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_len;
char *primary_msg;
int secondary_len;
char *secondary_msg;
char *wait_msg, *combined_msg;
+ int npackets;
nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
&primary_msg);
If we got an EOF, nread is 0 and primary_msg isn't set. This
is an indication that the capture is finished. */
- ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
+ ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
if(nread == 0) {
/* We got an EOF from the sync pipe. That means that the capture
child exited, and not in the middle of a message; we treat
}
/* No more child process. */
- capture_opts->fork_child = -1;
- capture_opts->fork_child_status = ret;
+ cap_session->fork_child = -1;
+ cap_session->fork_child_status = ret;
#ifdef _WIN32
- ws_close(capture_opts->signal_pipe_write_fd);
+ ws_close(cap_session->signal_pipe_write_fd);
#endif
- capture_input_closed(capture_opts, primary_msg);
+ capture_input_closed(cap_session, primary_msg);
g_free(primary_msg);
return FALSE;
}
/* we got a valid message block from the child, process it */
switch(indicator) {
case SP_FILE:
- if(!capture_input_new_file(capture_opts, buffer)) {
+ if(!capture_input_new_file(cap_session, buffer)) {
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
/* We weren't able to open the new capture file; user has been
This can also happen if the user specified "-", meaning
"standard output", as the capture file. */
- sync_pipe_stop(capture_opts);
- capture_input_closed(capture_opts, NULL);
+ sync_pipe_stop(cap_session);
+ capture_input_closed(cap_session, NULL);
return FALSE;
}
break;
case SP_PACKET_COUNT:
- nread = atoi(buffer);
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
- capture_input_new_packets(capture_opts, nread);
+ npackets = atoi(buffer);
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
+ capture_input_new_packets(cap_session, npackets);
break;
case SP_ERROR_MSG:
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
primary_msg = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
+ pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
secondary_msg = primary_msg + primary_len + 4;
/* message output */
- capture_input_error_message(capture_opts, primary_msg, secondary_msg);
+ capture_input_error_message(cap_session, primary_msg, secondary_msg);
/* the capture child will close the sync_pipe, nothing to do for now */
/* (an error message doesn't mean we have to stop capturing) */
break;
case SP_BAD_FILTER: {
char *ch;
- int index;
+ int indx;
ch = strtok(buffer, ":");
- index = (int)strtol(ch, NULL, 10);
+ indx = (int)strtol(ch, NULL, 10);
ch = strtok(NULL, ":");
- capture_input_cfilter_error_message(capture_opts, index, ch);
+ capture_input_cfilter_error_message(cap_session, indx, ch);
/* the capture child will close the sync_pipe, nothing to do for now */
break;
}
case SP_DROPS:
- capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
+ capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
break;
default:
g_assert_not_reached();
fork_child_status);
ret = -1;
}
- } else {
+ } 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;
}
#endif
g_get_current_time(&end_time);
- elapsed = (end_time.tv_sec - start_time.tv_sec) +
- ((end_time.tv_usec - start_time.tv_usec) / (float) 1e6);
+ elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
+ ((end_time.tv_usec - start_time.tv_usec) / 1e6));
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
return ret;
}
#ifdef _WIN32
/* tell the child through the signal pipe that we want to quit the capture */
static void
-signal_pipe_capquit_to_child(capture_options *capture_opts)
+signal_pipe_capquit_to_child(capture_session *cap_session)
{
const char quit_msg[] = "QUIT";
int ret;
-
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
/* it doesn't matter *what* we send here, the first byte will stop the capture */
/* simply sending a "QUIT" string */
- /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
- ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
+ /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
+ ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
if(ret == -1) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
- "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, g_strerror(errno));
+ "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
}
}
#endif
/* user wants to stop the capture run */
void
-sync_pipe_stop(capture_options *capture_opts)
+sync_pipe_stop(capture_session *cap_session)
{
#ifdef _WIN32
int count;
gboolean terminate = TRUE;
#endif
- if (capture_opts->fork_child != -1) {
+ if (cap_session->fork_child != -1) {
#ifndef _WIN32
/* send the SIGINT signal to close the capture child gracefully. */
- int sts = kill(capture_opts->fork_child, SIGINT);
+ int sts = kill(cap_session->fork_child, SIGINT);
if (sts != 0) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
"Sending SIGINT to child failed: %s\n", g_strerror(errno));
/* First, use the special signal pipe to try to close the capture child
* gracefully.
*/
- signal_pipe_capquit_to_child(capture_opts);
+ signal_pipe_capquit_to_child(cap_session);
/* Next, wait for the process to exit on its own */
for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
- if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
+ if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
childstatus != STILL_ACTIVE) {
terminate = FALSE;
break;
if (terminate) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
"sync_pipe_stop: forcing child to exit");
- sync_pipe_kill(capture_opts->fork_child);
+ sync_pipe_kill(cap_session->fork_child);
}
#endif
}
}
}
+void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
+ fetch_dumpcap_pid = cb;
+}
+
#endif /* HAVE_LIBPCAP */