[Spice-devel] [PATCH spice 07/18] tests: add fdpass stream test
Marc-André Lureau
marcandre.lureau at gmail.com
Tue Dec 15 15:49:21 PST 2015
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
---
server/tests/Makefile.am | 7 ++-
server/tests/stream-test.c | 118 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 1 deletion(-)
create mode 100644 server/tests/stream-test.c
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index e23e356..636b9f2 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -46,11 +46,13 @@ noinst_PROGRAMS = \
test_vdagent \
test_display_width_stride \
spice-server-replay \
+ stream-test \
stat_test \
$(NULL)
-TESTS = \
+TESTS = \
stat_test \
+ stream-test \
$(NULL)
check_PROGRAMS = $(TESTS)
@@ -119,6 +121,9 @@ spice_server_replay_SOURCES = \
test_display_base.h \
$(NULL)
+stream_test_SOURCES = stream-test.c
+stream_test_LDADD = libtest.la ../libserver.la
+
stat_test_SOURCES = stat-main.c
stat_test_LDADD = \
$(LDADD) \
diff --git a/server/tests/stream-test.c b/server/tests/stream-test.c
new file mode 100644
index 0000000..7dc9fbf
--- /dev/null
+++ b/server/tests/stream-test.c
@@ -0,0 +1,118 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "common/log.h"
+#include "reds-stream.h"
+#include "basic_event_loop.h"
+
+static int server_init(void)
+{
+ SpiceCoreInterface *core = basic_event_loop_init();
+ SpiceServer *server = spice_server_new();
+
+ return spice_server_init(server, core);
+}
+
+
+/*
+ * Based on code from Keith Packard:
+ * http://keithp.com/blogs/fd-passing/
+ */
+static ssize_t
+sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
+{
+ ssize_t size;
+
+ if (fd) {
+ struct msghdr msg;
+ struct iovec iov;
+ union {
+ struct cmsghdr cmsghdr;
+ char control[CMSG_SPACE(sizeof (int))];
+ } cmsgu;
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = bufsize;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgu.control;
+ msg.msg_controllen = sizeof(cmsgu.control);
+ size = recvmsg(sock, &msg, 0);
+ if (size < 0) {
+ perror ("recvmsg");
+ exit(1);
+ }
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ if (cmsg->cmsg_level != SOL_SOCKET) {
+ fprintf(stderr, "invalid cmsg_level %d\n",
+ cmsg->cmsg_level);
+ exit(1);
+ }
+ if (cmsg->cmsg_type != SCM_RIGHTS) {
+ fprintf(stderr, "invalid cmsg_type %d\n",
+ cmsg->cmsg_type);
+ exit(1);
+ }
+
+ *fd = *((int *) CMSG_DATA(cmsg));
+ } else
+ *fd = -1;
+ } else {
+ size = read(sock, buf, bufsize);
+ if (size < 0) {
+ perror("read");
+ exit(1);
+ }
+ }
+
+ return size;
+}
+
+int main(int argc, char *argv[])
+{
+ RedsStream *st[2];
+ int sv[2];
+ int ret, fd = -1;
+ char c;
+
+ spice_return_val_if_fail(server_init() == 0, -1);
+
+ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) {
+ spice_error("socketpair failed %s", strerror(errno));
+ return -1;
+ }
+
+ st[0] = reds_stream_new(sv[0]);
+ spice_assert(reds_stream_is_plain_unix(st[0]));
+ st[1] = reds_stream_new(sv[1]);
+ spice_assert(reds_stream_is_plain_unix(st[1]));
+
+ /* send stdin, for the fun of it */
+ ret = reds_stream_send_msgfd(st[0], 0);
+ spice_assert(ret == 1);
+ ret = sock_fd_read(sv[1], &c, 1, &fd);
+ spice_assert(c == '@');
+ spice_assert(ret == 1);
+ spice_assert(fd != -1);
+ close(fd);
+
+ /* send invalid fd behaviour */
+ ret = reds_stream_send_msgfd(st[0], -1);
+ spice_assert(ret == 1);
+ ret = sock_fd_read(sv[1], &c, 1, &fd);
+ spice_assert(c == '@');
+ spice_assert(ret == 1);
+ spice_assert(fd == -1);
+
+ reds_stream_free(st[0]);
+ reds_stream_free(st[1]);
+
+ return 0;
+}
--
2.5.0
More information about the Spice-devel
mailing list