capture: Move capture pipe polling out of UI
Both CLI and Qt interfaces spin GLib mainloop. Move the capture pipe polling into common code to reduce code duplication.
This commit is contained in:
parent
5aba5772e9
commit
2d1380ae5b
|
@ -88,7 +88,9 @@ typedef void (*closed_fn)(capture_session *cap_session, gchar *msg);
|
|||
struct _capture_session {
|
||||
ws_process_id fork_child; /**< If not WS_INVALID_PID, in parent, process ID of child */
|
||||
int fork_child_status; /**< Child exit status */
|
||||
int pipe_input_id; /**< GLib input pipe source ID */
|
||||
#ifdef _WIN32
|
||||
int sync_pipe_read_fd; /**< Input pipe descriptor */
|
||||
int signal_pipe_write_fd; /**< the pipe to signal the child */
|
||||
#endif
|
||||
capture_state state; /**< current state of the capture engine */
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <wsutil/unicode-utils.h>
|
||||
#include <wsutil/win32-utils.h>
|
||||
#include <wsutil/ws_pipe.h>
|
||||
#else
|
||||
#include <glib-unix.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
|
@ -124,7 +126,9 @@ capture_session_init(capture_session *cap_session, capture_file *cf,
|
|||
{
|
||||
cap_session->cf = cf;
|
||||
cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
|
||||
cap_session->pipe_input_id = 0;
|
||||
#ifdef _WIN32
|
||||
cap_session->sync_pipe_read_fd = 0;
|
||||
cap_session->signal_pipe_write_fd = -1;
|
||||
#endif
|
||||
cap_session->state = CAPTURE_STOPPED;
|
||||
|
@ -201,6 +205,67 @@ init_pipe_args(int *argc) {
|
|||
return argv;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* The timer has expired, see if there's stuff to read from the pipe,
|
||||
if so, do the callback */
|
||||
static gint
|
||||
pipe_timer_cb(gpointer user_data)
|
||||
{
|
||||
capture_session *cap_session = (capture_session *)user_data;
|
||||
HANDLE handle;
|
||||
DWORD avail = 0;
|
||||
gboolean result;
|
||||
DWORD childstatus;
|
||||
gint iterations = 0;
|
||||
|
||||
/* try to read data from the pipe only 5 times, to avoid blocking */
|
||||
while(iterations < 5) {
|
||||
/* Oddly enough although Named pipes don't work on win9x,
|
||||
PeekNamedPipe does !!! */
|
||||
handle = (HANDLE) _get_osfhandle (cap_session->sync_pipe_read_fd);
|
||||
result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
|
||||
|
||||
/* Get the child process exit status */
|
||||
GetExitCodeProcess((HANDLE)cap_session->fork_child,
|
||||
&childstatus);
|
||||
|
||||
/* If the Peek returned an error, or there are bytes to be read
|
||||
or the childwatcher thread has terminated then call the normal
|
||||
callback */
|
||||
if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
|
||||
|
||||
/* And call the real handler */
|
||||
if (!sync_pipe_input_cb(cap_session->sync_pipe_read_fd, user_data)) {
|
||||
ws_debug("input pipe closed, iterations: %u", iterations);
|
||||
/* pipe closed, stop the timer */
|
||||
cap_session->pipe_input_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No data, stop now */
|
||||
break;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
}
|
||||
|
||||
/* we didn't stop the timer, so let it run */
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
#else
|
||||
static gboolean
|
||||
pipe_fd_cb(gint fd, GIOCondition condition _U_, gpointer user_data)
|
||||
{
|
||||
capture_session *cap_session = (capture_session *)user_data;
|
||||
if (!sync_pipe_input_cb(fd, user_data)) {
|
||||
cap_session->pipe_input_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ARGV_NUMBER_LEN 24
|
||||
/* a new capture run: start a new dumpcap task and hand over parameters through command line */
|
||||
gboolean
|
||||
|
@ -664,9 +729,20 @@ sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
|
|||
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) cap_session,
|
||||
&cap_session->fork_child, sync_pipe_input_cb);
|
||||
|
||||
if (cap_session->pipe_input_id) {
|
||||
g_source_remove(cap_session->pipe_input_id);
|
||||
cap_session->pipe_input_id = 0;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
/* Tricky to use pipes in win9x, as no concept of wait. NT can
|
||||
do this but that doesn't cover all win32 platforms. Attempt to do
|
||||
something similar here, start a timer and check for data on every
|
||||
timeout. */
|
||||
cap_session->sync_pipe_read_fd = sync_pipe_read_fd;
|
||||
cap_session->pipe_input_id = g_timeout_add(200, pipe_timer_cb, cap_session);
|
||||
#else
|
||||
cap_session->pipe_input_id = g_unix_fd_add(sync_pipe_read_fd, G_IO_IN | G_IO_HUP, pipe_fd_cb, cap_session);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
89
tshark.c
89
tshark.c
|
@ -30,7 +30,6 @@
|
|||
|
||||
#ifndef _WIN32
|
||||
#include <signal.h>
|
||||
#include <glib-unix.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -2502,94 +2501,6 @@ clean_exit:
|
|||
gboolean loop_running = FALSE;
|
||||
guint32 packet_count = 0;
|
||||
|
||||
|
||||
typedef struct pipe_input_tag {
|
||||
gint source;
|
||||
gpointer user_data;
|
||||
ws_process_id *child_process;
|
||||
pipe_input_cb_t input_cb;
|
||||
guint pipe_input_id;
|
||||
} pipe_input_t;
|
||||
|
||||
static pipe_input_t pipe_input;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* The timer has expired, see if there's stuff to read from the pipe,
|
||||
if so, do the callback */
|
||||
static gint
|
||||
pipe_timer_cb(gpointer data)
|
||||
{
|
||||
HANDLE handle;
|
||||
DWORD avail = 0;
|
||||
gboolean result;
|
||||
DWORD childstatus;
|
||||
pipe_input_t *pipe_input_p = data;
|
||||
gint iterations = 0;
|
||||
|
||||
/* try to read data from the pipe only 5 times, to avoid blocking */
|
||||
while(iterations < 5) {
|
||||
/* Oddly enough although Named pipes don't work on win9x,
|
||||
PeekNamedPipe does !!! */
|
||||
handle = (HANDLE) _get_osfhandle (pipe_input_p->source);
|
||||
result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
|
||||
|
||||
/* Get the child process exit status */
|
||||
GetExitCodeProcess((HANDLE)*(pipe_input_p->child_process),
|
||||
&childstatus);
|
||||
|
||||
/* If the Peek returned an error, or there are bytes to be read
|
||||
or the childwatcher thread has terminated then call the normal
|
||||
callback */
|
||||
if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
|
||||
|
||||
/* And call the real handler */
|
||||
if (!pipe_input_p->input_cb(pipe_input_p->source, pipe_input_p->user_data)) {
|
||||
ws_debug("input pipe closed, iterations: %u", iterations);
|
||||
/* pipe closed, stop the timer */
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No data, stop now */
|
||||
break;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
}
|
||||
|
||||
/* we didn't stopped the timer, so let it run */
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
#else
|
||||
static gboolean
|
||||
pipe_fd_cb(gint fd _U_, GIOCondition condition _U_, gpointer user_data)
|
||||
{
|
||||
pipe_input_t *pipe_input_p = (pipe_input_t *)user_data;
|
||||
return pipe_input_p->input_cb(pipe_input_p->source, pipe_input_p->user_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
|
||||
{
|
||||
|
||||
pipe_input.source = source;
|
||||
pipe_input.child_process = child_process;
|
||||
pipe_input.user_data = user_data;
|
||||
pipe_input.input_cb = input_cb;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Tricky to use pipes in win9x, as no concept of wait. NT can
|
||||
do this but that doesn't cover all win32 platforms. GTK can do
|
||||
this but doesn't seem to work over processes. Attempt to do
|
||||
something similar here, start a timer and check for data on every
|
||||
timeout. */
|
||||
pipe_input.pipe_input_id = g_timeout_add(200, pipe_timer_cb, &pipe_input);
|
||||
#else
|
||||
pipe_input.pipe_input_id = g_unix_fd_add(source, G_IO_IN | G_IO_HUP, pipe_fd_cb, &pipe_input);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const nstime_t *
|
||||
tshark_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
|
||||
{
|
||||
|
|
|
@ -95,11 +95,6 @@ DIAG_ON(frame-larger-than=)
|
|||
// If we ever add support for multiple windows this will need to be replaced.
|
||||
static LograyMainWindow *gbl_cur_main_window_ = NULL;
|
||||
|
||||
void pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
|
||||
{
|
||||
gbl_cur_main_window_->setPipeInputHandler(source, user_data, child_process, input_cb);
|
||||
}
|
||||
|
||||
static void plugin_if_mainwindow_apply_filter(GHashTable * data_set)
|
||||
{
|
||||
if (!gbl_cur_main_window_ || !data_set)
|
||||
|
@ -334,11 +329,6 @@ LograyMainWindow::LograyMainWindow(QWidget *parent) :
|
|||
#endif
|
||||
, display_filter_dlg_(NULL)
|
||||
, capture_filter_dlg_(NULL)
|
||||
#ifdef _WIN32
|
||||
, pipe_timer_(NULL)
|
||||
#else
|
||||
, pipe_notifier_(NULL)
|
||||
#endif
|
||||
#if defined(Q_OS_MAC)
|
||||
, dock_menu_(NULL)
|
||||
#endif
|
||||
|
@ -844,43 +834,6 @@ void LograyMainWindow::removeInterfaceToolbar(const gchar *menu_title)
|
|||
menu->menuAction()->setVisible(!menu->actions().isEmpty());
|
||||
}
|
||||
|
||||
void LograyMainWindow::setPipeInputHandler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
|
||||
{
|
||||
pipe_source_ = source;
|
||||
pipe_child_process_ = child_process;
|
||||
pipe_user_data_ = user_data;
|
||||
pipe_input_cb_ = input_cb;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Tricky to use pipes in win9x, as no concept of wait. NT can
|
||||
do this but that doesn't cover all win32 platforms. GTK can do
|
||||
this but doesn't seem to work over processes. Attempt to do
|
||||
something similar here, start a timer and check for data on every
|
||||
timeout. */
|
||||
/*ws_log(NULL, LOG_LEVEL_DEBUG, "pipe_input_set_handler: new");*/
|
||||
|
||||
if (pipe_timer_) {
|
||||
disconnect(pipe_timer_, SIGNAL(timeout()), this, SLOT(pipeTimeout()));
|
||||
delete pipe_timer_;
|
||||
}
|
||||
|
||||
pipe_timer_ = new QTimer(this);
|
||||
connect(pipe_timer_, SIGNAL(timeout()), this, SLOT(pipeTimeout()));
|
||||
connect(pipe_timer_, SIGNAL(destroyed()), this, SLOT(pipeNotifierDestroyed()));
|
||||
pipe_timer_->start(200);
|
||||
#else
|
||||
if (pipe_notifier_) {
|
||||
disconnect(pipe_notifier_, SIGNAL(activated(int)), this, SLOT(pipeActivated(int)));
|
||||
delete pipe_notifier_;
|
||||
}
|
||||
|
||||
pipe_notifier_ = new QSocketNotifier(pipe_source_, QSocketNotifier::Read);
|
||||
// XXX ui/gtk/gui_utils.c sets the encoding. Do we need to do the same?
|
||||
connect(pipe_notifier_, SIGNAL(activated(int)), this, SLOT(pipeActivated(int)));
|
||||
connect(pipe_notifier_, SIGNAL(destroyed()), this, SLOT(pipeNotifierDestroyed()));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool LograyMainWindow::eventFilter(QObject *obj, QEvent *event) {
|
||||
|
||||
// The user typed some text. Start filling in a filter.
|
||||
|
|
|
@ -106,7 +106,6 @@ class LograyMainWindow : public MainWindow
|
|||
public:
|
||||
explicit LograyMainWindow(QWidget *parent = nullptr);
|
||||
~LograyMainWindow();
|
||||
void setPipeInputHandler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb);
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
capture_session *captureSession() { return &cap_session_; }
|
||||
|
@ -195,17 +194,6 @@ private:
|
|||
FilterDialog *display_filter_dlg_;
|
||||
FilterDialog *capture_filter_dlg_;
|
||||
|
||||
// Pipe input
|
||||
gint pipe_source_;
|
||||
gpointer pipe_user_data_;
|
||||
ws_process_id *pipe_child_process_;
|
||||
pipe_input_cb_t pipe_input_cb_;
|
||||
#ifdef _WIN32
|
||||
QTimer *pipe_timer_;
|
||||
#else
|
||||
QSocketNotifier *pipe_notifier_;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
QMenu *dock_menu_;
|
||||
#endif
|
||||
|
@ -333,9 +321,7 @@ private slots:
|
|||
*/
|
||||
void startCapture(QStringList);
|
||||
void startCapture();
|
||||
void pipeTimeout();
|
||||
void pipeActivated(int source);
|
||||
void pipeNotifierDestroyed();
|
||||
void popLiveCaptureInProgress();
|
||||
void stopCapture();
|
||||
|
||||
void loadWindowGeometry();
|
||||
|
|
|
@ -516,6 +516,7 @@ void LograyMainWindow::captureCaptureUpdateFinished(capture_session *session) {
|
|||
setMenusForCaptureFile();
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -538,6 +539,7 @@ void LograyMainWindow::captureCaptureFixedFinished(capture_session *) {
|
|||
setMenusForCaptureFile(true);
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -558,6 +560,7 @@ void LograyMainWindow::captureCaptureFailed(capture_session *) {
|
|||
mainApp->popStatus(WiresharkApplication::FileStatus);
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -917,75 +920,9 @@ void LograyMainWindow::startCapture(QStringList interfaces _U_) {
|
|||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
// Copied from ui/gtk/gui_utils.c
|
||||
void LograyMainWindow::pipeTimeout() {
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
DWORD avail = 0;
|
||||
gboolean result, result1;
|
||||
DWORD childstatus;
|
||||
gint iterations = 0;
|
||||
|
||||
|
||||
/* try to read data from the pipe only 5 times, to avoid blocking */
|
||||
while (iterations < 5) {
|
||||
/* Oddly enough although Named pipes don't work on win9x,
|
||||
PeekNamedPipe does !!! */
|
||||
handle = (HANDLE)_get_osfhandle(pipe_source_);
|
||||
result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
|
||||
|
||||
/* Get the child process exit status */
|
||||
result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
|
||||
&childstatus);
|
||||
|
||||
/* If the Peek returned an error, or there are bytes to be read
|
||||
or the childwatcher thread has terminated then call the normal
|
||||
callback */
|
||||
if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
|
||||
|
||||
/* And call the real handler */
|
||||
if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
|
||||
ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
|
||||
/* pipe closed, return false so that the old timer is not run again */
|
||||
delete pipe_timer_;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* No data, stop now */
|
||||
break;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void LograyMainWindow::pipeActivated(int source) {
|
||||
Q_UNUSED(source)
|
||||
|
||||
#ifndef _WIN32
|
||||
ws_assert(source == pipe_source_);
|
||||
|
||||
pipe_notifier_->setEnabled(false);
|
||||
if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
|
||||
pipe_notifier_->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
delete pipe_notifier_;
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void LograyMainWindow::pipeNotifierDestroyed()
|
||||
{
|
||||
void LograyMainWindow::popLiveCaptureInProgress() {
|
||||
/* Pop the "<live capture in progress>" message off the status bar. */
|
||||
main_ui_->statusBar->setFileName(capture_file_);
|
||||
|
||||
#ifdef _WIN32
|
||||
pipe_timer_ = NULL;
|
||||
#else
|
||||
pipe_notifier_ = NULL;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void LograyMainWindow::stopCapture() {
|
||||
|
|
|
@ -97,11 +97,6 @@ DIAG_ON(frame-larger-than=)
|
|||
// If we ever add support for multiple windows this will need to be replaced.
|
||||
static WiresharkMainWindow *gbl_cur_main_window_ = NULL;
|
||||
|
||||
void pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
|
||||
{
|
||||
gbl_cur_main_window_->setPipeInputHandler(source, user_data, child_process, input_cb);
|
||||
}
|
||||
|
||||
static void plugin_if_mainwindow_apply_filter(GHashTable * data_set)
|
||||
{
|
||||
if (!gbl_cur_main_window_ || !data_set)
|
||||
|
@ -336,11 +331,6 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
|
|||
#endif
|
||||
, display_filter_dlg_(NULL)
|
||||
, capture_filter_dlg_(NULL)
|
||||
#ifdef _WIN32
|
||||
, pipe_timer_(NULL)
|
||||
#else
|
||||
, pipe_notifier_(NULL)
|
||||
#endif
|
||||
#if defined(Q_OS_MAC)
|
||||
, dock_menu_(NULL)
|
||||
#endif
|
||||
|
@ -875,43 +865,6 @@ void WiresharkMainWindow::removeInterfaceToolbar(const gchar *menu_title)
|
|||
menu->menuAction()->setVisible(!menu->actions().isEmpty());
|
||||
}
|
||||
|
||||
void WiresharkMainWindow::setPipeInputHandler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
|
||||
{
|
||||
pipe_source_ = source;
|
||||
pipe_child_process_ = child_process;
|
||||
pipe_user_data_ = user_data;
|
||||
pipe_input_cb_ = input_cb;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Tricky to use pipes in win9x, as no concept of wait. NT can
|
||||
do this but that doesn't cover all win32 platforms. GTK can do
|
||||
this but doesn't seem to work over processes. Attempt to do
|
||||
something similar here, start a timer and check for data on every
|
||||
timeout. */
|
||||
/*ws_log(NULL, LOG_LEVEL_DEBUG, "pipe_input_set_handler: new");*/
|
||||
|
||||
if (pipe_timer_) {
|
||||
disconnect(pipe_timer_, SIGNAL(timeout()), this, SLOT(pipeTimeout()));
|
||||
delete pipe_timer_;
|
||||
}
|
||||
|
||||
pipe_timer_ = new QTimer(this);
|
||||
connect(pipe_timer_, SIGNAL(timeout()), this, SLOT(pipeTimeout()));
|
||||
connect(pipe_timer_, SIGNAL(destroyed()), this, SLOT(pipeNotifierDestroyed()));
|
||||
pipe_timer_->start(200);
|
||||
#else
|
||||
if (pipe_notifier_) {
|
||||
disconnect(pipe_notifier_, SIGNAL(activated(int)), this, SLOT(pipeActivated(int)));
|
||||
delete pipe_notifier_;
|
||||
}
|
||||
|
||||
pipe_notifier_ = new QSocketNotifier(pipe_source_, QSocketNotifier::Read);
|
||||
// XXX ui/gtk/gui_utils.c sets the encoding. Do we need to do the same?
|
||||
connect(pipe_notifier_, SIGNAL(activated(int)), this, SLOT(pipeActivated(int)));
|
||||
connect(pipe_notifier_, SIGNAL(destroyed()), this, SLOT(pipeNotifierDestroyed()));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WiresharkMainWindow::eventFilter(QObject *obj, QEvent *event) {
|
||||
|
||||
// The user typed some text. Start filling in a filter.
|
||||
|
|
|
@ -112,7 +112,6 @@ class WiresharkMainWindow : public MainWindow
|
|||
public:
|
||||
explicit WiresharkMainWindow(QWidget *parent = nullptr);
|
||||
~WiresharkMainWindow();
|
||||
void setPipeInputHandler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb);
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
capture_session *captureSession() { return &cap_session_; }
|
||||
|
@ -204,17 +203,6 @@ private:
|
|||
FilterDialog *display_filter_dlg_;
|
||||
FilterDialog *capture_filter_dlg_;
|
||||
|
||||
// Pipe input
|
||||
gint pipe_source_;
|
||||
gpointer pipe_user_data_;
|
||||
ws_process_id *pipe_child_process_;
|
||||
pipe_input_cb_t pipe_input_cb_;
|
||||
#ifdef _WIN32
|
||||
QTimer *pipe_timer_;
|
||||
#else
|
||||
QSocketNotifier *pipe_notifier_;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
QMenu *dock_menu_;
|
||||
#endif
|
||||
|
@ -356,9 +344,7 @@ private slots:
|
|||
*/
|
||||
void startCapture(QStringList);
|
||||
void startCapture();
|
||||
void pipeTimeout();
|
||||
void pipeActivated(int source);
|
||||
void pipeNotifierDestroyed();
|
||||
void popLiveCaptureInProgress();
|
||||
void stopCapture();
|
||||
|
||||
void loadWindowGeometry();
|
||||
|
|
|
@ -547,6 +547,7 @@ void WiresharkMainWindow::captureCaptureUpdateFinished(capture_session *session)
|
|||
setMenusForCaptureFile();
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -569,6 +570,7 @@ void WiresharkMainWindow::captureCaptureFixedFinished(capture_session *) {
|
|||
setMenusForCaptureFile(true);
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -589,6 +591,7 @@ void WiresharkMainWindow::captureCaptureFailed(capture_session *) {
|
|||
mainApp->popStatus(WiresharkApplication::FileStatus);
|
||||
|
||||
setWindowIcon(mainApp->normalIcon());
|
||||
popLiveCaptureInProgress();
|
||||
|
||||
if (global_commandline_info.quit_after_cap) {
|
||||
// Command line asked us to quit after capturing.
|
||||
|
@ -977,75 +980,9 @@ DIAG_ON(stringop-overread)
|
|||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
// Copied from ui/gtk/gui_utils.c
|
||||
void WiresharkMainWindow::pipeTimeout() {
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
DWORD avail = 0;
|
||||
gboolean result, result1;
|
||||
DWORD childstatus;
|
||||
gint iterations = 0;
|
||||
|
||||
|
||||
/* try to read data from the pipe only 5 times, to avoid blocking */
|
||||
while (iterations < 5) {
|
||||
/* Oddly enough although Named pipes don't work on win9x,
|
||||
PeekNamedPipe does !!! */
|
||||
handle = (HANDLE)_get_osfhandle(pipe_source_);
|
||||
result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
|
||||
|
||||
/* Get the child process exit status */
|
||||
result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
|
||||
&childstatus);
|
||||
|
||||
/* If the Peek returned an error, or there are bytes to be read
|
||||
or the childwatcher thread has terminated then call the normal
|
||||
callback */
|
||||
if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
|
||||
|
||||
/* And call the real handler */
|
||||
if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
|
||||
ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
|
||||
/* pipe closed, return false so that the old timer is not run again */
|
||||
delete pipe_timer_;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* No data, stop now */
|
||||
break;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void WiresharkMainWindow::pipeActivated(int source) {
|
||||
Q_UNUSED(source)
|
||||
|
||||
#ifndef _WIN32
|
||||
ws_assert(source == pipe_source_);
|
||||
|
||||
pipe_notifier_->setEnabled(false);
|
||||
if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
|
||||
pipe_notifier_->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
delete pipe_notifier_;
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void WiresharkMainWindow::pipeNotifierDestroyed()
|
||||
{
|
||||
void WiresharkMainWindow::popLiveCaptureInProgress() {
|
||||
/* Pop the "<live capture in progress>" message off the status bar. */
|
||||
main_ui_->statusBar->setFileName(capture_file_);
|
||||
|
||||
#ifdef _WIN32
|
||||
pipe_timer_ = NULL;
|
||||
#else
|
||||
pipe_notifier_ = NULL;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void WiresharkMainWindow::stopCapture() {
|
||||
|
|
|
@ -45,11 +45,6 @@ extern void main_window_update(void);
|
|||
/* Exit routine provided by UI-specific code. */
|
||||
extern void exit_application(int status);
|
||||
|
||||
/* read from a pipe (callback) */
|
||||
typedef gboolean (*pipe_input_cb_t) (gint source, gpointer user_data);
|
||||
/* install callback function, called if pipe input is available */
|
||||
extern void pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb);
|
||||
|
||||
/* XXX - Yes this isn't the best place, but they are used by file_dlg_win32.c, which is supposed
|
||||
to be GUI independent, but has lots of GTK leanings. But if you put these in a GTK UI
|
||||
header file, file_dlg_win32.c complains about all of the GTK structures also in the header
|
||||
|
|
Loading…
Reference in New Issue