[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/3] qga: Channel: Add functions for checking serial
From: |
Sameeh Jubran |
Subject: |
[Qemu-devel] [PATCH 1/3] qga: Channel: Add functions for checking serial status |
Date: |
Sun, 13 Aug 2017 18:58:47 +0300 |
From: Sameeh Jubran <address@hidden>
This commit adds functions to check if the serial is
connected/disconnected or else if it has been attached or detached.
Signed-off-by: Sameeh Jubran <address@hidden>
---
qga/channel-posix.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
qga/channel-win32.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
qga/channel.h | 9 ++++++++
3 files changed, 123 insertions(+)
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 3f34465..d307cf4 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -295,3 +295,57 @@ void ga_channel_free(GAChannel *c)
}
g_free(c);
}
+
+static bool is_serial_present(GAChannelMethod method, const gchar *path,
+ int *error_code)
+{
+ int fd = -1;
+ bool ret = true;
+
+ assert(error_code);
+ *error_code = 0;
+
+ switch (method) {
+ case GA_CHANNEL_VIRTIO_SERIAL:
+ fd = qemu_open(path, O_RDWR | O_NONBLOCK
+#ifndef CONFIG_SOLARIS
+ | O_ASYNC
+#endif
+ );
+ break;
+ case GA_CHANNEL_ISA_SERIAL:
+ fd = qemu_open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ break;
+ default:
+ ret = false;
+ }
+ if (fd < 0) {
+ *error_code = errno;
+ ret = false;
+ } else {
+ close(fd);
+ }
+ return ret;
+}
+
+bool ga_channel_serial_is_present(GAChannelMethod method, const gchar *path)
+{
+ int error_code = 0;
+ return is_serial_present(method, path, &error_code) ||
+ error_code == EBUSY;
+}
+
+bool ga_channel_was_serial_attached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached)
+{
+ int error_code = 0;
+ return !is_serial_attached &&
+ is_serial_present(method, path, &error_code);
+}
+bool ga_channel_was_serial_detached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached)
+{
+ int error_code = 0;
+ return is_serial_attached && !is_serial_present(method, path, &error_code)
+ && error_code == ENOENT;
+}
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 7e6dc4d..2d51bee 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -354,3 +354,63 @@ void ga_channel_free(GAChannel *c)
g_free(c->rstate.buf);
g_free(c);
}
+
+static bool is_serial_present(GAChannelMethod method, const gchar *path,
+ DWORD *err)
+{
+ gchar newpath[MAXPATHLEN] = { 0 };
+ bool ret = false;
+
+ assert(err);
+
+ if (method != GA_CHANNEL_VIRTIO_SERIAL && method != GA_CHANNEL_ISA_SERIAL)
{
+ g_critical("unsupported communication method");
+ return false;
+ }
+
+ if (method == GA_CHANNEL_ISA_SERIAL) {
+ snprintf(newpath, sizeof(newpath), "\\\\.\\%s", path);
+ } else {
+ g_strlcpy(newpath, path, sizeof(newpath));
+ }
+
+ HANDLE handle = CreateFile(newpath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ *err = GetLastError();
+ ret = false;
+ } else {
+ ret = true;
+ }
+
+ CloseHandle(handle);
+ return ret;
+}
+
+bool ga_channel_serial_is_present(GAChannelMethod method, const gchar *path)
+{
+ DWORD err_code;
+ return is_serial_present(method, path, &err_code) ||
+ err_code == ERROR_ACCESS_DENIED;
+}
+
+bool ga_channel_was_serial_attached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached)
+{
+ DWORD err_code;
+ return !is_serial_attached && is_serial_present(method, path, &err_code);
+}
+
+bool ga_channel_was_serial_detached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached)
+{
+ DWORD err_code = NO_ERROR;
+ /* In order to make sure the serial that qemu-ga uses is the one that
+ * was detached. We'll get the error ERROR_FILE_NOT_FOUND when
+ * attempting to call CreateFile with the serial path.
+ */
+ return is_serial_attached && !is_serial_present(method, path, &err_code)
+ && err_code == ERROR_FILE_NOT_FOUND;
+}
diff --git a/qga/channel.h b/qga/channel.h
index 1778416..acb3d73 100644
--- a/qga/channel.h
+++ b/qga/channel.h
@@ -12,6 +12,10 @@
#ifndef QGA_CHANNEL_H
#define QGA_CHANNEL_H
+#ifndef _WIN32
+#define SUBSYSTEM_VIRTIO_SERIAL "virtio-ports";
+#define SUBSYSTEM_ISA_SERIAL "isa-serial";
+#endif
typedef struct GAChannel GAChannel;
@@ -30,5 +34,10 @@ GAChannel *ga_channel_new(GAChannelMethod method, const
gchar *path,
void ga_channel_free(GAChannel *c);
GIOStatus ga_channel_read(GAChannel *c, gchar *buf, gsize size, gsize *count);
GIOStatus ga_channel_write_all(GAChannel *c, const gchar *buf, gsize size);
+bool ga_channel_serial_is_present(GAChannelMethod method, const gchar *path);
+bool ga_channel_was_serial_attached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached);
+bool ga_channel_was_serial_detached(GAChannelMethod method, const gchar *path,
+ bool is_serial_attached);
#endif
--
2.9.4