Tarantool development patches archive
 help / color / mirror / Atom feed
From: "Max Melentiev" <dmarc-noreply@freelists.org> (Redacted sender "m.melentiev" for DMARC)
To: tarantool-patches@freelists.org
Cc: Max Melentiev <m.melentiev@corp.mail.ru>
Subject: [tarantool-patches] [PATCH] Enable support for NOTIFY_SOCKET on macOS
Date: Mon, 19 Aug 2019 11:28:13 +0300	[thread overview]
Message-ID: <20190819082813.38237-1-m.melentiev@corp.mail.ru> (raw)

To make it possible to develop and test related features on macOS.

SOCK_CLOEXEC (not available on macOS) flag for socket()
is replaced with `fcntl(fd, F_SETFD, FD_CLOEXEC)` which has the same effect.

MSG_NOSIGNAL flag for sendmsg is also not available on macOS.
However it has SO_NOSIGPIPE flag for setsockopt which disables SIGPIPE.
So it requires different solution for different OS.
Inspired by https://nwat.xyz/blog/2014/01/16/porting-msg_more-and-msg_nosigpipe-to-osx/

`sendmsg()` is replaced with `sendto()` because `msg_namelen` was calculated incorrectly.
New method builds message automatically without errors.
---
 src/systemd.c             | 34 ++++++++++++++++++----------------
 src/systemd.h             | 25 ++++++++++++++++---------
 src/trivia/config.h.cmake |  5 -----
 3 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/src/systemd.c b/src/systemd.c
index b6c48afe2..f49a7f3f9 100644
--- a/src/systemd.c
+++ b/src/systemd.c
@@ -30,7 +30,6 @@
  */
 #include "systemd.h"
 
-#if defined(WITH_SYSTEMD)
 #include <errno.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -68,11 +67,25 @@ int systemd_init() {
 		say_error("systemd: NOTIFY_SOCKET is longer that MAX_UNIX_PATH");
 		goto error;
 	}
-	if ((systemd_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1) {
+	if ((systemd_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
 		say_syserror("systemd: failed to create unix socket");
 		goto error;
 	}
-	int sndbuf_sz = 8 * 1024 * 1024;
+	if (fcntl(systemd_fd, F_SETFD, FD_CLOEXEC) == -1) {
+		say_syserror("systemd: fcntl failed to set FD_CLOEXEC");
+		goto error;
+	}
+
+	#ifdef SYSTEMD_USE_SO_NOSIGPIPE
+	int val = 1;
+	if (setsockopt(systemd_fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val,
+			sizeof(val)) < 0) {
+		say_syserror("systemd: failed to set NOSIGPIPE");
+		goto error;
+	}
+	#endif
+
+	int sndbuf_sz = 4 * 1024 * 1024;
 	if (setsockopt(systemd_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_sz,
 		      sizeof(int)) < 0) {
 		say_syserror("systemd: failed to set sndbuf size");
@@ -100,23 +113,13 @@ int systemd_notify(const char *message) {
 	struct sockaddr_un sa = {
 		.sun_family = AF_UNIX,
 	};
-	struct iovec vec = {
-		.iov_base = (char  *)message,
-		.iov_len  = (size_t )strlen(message)
-	};
-	struct msghdr msg = {
-		.msg_iov    = &vec,
-		.msg_iovlen = 1,
-		.msg_name   = &sa,
-	};
-
-	msg.msg_namelen = sizeof(sa.sun_family) + strlen(sd_unix_path);
 	strncpy(sa.sun_path, sd_unix_path, sizeof(sa.sun_path));
 	if (sa.sun_path[0] == '@')
 		sa.sun_path[0] = '\0';
 
 	say_debug("systemd: sending message '%s'", message);
-	ssize_t sent = sendmsg(systemd_fd, &msg, MSG_NOSIGNAL);
+	ssize_t sent = sendto(systemd_fd, message, (size_t)strlen(message),
+		SYSTEMD_MSG_NOSIGNAL, (struct sockaddr*)&sa, sizeof(sa));
 	if (sent == -1) {
 		say_syserror("systemd: failed to send message");
 		return -1;
@@ -151,4 +154,3 @@ systemd_snotify(const char *format, ...)
 	va_end(args);
 	return res;
 }
-#endif /* defined(WITH_SYSTEMD) */
diff --git a/src/systemd.h b/src/systemd.h
index f4f36e2cf..f86159581 100644
--- a/src/systemd.h
+++ b/src/systemd.h
@@ -35,11 +35,26 @@
 
 #include "trivia/config.h"
 
+/*
+ * Linux supports MSG_NOSIGNAL flag for sendmsg.
+ * macOS lacks it, but has SO_NOSIGPIPE for setsockopt to achieve same behaviour.
+ */
+#ifdef MSG_NOSIGNAL
+# define SYSTEMD_MSG_NOSIGNAL MSG_NOSIGNAL
+#else
+# define SYSTEMD_MSG_NOSIGNAL 0
+# include <sys/socket.h>
+# ifdef SO_NOSIGPIPE
+#  define SYSTEMD_USE_SO_NOSIGPIPE
+# else
+#  error "No way to block SIGPIPE in sendmsg!"
+# endif
+#endif
+
 #if defined(__cplusplus)
 extern "C" {
 #endif /* defined(__cplusplus) */
 
-#if defined(WITH_SYSTEMD)
 /**
  * Open connection with systemd daemon (using unix socket located in
  * "NOTIFY_SOCKET" environmnent variable)
@@ -95,14 +110,6 @@ systemd_vsnotify(const char *format, va_list ap);
 int
 systemd_snotify(const char *format, ...);
 
-#else /* !defined(WITH_SYSTEMD) */
-#  define systemd_init()
-#  define systemd_free()
-#  define systemd_notify(...)
-#  define systemd_vsnotify(...)
-#  define systemd_snotify(...)
-#endif /* WITH_SYSTEMD */
-
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake
index ca0057d2b..f50f64a02 100644
--- a/src/trivia/config.h.cmake
+++ b/src/trivia/config.h.cmake
@@ -201,11 +201,6 @@
  */
 #cmakedefine HAVE_ICU_STRCOLLUTF8 1
 
-/*
-* Defined if systemd is enabled
- */
-#cmakedefine WITH_SYSTEMD 1
-
 /** \cond public */
 
 /** System configuration dir (e.g /etc) */
-- 
2.21.0

             reply	other threads:[~2019-08-19  8:28 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-19  8:28 Max Melentiev [this message]
2019-08-19 19:33 ` [tarantool-patches] " Alexander Turenko
2019-08-21  8:31   ` Maxim Melentiev
2019-08-21 15:52     ` Konstantin Osipov
2019-08-22  8:59       ` Maxim Melentiev
2019-08-22 10:06         ` Konstantin Osipov
2019-08-22 12:44           ` Maxim Melentiev
2019-08-22 13:03             ` Konstantin Osipov
2019-08-22 14:27               ` Maxim Melentiev
2019-08-23 12:11                 ` Alexander Turenko
2019-08-27 23:51                 ` Kirill Yukhin
2019-08-21 22:45     ` Alexander Turenko
2019-08-19 20:18 ` Konstantin Osipov
2019-08-20 15:26   ` Maxim Melentiev
2019-08-20 16:22     ` Konstantin Osipov
2019-08-27 23:54 ` Kirill Yukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190819082813.38237-1-m.melentiev@corp.mail.ru \
    --to=dmarc-noreply@freelists.org \
    --cc=m.melentiev@corp.mail.ru \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH] Enable support for NOTIFY_SOCKET on macOS' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox