summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/macro.h2
-rw-r--r--src/sd-daemon.c20
-rw-r--r--src/sd-daemon.h291
3 files changed, 194 insertions, 119 deletions
diff --git a/src/macro.h b/src/macro.h
index 763a4de27a..d00e70bf6d 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -38,6 +38,8 @@
#define _weak_ __attribute__ ((weak))
#define _likely_(x) (__builtin_expect(!!(x),1))
#define _unlikely_(x) (__builtin_expect(!!(x),0))
+#define _public_ __attribute__ ((visibility("default")))
+#define _hidden_ __attribute__ ((visibility("hidden")))
/* Rounds up */
static inline size_t ALIGN(size_t l) {
diff --git a/src/sd-daemon.c b/src/sd-daemon.c
index e6b9a6f3c2..cb568b5e65 100644
--- a/src/sd-daemon.c
+++ b/src/sd-daemon.c
@@ -426,3 +426,23 @@ int sd_notifyf(int unset_environment, const char *format, ...) {
return r;
#endif
}
+
+int sd_booted(void) {
+#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
+ return 0;
+#else
+
+ struct stat a, b;
+
+ /* We simply test whether the systemd cgroup hierarchy is
+ * mounted */
+
+ if (lstat("/cgroup", &a) < 0)
+ return 0;
+
+ if (lstat("/cgroup/systemd", &b) < 0)
+ return 0;
+
+ return a.st_dev != b.st_dev;
+#endif
+}
diff --git a/src/sd-daemon.h b/src/sd-daemon.h
index 20c260c40d..dc18f42eaa 100644
--- a/src/sd-daemon.h
+++ b/src/sd-daemon.h
@@ -34,17 +34,43 @@
extern "C" {
#endif
-/* Reference implementation of a few systemd related interfaces for
- * writing daemons. These interfaces are trivial to implement. To
- * simplify porting we provide this reference
- * implementation. Applications are welcome to reimplement the
- * algorithms described here, if they do not want to include these two
- * source files. */
-
-#ifdef __GNUC__
+/*
+ Reference implementation of a few systemd related interfaces for
+ writing daemons. These interfaces are trivial to implement. To
+ simplify porting we provide this reference implementation.
+ Applications are welcome to reimplement the algorithms described
+ here if they do not want to include these two source files.
+
+ The following functionality is provided:
+
+ - Support for logging with log levels on stderr
+ - File descriptor passing for socket-based activation
+ - Daemon startup and status notification
+ - Detection of systemd boots
+
+ You may compile this with -DDISABLE_SYSTEMD to disable systemd
+ support. This make all those calls NOPs that are directly related to
+ systemd (i.e. only sd_is_xxx() will stay useful).
+
+ Since this is drop-in code we don't want any of our symbols to be
+ exported in any case. Hence we declare hidden visibility for all of
+ them.
+
+ 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
+
+ This should compile on non-Linux systems, too, but with the
+ exception of the sd_is_xxx() calls all functions will become NOPs.
+*/
+
+#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
/*
@@ -54,7 +80,6 @@ extern "C" {
This is similar to printk() usage in the kernel.
*/
-
#define SD_EMERG "<0>" /* system is unusable */
#define SD_ALERT "<1>" /* action must be taken immediately */
#define SD_CRIT "<2>" /* critical conditions */
@@ -67,116 +92,144 @@ extern "C" {
/* The first passed file descriptor is fd 3 */
#define SD_LISTEN_FDS_START 3
-/* Returns how many file descriptors have been passed, or a negative
- * errno code on failure. Optionally, removes the $LISTEN_FDS and
- * $LISTEN_PID file descriptors from the environment (recommended, but
- * problematic in threaded environments). If r is the return value of
- * this function you'll find the file descriptors passed as fds
- * SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
- * errno style error code on failure. This function call ensures that
- * the FD_CLOEXEC flag is set for the passed file descriptors, to make
- * sure they are not passed on to child processes. If FD_CLOEXEC shall
- * not be set, the caller needs to unset it after this call for all file
- * descriptors that are used.*/
-int sd_listen_fds(int unset_environment);
-
-/* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is a FIFO in 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 FIFO. Returns a negative errno style error code on
- * failure. */
-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 socket of the specified family (AF_INET,
- * ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
- * family is 0 a socket family check will not be done. If type is 0 a
- * socket type check will not be done and the call only verifies if
- * the file descriptor refers to a socket. If listening is > 0 it is
- * verified that the socket is in listening mode. (i.e. listen() has
- * been called) If listening is == 0 it is verified that the socket is
- * not in listening mode. If listening is < 0 no listening mode check
- * is done. Returns a negative errno style error code on failure. */
-int sd_is_socket(int fd, int family, int type, int listening);
-
-/* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is an Internet socket, of the specified family
- * (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
- * SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
- * check is not done. If type is 0 a socket type check will not be
- * done. If port is 0 a socket port check will not be done. The
- * listening flag is used the same way as in sd_is_socket(). Returns a
- * negative errno style error code on failure. */
-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
- * the file descriptor is an AF_UNIX socket of the specified type
- * (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
- * a socket type check will not be done. If path is NULL a socket path
- * check will not be done. For normal AF_UNIX sockets set length to
- * 0. For abstract namespace sockets set length to the length of the
- * socket name (including the initial 0 byte), and pass the full
- * socket path in path (including the initial 0 byte). The listening
- * flag is used the same way as in sd_is_socket(). Returns a negative
- * errno style error code on failure. */
-int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
-
-/* Informs systemd about changed daemon state. This takes a numeber of
- * newline seperated environment-style variable assignments in a
- * string. The following strings 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
- * value daemons should send is "READY=1".
- *
- * STATUS=... Passes a single-line status string back to systemd
- * that describes the daemon state. This is free-from
- * and can be used for various purposes: general state
- * feedback, fsck-like programs could pass completion
- * percentages and failing programs could pass a human
- * readable error message. Example: "STATUS=Completed
- * 66% of file system check..."
- *
- * ERRNO=... If a daemon fails, the errno-style error code,
- * formatted as string. Example: "ERRNO=2" for ENOENT.
- *
- * BUSERROR=... If a daemon fails, the D-Bus error-style error
- * code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
- *
- * MAINPID=... The main pid of a daemon, in case systemd did not
- * fork off the process itself. Example: "MAINPID=4711"
- *
- * Daemons can choose to send additional variables.
- *
- * Returns a negative errno-style error code on failure. Returns > 0
- * if systemd could be notified, 0 if it couldn't possibly because
- * systemd is not running.
- *
- * See sd_notifyf() for more complete examples.
- */
-int sd_notify(int unset_environment, const char *state);
-
-/* Similar to sd_send_state() but takes a format string.
- *
- * Example 1: A daemon could send the following after initialization:
- *
- * sd_notifyf(0, "READY=1\n"
- * "STATUS=Processing requests...\n"
- * "MAINPID=%lu",
- * (unsigned long) getpid());
- *
- * Example 2: A daemon could send the following shortly before
- * exiting, on failure:
- *
- * sd_notifyf(0, "STATUS=Failed to start up: %s\n"
- * "ERRNO=%i",
- * strerror(errno),
- * errno);
- */
-int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
+/*
+ Returns how many file descriptors have been passed, or a negative
+ errno code on failure. Optionally, removes the $LISTEN_FDS and
+ $LISTEN_PID file descriptors from the environment (recommended, but
+ problematic in threaded environments). If r is the return value of
+ this function you'll find the file descriptors passed as fds
+ SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
+ errno style error code on failure. This function call ensures that
+ the FD_CLOEXEC flag is set for the passed file descriptors, to make
+ sure they are not passed on to child processes. If FD_CLOEXEC shall
+ not be set, the caller needs to unset it after this call for all file
+ descriptors that are used.
+*/
+int sd_listen_fds(int unset_environment) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a FIFO in 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 FIFO. Returns a negative errno style error code on
+ failure.
+*/
+int sd_is_fifo(int fd, const char *path) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a socket of the specified family (AF_INET,
+ ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
+ family is 0 a socket family check will not be done. If type is 0 a
+ socket type check will not be done and the call only verifies if
+ the file descriptor refers to a socket. If listening is > 0 it is
+ verified that the socket is in listening mode. (i.e. listen() has
+ been called) If listening is == 0 it is verified that the socket is
+ not in listening mode. If listening is < 0 no listening mode check
+ is done. Returns a negative errno style error code on failure.
+*/
+int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is an Internet socket, of the specified family
+ (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
+ SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
+ check is not done. If type is 0 a socket type check will not be
+ done. If port is 0 a socket port check will not be done. The
+ listening flag is used the same way as in sd_is_socket(). Returns a
+ negative errno style error code on failure.
+*/
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_;
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is an AF_UNIX socket of the specified type
+ (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
+ a socket type check will not be done. If path is NULL a socket path
+ check will not be done. For normal AF_UNIX sockets set length to
+ 0. For abstract namespace sockets set length to the length of the
+ socket name (including the initial 0 byte), and pass the full
+ socket path in path (including the initial 0 byte). The listening
+ flag is used the same way as in sd_is_socket(). Returns a negative
+ errno style error code on failure.
+*/
+int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_;
+
+/*
+ Informs systemd about changed daemon state. This takes a numeber of
+ newline seperated environment-style variable assignments in a
+ string. The following strings 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
+ value daemons should send is "READY=1".
+
+ STATUS=... Passes a single-line status string back to systemd
+ that describes the daemon state. This is free-from
+ and can be used for various purposes: general state
+ feedback, fsck-like programs could pass completion
+ percentages and failing programs could pass a human
+ readable error message. Example: "STATUS=Completed
+ 66% of file system check..."
+
+ ERRNO=... If a daemon fails, the errno-style error code,
+ formatted as string. Example: "ERRNO=2" for ENOENT.
+
+ BUSERROR=... If a daemon fails, the D-Bus error-style error
+ code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
+
+ MAINPID=... The main pid of a daemon, in case systemd did not
+ fork off the process itself. Example: "MAINPID=4711"
+
+ Daemons can choose to send additional variables.
+
+ Returns a negative errno-style error code on failure. Returns > 0
+ if systemd could be notified, 0 if it couldn't possibly because
+ systemd is not running.
+
+ Example: When a daemon finished starting up, it could issue this
+ call to notify systemd about it:
+
+ sd_notify(0, "READY=1");
+
+ See sd_notifyf() for more complete examples.
+*/
+int sd_notify(int unset_environment, const char *state) _sd_hidden_;
+
+/*
+ Similar to sd_notify() but takes a format string.
+
+ Example 1: A daemon could send the following after initialization:
+
+ sd_notifyf(0, "READY=1\n"
+ "STATUS=Processing requests...\n"
+ "MAINPID=%lu",
+ (unsigned long) getpid());
+
+ Example 2: A daemon could send the following shortly before
+ exiting, on failure:
+
+ sd_notifyf(0, "STATUS=Failed to start up: %s\n"
+ "ERRNO=%i",
+ strerror(errno),
+ errno);
+*/
+int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3) _sd_hidden_;
+
+/*
+ Returns > 0 if the system was booted with systemd. Returns < 0 on
+ error. Returns 0 if the system was not booted with systemd. Note
+ that all of the functions above handle non-systemd boots just
+ 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.
+*/
+int sd_booted(void) _sd_hidden_;
#ifdef __cplusplus
}