summaryrefslogtreecommitdiffstats
path: root/ui/qt/interface_toolbar_reader.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /ui/qt/interface_toolbar_reader.cpp
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/qt/interface_toolbar_reader.cpp')
-rw-r--r--ui/qt/interface_toolbar_reader.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/ui/qt/interface_toolbar_reader.cpp b/ui/qt/interface_toolbar_reader.cpp
new file mode 100644
index 00000000..d12f7472
--- /dev/null
+++ b/ui/qt/interface_toolbar_reader.cpp
@@ -0,0 +1,181 @@
+/* interface_toolbar_reader.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+
+#include "interface_toolbar_reader.h"
+#include "sync_pipe.h"
+#include "wsutil/file_util.h"
+
+#include <QThread>
+
+const int header_size = 6;
+
+#ifdef _WIN32
+int InterfaceToolbarReader::async_pipe_read(void *data, int nbyte)
+{
+ BOOL success;
+ DWORD nof_bytes_read;
+ OVERLAPPED overlap;
+ int bytes_read = -1;
+
+ overlap.Pointer = 0;
+ overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (overlap.hEvent == NULL)
+ {
+ // CreateEvent failed with error code GetLastError()
+ return -1;
+ }
+
+ success = ReadFile(control_in_, data, nbyte, &nof_bytes_read, &overlap);
+
+ if (success && nof_bytes_read != 0)
+ {
+ // The read operation completed successfully.
+ bytes_read = nof_bytes_read;
+ }
+ else if (!success && GetLastError() == ERROR_IO_PENDING)
+ {
+ // The operation is still pending, wait for a signal.
+ if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0)
+ {
+ // The wait operation has completed.
+ success = GetOverlappedResult(control_in_, &overlap, &nof_bytes_read, FALSE);
+
+ if (success && nof_bytes_read != 0)
+ {
+ // The get result operation completed successfully.
+ bytes_read = nof_bytes_read;
+ }
+ }
+ }
+
+ CloseHandle(overlap.hEvent);
+ return bytes_read;
+}
+#endif
+
+int InterfaceToolbarReader::pipe_read(char *data, int nbyte)
+{
+ int total_len = 0;
+
+ while (total_len < nbyte)
+ {
+ char *data_ptr = data + total_len;
+ int data_len = nbyte - total_len;
+
+#ifdef _WIN32
+ int read_len = async_pipe_read(data_ptr, data_len);
+#else
+ int read_len = (int)ws_read(fd_in_, data_ptr, data_len);
+#endif
+ if (read_len == -1)
+ {
+ if (errno != EAGAIN)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ total_len += read_len;
+ }
+
+ if (QThread::currentThread()->isInterruptionRequested())
+ {
+ return -1;
+ }
+ }
+
+ return total_len;
+}
+
+void InterfaceToolbarReader::loop()
+{
+ QByteArray header;
+ QByteArray payload;
+
+#ifndef _WIN32
+ struct timeval timeout;
+ fd_set readfds;
+ fd_in_ = ws_open(control_in_.toUtf8(), O_RDONLY | O_BINARY | O_NONBLOCK, 0);
+
+ if (fd_in_ == -1)
+ {
+ emit finished();
+ return;
+ }
+#endif
+
+ header.resize(header_size);
+
+ forever
+ {
+#ifndef _WIN32
+ FD_ZERO(&readfds);
+ FD_SET(fd_in_, &readfds);
+
+ timeout.tv_sec = 2;
+ timeout.tv_usec = 0;
+
+ int ret = select(fd_in_ + 1, &readfds, NULL, NULL, &timeout);
+ if (ret == -1)
+ {
+ break;
+ }
+
+ if (QThread::currentThread()->isInterruptionRequested())
+ {
+ break;
+ }
+
+ if (ret == 0 || !FD_ISSET(fd_in_, &readfds))
+ {
+ continue;
+ }
+#endif
+
+ // Read the header from the pipe.
+ if (pipe_read(header.data(), header_size) != header_size)
+ {
+ break;
+ }
+
+ unsigned char high_nibble = header[1] & 0xFF;
+ unsigned char mid_nibble = header[2] & 0xFF;
+ unsigned char low_nibble = header[3] & 0xFF;
+ int payload_len = (int)((high_nibble << 16) + (mid_nibble << 8) + low_nibble) - 2;
+
+ payload.resize(payload_len);
+ // Read the payload from the pipe.
+ if (pipe_read(payload.data(), payload_len) != payload_len)
+ {
+ break;
+ }
+
+ if (header[0] == SP_TOOLBAR_CTRL)
+ {
+ emit received(ifname_, (unsigned char)header[4], (unsigned char)header[5], payload);
+ }
+ }
+
+#ifndef _WIN32
+ ws_close(fd_in_);
+#endif
+
+ emit finished();
+}