Qt: Add asynchronous simple dialog

When extcap fails before connecting to pipes, ws_write() in
InterfaceToolbar::controlSend() fails and error message is displayed to
the user.

Before this change, the message box would block until the user closes
the message. As the controlSend() was called inside "capture prepared"
context the remaining capture preparation code would wait for the user
action. However, the pipeTimeout() would get called before user confirms
the message as Qt would be processing all events in the main event
queue. This led to "capture failed" executing before "capture prepared"
finished. Such interruption caused multiple issues including freeing
buffer that was not yet allocated.

Bug: 15743
Change-Id: I6bc2734126292cdc5b560418069caf98747be68e
Reviewed-on: https://code.wireshark.org/review/33208
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Tomasz Moń <desowin@gmail.com>
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Tomasz Moń 2019-05-15 17:56:08 +02:00 committed by Anders Broman
parent 40f6cb70e9
commit ca1163ab60
4 changed files with 41 additions and 6 deletions

View File

@ -550,15 +550,15 @@ void InterfaceToolbar::controlReceived(QString ifname, int num, int command, QBy
break;
case commandInformationMessage:
simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "%s", payload.data());
simple_dialog_async(ESD_TYPE_INFO, ESD_BTN_OK, "%s", payload.data());
break;
case commandWarningMessage:
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "%s", payload.data());
simple_dialog_async(ESD_TYPE_WARN, ESD_BTN_OK, "%s", payload.data());
break;
case commandErrorMessage:
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", payload.data());
simple_dialog_async(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", payload.data());
break;
default:
@ -598,9 +598,9 @@ void InterfaceToolbar::controlSend(QString ifname, int num, int command, const Q
if (ws_write(interface_[ifname].out_fd, ba.data(), ba.length()) != ba.length())
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Unable to send control message:\n%s.",
g_strerror(errno));
simple_dialog_async(ESD_TYPE_ERROR, ESD_BTN_OK,
"Unable to send control message:\n%s.",
g_strerror(errno));
}
}

View File

@ -73,6 +73,19 @@ simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
return NULL;
}
gpointer
simple_dialog_async(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
{
va_list ap;
va_start(ap, msg_format);
SimpleDialog sd(wsApp->mainWindow(), type, btn_mask, msg_format, ap);
va_end(ap);
sd.show();
return NULL;
}
/*
* Alert box, with optional "don't show this message again" variable
* and checkbox, and optional secondary text.
@ -333,6 +346,23 @@ int SimpleDialog::exec()
}
}
void SimpleDialog::show()
{
if (!message_box_) {
return;
}
message_box_->setDetailedText(detailed_text_);
message_box_->setCheckBox(check_box_);
message_box_->setModal(Qt::WindowModal);
message_box_->setAttribute(Qt::WA_DeleteOnClose);
message_box_->show();
/* Message box was shown and will be deleted once user closes it */
message_box_ = 0;
}
const MessagePair SimpleDialog::splitMessage(QString &message) const
{
if (message.startsWith(primary_delimiter_)) {

View File

@ -38,6 +38,7 @@ public:
void setDetailedText(QString text) { detailed_text_ = text; }
void setCheckBox(QCheckBox *cb) { check_box_ = cb; }
int exec();
void show();
private:
const MessagePair splitMessage(QString &message) const;

View File

@ -96,6 +96,10 @@ extern gpointer simple_dialog(ESD_TYPE_E type, gint btn_mask,
const gchar *msg_format, ...)
G_GNUC_PRINTF(3, 4);
extern gpointer simple_dialog_async(ESD_TYPE_E type, gint btn_mask,
const gchar *msg_format, ...)
G_GNUC_PRINTF(3, 4);
/** Surround the primary dialog message text by
* simple_dialog_primary_start() and simple_dialog_primary_end().
*/