diff options
| -rw-r--r-- | Makefile.am | 4 | ||||
| -rw-r--r-- | sd-daemon.c | 110 | ||||
| -rw-r--r-- | sd-daemon.h | 57 | 
3 files changed, 141 insertions, 30 deletions
diff --git a/Makefile.am b/Makefile.am index 53beb69..febc355 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,5 +95,5 @@ DISTCHECK_CONFIGURE_FLAGS = \  	--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)  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 > sd-daemon.c +	curl http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h > sd-daemon.h diff --git a/sd-daemon.c b/sd-daemon.c index 6d1eebf..763e079 100644 --- a/sd-daemon.c +++ b/sd-daemon.c @@ -32,7 +32,11 @@  #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> @@ -41,10 +45,27 @@  #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; @@ -125,7 +146,7 @@ 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) @@ -158,6 +179,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; @@ -209,7 +266,7 @@ 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) @@ -237,7 +294,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; @@ -282,7 +339,7 @@ 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; @@ -325,7 +382,44 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t          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 @@ -393,7 +487,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 @@ -415,7 +509,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 diff --git a/sd-daemon.h b/sd-daemon.h index d0a0a94..fe51159 100644 --- a/sd-daemon.h +++ b/sd-daemon.h @@ -58,8 +58,8 @@ 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/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. @@ -75,14 +75,6 @@ extern "C" {  #endif  #endif -#ifndef _sd_hidden_ -#if (__GNUC__ >= 4) && !defined(SD_EXPORT_SYMBOLS) -#define _sd_hidden_ __attribute__ ((visibility("hidden"))) -#else -#define _sd_hidden_ -#endif -#endif -  /*    Log levels for usage on stderr: @@ -117,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 @@ -129,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 @@ -145,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 @@ -159,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 @@ -175,7 +179,15 @@ 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 @@ -185,7 +197,7 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t       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 @@ -205,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 @@ -221,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. @@ -243,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 @@ -256,7 +273,7 @@ int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(    See sd_booted(3) for more information.  */ -int sd_booted(void) _sd_hidden_; +int sd_booted(void);  #ifdef __cplusplus  }  | 
