Update sd-daemon.[ch] from systemd
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 12 Feb 2013 11:14:55 +0000 (11:14 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 12 Feb 2013 11:14:55 +0000 (11:14 +0000)
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=60681

dbus/Makefile.am
dbus/sd-daemon.c
dbus/sd-daemon.h

index bb5ccca..3679e3f 100644 (file)
@@ -308,5 +308,5 @@ clean-local:
        /bin/rm *.bb *.bbg *.da *.gcov .libs/*.da .libs/*.bbg || true
 
 update-systemd:
-       curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c > sd-daemon.c
-       curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h > sd-daemon.h
+       curl http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c > $(srcdir)/sd-daemon.c
+       curl http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h > $(srcdir)/sd-daemon.h
index 9c23b91..80aadf7 100644 (file)
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#ifdef __BIONIC__
+#include <linux/fcntl.h>
+#else
 #include <sys/fcntl.h>
+#endif
 #include <netinet/in.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stddef.h>
+#include <limits.h>
+
+#if defined(__linux__)
+#include <mqueue.h>
+#endif
 
 #include "sd-daemon.h"
 
-int sd_listen_fds(int unset_environment) {
+#if (__GNUC__ >= 4)
+#ifdef SD_EXPORT_SYMBOLS
+/* Export symbols */
+#define _sd_export_ __attribute__ ((visibility("default")))
+#else
+/* Don't export the symbols */
+#define _sd_export_ __attribute__ ((visibility("hidden")))
+#endif
+#else
+#define _sd_export_
+#endif
+
+_sd_export_ int sd_listen_fds(int unset_environment) {
 
 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
         return 0;
@@ -53,7 +75,8 @@ int sd_listen_fds(int unset_environment) {
         char *p = NULL;
         unsigned long l;
 
-        if (!(e = getenv("LISTEN_PID"))) {
+        e = getenv("LISTEN_PID");
+        if (!e) {
                 r = 0;
                 goto finish;
         }
@@ -66,7 +89,7 @@ int sd_listen_fds(int unset_environment) {
                 goto finish;
         }
 
-        if (!p || *p || l <= 0) {
+        if (!p || p == e || *p || l <= 0) {
                 r = -EINVAL;
                 goto finish;
         }
@@ -77,7 +100,8 @@ int sd_listen_fds(int unset_environment) {
                 goto finish;
         }
 
-        if (!(e = getenv("LISTEN_FDS"))) {
+        e = getenv("LISTEN_FDS");
+        if (!e) {
                 r = 0;
                 goto finish;
         }
@@ -90,7 +114,7 @@ int sd_listen_fds(int unset_environment) {
                 goto finish;
         }
 
-        if (!p || *p) {
+        if (!p || p == e || *p) {
                 r = -EINVAL;
                 goto finish;
         }
@@ -98,7 +122,8 @@ int sd_listen_fds(int unset_environment) {
         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
                 int flags;
 
-                if ((flags = fcntl(fd, F_GETFD)) < 0) {
+                flags = fcntl(fd, F_GETFD);
+                if (flags < 0) {
                         r = -errno;
                         goto finish;
                 }
@@ -124,13 +149,12 @@ finish:
 #endif
 }
 
-int sd_is_fifo(int fd, const char *path) {
+_sd_export_ int sd_is_fifo(int fd, const char *path) {
         struct stat st_fd;
 
         if (fd < 0)
                 return -EINVAL;
 
-        memset(&st_fd, 0, sizeof(st_fd));
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
 
@@ -140,7 +164,6 @@ int sd_is_fifo(int fd, const char *path) {
         if (path) {
                 struct stat st_path;
 
-                memset(&st_path, 0, sizeof(st_path));
                 if (stat(path, &st_path) < 0) {
 
                         if (errno == ENOENT || errno == ENOTDIR)
@@ -157,6 +180,42 @@ int sd_is_fifo(int fd, const char *path) {
         return 1;
 }
 
+_sd_export_ int sd_is_special(int fd, const char *path) {
+        struct stat st_fd;
+
+        if (fd < 0)
+                return -EINVAL;
+
+        if (fstat(fd, &st_fd) < 0)
+                return -errno;
+
+        if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode))
+                return 0;
+
+        if (path) {
+                struct stat st_path;
+
+                if (stat(path, &st_path) < 0) {
+
+                        if (errno == ENOENT || errno == ENOTDIR)
+                                return 0;
+
+                        return -errno;
+                }
+
+                if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode))
+                        return
+                                st_path.st_dev == st_fd.st_dev &&
+                                st_path.st_ino == st_fd.st_ino;
+                else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode))
+                        return st_path.st_rdev == st_fd.st_rdev;
+                else
+                        return 0;
+        }
+
+        return 1;
+}
+
 static int sd_is_socket_internal(int fd, int type, int listening) {
         struct stat st_fd;
 
@@ -208,13 +267,14 @@ union sockaddr_union {
         struct sockaddr_storage storage;
 };
 
-int sd_is_socket(int fd, int family, int type, int listening) {
+_sd_export_ int sd_is_socket(int fd, int family, int type, int listening) {
         int r;
 
         if (family < 0)
                 return -EINVAL;
 
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
                 return r;
 
         if (family > 0) {
@@ -236,7 +296,7 @@ int sd_is_socket(int fd, int family, int type, int listening) {
         return 1;
 }
 
-int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
+_sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
         union sockaddr_union sockaddr;
         socklen_t l;
         int r;
@@ -244,7 +304,8 @@ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port
         if (family != 0 && family != AF_INET && family != AF_INET6)
                 return -EINVAL;
 
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
                 return r;
 
         memset(&sockaddr, 0, sizeof(sockaddr));
@@ -281,12 +342,13 @@ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port
         return 1;
 }
 
-int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
+_sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
         union sockaddr_union sockaddr;
         socklen_t l;
         int r;
 
-        if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+        r = sd_is_socket_internal(fd, type, listening);
+        if (r <= 0)
                 return r;
 
         memset(&sockaddr, 0, sizeof(sockaddr));
@@ -302,29 +364,66 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
                 return 0;
 
         if (path) {
-                if (length <= 0)
+                if (length == 0)
                         length = strlen(path);
 
-                if (length <= 0)
+                if (length == 0)
                         /* Unnamed socket */
-                        return l == sizeof(sa_family_t);
+                        return l == offsetof(struct sockaddr_un, sun_path);
 
                 if (path[0])
                         /* Normal path socket */
                         return
-                                (l >= sizeof(sa_family_t) + length + 1) &&
+                                (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
                                 memcmp(path, sockaddr.un.sun_path, length+1) == 0;
                 else
                         /* Abstract namespace socket */
                         return
-                                (l == sizeof(sa_family_t) + length) &&
+                                (l == offsetof(struct sockaddr_un, sun_path) + length) &&
                                 memcmp(path, sockaddr.un.sun_path, length) == 0;
         }
 
         return 1;
 }
 
-int sd_notify(int unset_environment, const char *state) {
+_sd_export_ int sd_is_mq(int fd, const char *path) {
+#if !defined(__linux__)
+        return 0;
+#else
+        struct mq_attr attr;
+
+        if (fd < 0)
+                return -EINVAL;
+
+        if (mq_getattr(fd, &attr) < 0)
+                return -errno;
+
+        if (path) {
+                char fpath[PATH_MAX];
+                struct stat a, b;
+
+                if (path[0] != '/')
+                        return -EINVAL;
+
+                if (fstat(fd, &a) < 0)
+                        return -errno;
+
+                strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12);
+                fpath[sizeof(fpath)-1] = 0;
+
+                if (stat(fpath, &b) < 0)
+                        return -errno;
+
+                if (a.st_dev != b.st_dev ||
+                    a.st_ino != b.st_ino)
+                        return 0;
+        }
+
+        return 1;
+#endif
+}
+
+_sd_export_ int sd_notify(int unset_environment, const char *state) {
 #if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC)
         return 0;
 #else
@@ -339,7 +438,8 @@ int sd_notify(int unset_environment, const char *state) {
                 goto finish;
         }
 
-        if (!(e = getenv("NOTIFY_SOCKET")))
+        e = getenv("NOTIFY_SOCKET");
+        if (!e)
                 return 0;
 
         /* Must be an abstract socket, or an absolute path */
@@ -348,7 +448,8 @@ int sd_notify(int unset_environment, const char *state) {
                 goto finish;
         }
 
-        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+        if (fd < 0) {
                 r = -errno;
                 goto finish;
         }
@@ -366,7 +467,7 @@ int sd_notify(int unset_environment, const char *state) {
 
         memset(&msghdr, 0, sizeof(msghdr));
         msghdr.msg_name = &sockaddr;
-        msghdr.msg_namelen = sizeof(sa_family_t) + strlen(e);
+        msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
 
         if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
                 msghdr.msg_namelen = sizeof(struct sockaddr_un);
@@ -392,7 +493,7 @@ finish:
 #endif
 }
 
-int sd_notifyf(int unset_environment, const char *format, ...) {
+_sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) {
 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
         return 0;
 #else
@@ -414,7 +515,7 @@ int sd_notifyf(int unset_environment, const char *format, ...) {
 #endif
 }
 
-int sd_booted(void) {
+_sd_export_ int sd_booted(void) {
 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
         return 0;
 #else
index c68c96d..fb7456d 100644 (file)
@@ -58,21 +58,21 @@ extern "C" {
 
   You may find an up-to-date version of these source files online:
 
-  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
-  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h
+  http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c
 
   This should compile on non-Linux systems, too, but with the
   exception of the sd_is_xxx() calls all functions will become NOPs.
 
-  See sd-daemon(7) for more information.
+  See sd-daemon(3) for more information.
 */
 
+#ifndef _sd_printf_attr_
 #if __GNUC__ >= 4
 #define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
-#define _sd_hidden_ __attribute__ ((visibility("hidden")))
 #else
 #define _sd_printf_attr_(a,b)
-#define _sd_hidden_
+#endif
 #endif
 
 /*
@@ -109,7 +109,7 @@ extern "C" {
 
   See sd_listen_fds(3) for more information.
 */
-int sd_listen_fds(int unset_environment) _sd_hidden_;
+int sd_listen_fds(int unset_environment);
 
 /*
   Helper call for identifying a passed file descriptor. Returns 1 if
@@ -121,7 +121,19 @@ int sd_listen_fds(int unset_environment) _sd_hidden_;
 
   See sd_is_fifo(3) for more information.
 */
-int sd_is_fifo(int fd, const char *path) _sd_hidden_;
+int sd_is_fifo(int fd, const char *path);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a special character device on the file
+  system stored under the specified path, 0 otherwise.
+  If path is NULL a path name check will not be done and the call
+  only verifies if the file descriptor refers to a special character.
+  Returns a negative errno style error code on failure.
+
+  See sd_is_special(3) for more information.
+*/
+int sd_is_special(int fd, const char *path);
 
 /*
   Helper call for identifying a passed file descriptor. Returns 1 if
@@ -137,7 +149,7 @@ int sd_is_fifo(int fd, const char *path) _sd_hidden_;
 
   See sd_is_socket(3) for more information.
 */
-int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
+int sd_is_socket(int fd, int family, int type, int listening);
 
 /*
   Helper call for identifying a passed file descriptor. Returns 1 if
@@ -151,7 +163,7 @@ int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
 
   See sd_is_socket_inet(3) for more information.
 */
-int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_;
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
 
 /*
   Helper call for identifying a passed file descriptor. Returns 1 if
@@ -167,17 +179,25 @@ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port
 
   See sd_is_socket_unix(3) for more information.
 */
-int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_;
+int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a POSIX Message Queue of the specified name,
+  0 otherwise. If path is NULL a message queue name check is not
+  done. Returns a negative errno style error code on failure.
+*/
+int sd_is_mq(int fd, const char *path);
 
 /*
   Informs systemd about changed daemon state. This takes a number of
-  newline seperated environment-style variable assignments in a
+  newline separated environment-style variable assignments in a
   string. The following variables are known:
 
      READY=1      Tells systemd that daemon startup is finished (only
                   relevant for services of Type=notify). The passed
                   argument is a boolean "1" or "0". Since there is
-                  little value in signalling non-readiness the only
+                  little value in signaling non-readiness the only
                   value daemons should send is "READY=1".
 
      STATUS=...   Passes a single-line status string back to systemd
@@ -197,8 +217,13 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
      MAINPID=...  The main pid of a daemon, in case systemd did not
                   fork off the process itself. Example: "MAINPID=4711"
 
+     WATCHDOG=1   Tells systemd to update the watchdog timestamp.
+                  Services using this feature should do this in
+                  regular intervals. A watchdog framework can use the
+                  timestamps to detect failed services.
+
   Daemons can choose to send additional variables. However, it is
-  recommened to prefix variable names not listed above with X_.
+  recommended to prefix variable names not listed above with X_.
 
   Returns a negative errno-style error code on failure. Returns > 0
   if systemd could be notified, 0 if it couldn't possibly because
@@ -213,7 +238,7 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
 
   See sd_notify(3) for more information.
 */
-int sd_notify(int unset_environment, const char *state) _sd_hidden_;
+int sd_notify(int unset_environment, const char *state);
 
 /*
   Similar to sd_notify() but takes a format string.
@@ -235,7 +260,7 @@ int sd_notify(int unset_environment, const char *state) _sd_hidden_;
 
   See sd_notifyf(3) for more information.
 */
-int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3) _sd_hidden_;
+int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
 
 /*
   Returns > 0 if the system was booted with systemd. Returns < 0 on
@@ -244,11 +269,11 @@ int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(
   fine. You should NOT protect them with a call to this function. Also
   note that this function checks whether the system, not the user
   session is controlled by systemd. However the functions above work
-  for both session and system services.
+  for both user and system services.
 
   See sd_booted(3) for more information.
 */
-int sd_booted(void) _sd_hidden_;
+int sd_booted(void);
 
 #ifdef __cplusplus
 }