summaryrefslogtreecommitdiffstats
path: root/include/sd-notify.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:34:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:34:59 +0000
commit36a5f1403a91d93db689e989ead3d9cf140c3cde (patch)
tree278cc6e7860205b0d40a895b977a46ea09018eb2 /include/sd-notify.h
parentReleasing progress-linux version 2.6.7+dfsg-1~exp1~progress7.99u1. (diff)
downloadopenldap-36a5f1403a91d93db689e989ead3d9cf140c3cde.tar.xz
openldap-36a5f1403a91d93db689e989ead3d9cf140c3cde.zip
Merging upstream version 2.6.8+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/sd-notify.h')
-rw-r--r--include/sd-notify.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/include/sd-notify.h b/include/sd-notify.h
new file mode 100644
index 0000000..be284f6
--- /dev/null
+++ b/include/sd-notify.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: MIT-0 */
+/* Implement the systemd notify protocol without external dependencies.
+ * Supports both readiness notification on startup and on reloading,
+ * according to the protocol defined at:
+ * https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
+ * This protocol is guaranteed to be stable as per:
+ * https://systemd.io/PORTABILITY_AND_STABILITY/ */
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+static int sd_notify(int ignore, const char *message) {
+ union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_un sun;
+ } socket_addr = {
+ .sun.sun_family = AF_UNIX,
+ };
+ size_t path_length, message_length;
+ const char *socket_path;
+ int fd = -1;
+ int rc = 1;
+
+ socket_path = getenv("NOTIFY_SOCKET");
+ if (!socket_path)
+ return 0; /* Not running under systemd? Nothing to do */
+
+ if (!message)
+ return -EINVAL;
+
+ message_length = strlen(message);
+ if (message_length == 0)
+ return -EINVAL;
+
+ /* Only AF_UNIX is supported, with path or abstract sockets */
+ if (socket_path[0] != '/' && socket_path[0] != '@')
+ return -EAFNOSUPPORT;
+
+ path_length = strlen(socket_path);
+ /* Ensure there is room for NUL byte */
+ if (path_length >= sizeof(socket_addr.sun.sun_path))
+ return -E2BIG;
+
+ memcpy(socket_addr.sun.sun_path, socket_path, path_length);
+
+ /* Support for abstract socket */
+ if (socket_addr.sun.sun_path[0] == '@')
+ socket_addr.sun.sun_path[0] = 0;
+
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return -errno;
+
+ ssize_t written = sendto(fd, message, message_length, 0,
+ &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + path_length);
+ if (written != (ssize_t) message_length)
+ rc = written < 0 ? -errno : -EPROTO;
+
+ close(fd);
+ return rc;
+}