Tomasz Kramkowski

Systemd Notifications on a Budget

Recently, the inclusion of libsystemd as a dependency of distribution vendored copies of OpenSSH server caused a bit of a scare. Not necessarily because of libsystemd. That being said, maybe NIH isn't that bad in some situations, maybe we shouldn't be so eager to add a dependency when a short bit of code is sufficient. So I wrote a short bit of code.

// SPDX-License-Identifier: CC0-1.0
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

int notify_socket_send(const char *message)
{
    const char *path = getenv("NOTIFY_SOCKET");
    if (path == NULL || path[0] == '\0') return 0;
    struct sockaddr_un sa = {.sun_family = AF_UNIX};
    size_t len = strnlen(path, sizeof sa.sun_path);
    if (len >= sizeof sa.sun_path) return ENAMETOOLONG;
    memcpy(sa.sun_path, path, len);
    if (sa.sun_path[0] == '@') sa.sun_path[0] = '\0';
    size_t addrlen = sa.sun_path[0] == '\0' ? sizeof sa.sun_family + len
                                            : sizeof sa;
    int fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
    if (fd == -1) return errno;
    ssize_t ret = sendto(fd, message, strlen(message), 0, (void *)&sa, addrlen);
    int errno_save = errno;
    close(fd);
    return ret == -1 ? errno_save : 0;
}

Please do let me know about all the bugs you find. I'm sure there's at least one.

Updates on 2024-04-01: There were bugs and I have now gotten around to compiling the code. This version latest also incorporates some suggestions from Leah Neukirchen and Rich Felker (dalias). The changes are as follows: