diff -aur a/Makefile.in b/Makefile.in --- a/Makefile.in 2018-08-22 04:32:02.000000000 -0700 +++ b/Makefile.in 2019-04-23 11:52:06.000000000 -0700 @@ -422,7 +422,7 @@ valgrind_tools = @valgrind_tools@ NULL = ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = subprojects/spice-common server docs tools +SUBDIRS = subprojects/spice-common server docs pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = spice-server.pc DISTCHECK_CONFIGURE_FLAGS = \ From 23e9f84657479298f2527dc84ba64f00d811bc96 Mon Sep 17 00:00:00 2001 From: osy <50960678+osy@users.noreply.github.com> Date: Wed, 24 Apr 2019 18:50:25 -0700 Subject: [PATCH 1/2] OSX: added support for OSX/iOS Fix some Apple specific issues such as lack of %m print format and buggy TCP_NOPUSH implementation --- server/red-stream.c | 16 +++++++++++++++- server/red-worker.c | 2 ++ server/reds.c | 18 +++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/server/red-stream.c b/server/red-stream.c index 18c4a935..3fec87cf 100644 --- a/server/red-stream.c +++ b/server/red-stream.c @@ -39,7 +39,7 @@ #include "reds.h" // compatibility for *BSD systems -#ifndef TCP_CORK +#if !defined(TCP_CORK) && !defined(__APPLE__) #define TCP_CORK TCP_NOPUSH #endif @@ -100,6 +100,7 @@ struct RedStreamPrivate { SpiceCoreInterfaceInternal *core; }; +#if !defined(__APPLE__) // TCP_CORK doesn't exist and TCP_NOPUSH is broken /** * Set TCP_CORK on socket */ @@ -109,6 +110,7 @@ static int socket_set_cork(int socket, int enabled) SPICE_VERIFY(sizeof(enabled) == sizeof(int)); return setsockopt(socket, IPPROTO_TCP, TCP_CORK, &enabled, sizeof(enabled)); } +#endif static ssize_t stream_write_cb(RedStream *s, const void *buf, size_t size) { @@ -223,6 +225,7 @@ bool red_stream_write_all(RedStream *stream, const void *in_buf, size_t n) bool red_stream_set_auto_flush(RedStream *s, bool auto_flush) { +#if !defined(__APPLE__) if (s->priv->use_cork == !auto_flush) { return true; } @@ -239,15 +242,18 @@ bool red_stream_set_auto_flush(RedStream *s, bool auto_flush) socket_set_cork(s->socket, 0); s->priv->corked = false; } +#endif return true; } void red_stream_flush(RedStream *s) { +#if !defined(__APPLE__) if (s->priv->corked) { socket_set_cork(s->socket, 0); socket_set_cork(s->socket, 1); } +#endif } #if HAVE_SASL @@ -352,8 +358,16 @@ int red_stream_send_msgfd(RedStream *stream, int fd) memcpy(CMSG_DATA(cmsg), &fd, fd_size); } +#if defined(__APPLE__) + int set = 1; + setsockopt(stream->socket, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); +#endif do { +#if defined(__APPLE__) + r = sendmsg(stream->socket, &msgh, 0); +#else r = sendmsg(stream->socket, &msgh, MSG_NOSIGNAL); +#endif } while (r < 0 && (errno == EINTR || errno == EAGAIN)); return r; diff --git a/server/red-worker.c b/server/red-worker.c index ccab9d96..04c695bb 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -1391,7 +1391,9 @@ bool red_worker_run(RedWorker *worker) spice_error("create thread failed %d", r); } pthread_sigmask(SIG_SETMASK, &curr_sig_mask, NULL); +#if !defined(__APPLE__) // not supported pthread_setname_np(worker->thread, "SPICE Worker"); +#endif return r == 0; } diff --git a/server/reds.c b/server/reds.c index 85043a88..f1e19b87 100644 --- a/server/reds.c +++ b/server/reds.c @@ -3555,6 +3555,7 @@ static const int video_codec_caps[] = { static const char* parse_next_video_codec(const char *codecs, char **encoder, char **codec) { + size_t len; if (!codecs) { return NULL; } @@ -3562,8 +3563,22 @@ static const char* parse_next_video_codec(const char *codecs, char **encoder, if (!*codecs) { return NULL; } + len = strcspn(codecs, ";"); int n; *encoder = *codec = NULL; +#if defined(__APPLE__) + char *aencoder = malloc(len); + char *acodec = malloc(len); + if (sscanf(codecs, "%[0-9a-zA-Z_]:%[0-9a-zA-Z_]%n", aencoder, acodec, &n) == 2) { + // this avoids accepting "encoder:codec" followed by garbage like "$%*" + if (codecs[n] != ';' && codecs[n] != '\0') { + free(acodec); + acodec = NULL; + } + } + *encoder = aencoder; + *codec = acodec; +#else if (sscanf(codecs, "%m[0-9a-zA-Z_]:%m[0-9a-zA-Z_]%n", encoder, codec, &n) == 2) { // this avoids accepting "encoder:codec" followed by garbage like "$%*" if (codecs[n] != ';' && codecs[n] != '\0') { @@ -3571,7 +3586,8 @@ static const char* parse_next_video_codec(const char *codecs, char **encoder, *codec = NULL; } } - return codecs + strcspn(codecs, ";"); +#endif + return codecs + len; } static void reds_set_video_codecs_from_string(RedsState *reds, const char *codecs) -- 2.28.0 From 9fe644b11858d803d51a5b162be0b18d864fc5c3 Mon Sep 17 00:00:00 2001 From: osy <50960678+osy@users.noreply.github.com> Date: Wed, 28 Jul 2021 17:22:25 -0700 Subject: [PATCH 2/2] net-utils: fix EINVAL error on AF_UNIX sockets on darwin --- server/net-utils.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/server/net-utils.c b/server/net-utils.c index ca8a4e7f..8265f15e 100644 --- a/server/net-utils.c +++ b/server/net-utils.c @@ -34,6 +34,25 @@ #include "net-utils.h" +static inline bool +darwin_einval_on_unix_socket(int fd, int err) +{ +#if defined(__APPLE__) + if (err == EINVAL || err == EOPNOTSUPP) { + union { + struct sockaddr sa; + char buf[1024]; + } addr; + socklen_t len = sizeof(addr); + + if (getsockname(fd, &addr.sa, &len) == 0 && addr.sa.sa_family == AF_UNIX) { + return true; + } + } +#endif + return false; +} + /** * red_socket_set_keepalive: * @fd: a socket file descriptor @@ -46,7 +65,7 @@ bool red_socket_set_keepalive(int fd, bool enable, int timeout) int keepalive = !!enable; if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) == -1) { - if (errno != ENOTSUP) { + if (errno != ENOTSUP && !darwin_einval_on_unix_socket(fd, errno)) { g_warning("setsockopt for keepalive failed, %s", strerror(errno)); return false; } @@ -58,7 +77,7 @@ bool red_socket_set_keepalive(int fd, bool enable, int timeout) #ifdef HAVE_TCP_KEEPIDLE if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout)) == -1) { - if (errno != ENOTSUP) { + if (errno != ENOTSUP && !darwin_einval_on_unix_socket(fd, errno)) { g_warning("setsockopt for keepalive timeout failed, %s", strerror(errno)); return false; } @@ -81,7 +100,8 @@ bool red_socket_set_no_delay(int fd, bool no_delay) if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) != 0) { - if (errno != ENOTSUP && errno != ENOPROTOOPT) { + if (errno != ENOTSUP && errno != ENOPROTOOPT && + !darwin_einval_on_unix_socket(fd, errno)) { spice_warning("setsockopt failed, %s", strerror(errno)); return false; } -- 2.28.0 From 3977c49109906b9ab26950e301a5ad684c36a57d Mon Sep 17 00:00:00 2001 From: osy <50960678+osy@users.noreply.github.com> Date: Tue, 2 Nov 2021 12:56:54 -0700 Subject: [PATCH] reds: always send monitors config Windows VDagent needs this to apply the resolution changes. --- server/reds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/reds.c b/server/reds.c index f1e19b87..2fa2cfae 100644 --- a/server/reds.c +++ b/server/reds.c @@ -1182,7 +1182,7 @@ void reds_on_main_agent_data(RedsState *reds, MainChannelClient *mcc, const void return; case AGENT_MSG_FILTER_MONITORS_CONFIG: reds_on_main_agent_monitors_config(reds, mcc, message, size); - return; + break; case AGENT_MSG_FILTER_PROTO_ERROR: red_channel_client_shutdown(RED_CHANNEL_CLIENT(mcc)); return; -- 2.28.0