chiark / gitweb /
Add support for building elogind against musl libc
authorSven Eden <yamakuzure@gmx.net>
Tue, 7 Mar 2017 09:29:34 +0000 (10:29 +0100)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 09:23:22 +0000 (10:23 +0100)
* Check whether printf.h is available and define/undef HAVE_PRINTF_H
  accordingly.
* Added src/shared/parse-printf-format.[hc] by Emil Renner Berthing
  <systemd@esmil.dk> that provides parse_printf_format() if printf.h
  is unavailable
* Added src/basic/musl_missing.h by Juergen Buchmueller
  <pullmoll@t-online.de> that implements glibc functions missing in
  musl libc as macros.
* Extended src/basic/musl_missing.h and added
  src/basic/musl_missing.c providing
  - program_invocation_name
  - program_invocation_short_name and
  - elogind_set_program_name() to set the two where appropriate.
* Added calls to elogind_set_program_name() to all main() functions
  where needed.
* A few other fixes to work nicely with musl libc.

19 files changed:
Makefile.am
configure.ac
src/basic/cgroup-util.c
src/basic/log.c
src/basic/missing.h
src/basic/musl_missing.c [new file with mode: 0644]
src/basic/musl_missing.h [new file with mode: 0644]
src/basic/parse-printf-format.c [new file with mode: 0644]
src/basic/parse-printf-format.h [new file with mode: 0644]
src/basic/selinux-util.h
src/basic/util.h
src/cgroups-agent/cgroups-agent.c
src/libelogind/sd-bus/bus-introspect.c
src/libelogind/sd-login/test-login.c
src/login/inhibit.c
src/login/loginctl.c
src/login/logind.c
src/login/test-login-shared.c
src/shared/pager.c

index d3d5ac71843b3c13411dd2c73cd0bd3ec4c1da6a..fbcc25d1d40e5b7dd2802aa023238b31047a0ff2 100644 (file)
@@ -294,6 +294,8 @@ noinst_LTLIBRARIES += \
 
 libbasic_la_SOURCES = \
        src/basic/missing.h \
 
 libbasic_la_SOURCES = \
        src/basic/missing.h \
+       src/basic/musl_missing.h \
+       src/basic/musl_missing.c \
        src/basic/capability.c \
        src/basic/capability.h \
        src/basic/conf-files.c \
        src/basic/capability.c \
        src/basic/capability.h \
        src/basic/conf-files.c \
@@ -364,7 +366,9 @@ libbasic_la_SOURCES = \
        src/basic/rm-rf.c \
        src/basic/rm-rf.h \
        src/basic/copy.c \
        src/basic/rm-rf.c \
        src/basic/rm-rf.h \
        src/basic/copy.c \
-       src/basic/copy.h
+       src/basic/copy.h \
+       src/basic/parse-printf-format.c \
+       src/basic/parse-printf-format.h
 
 nodist_libbasic_la_SOURCES = \
        src/basic/errno-from-name.h \
 
 nodist_libbasic_la_SOURCES = \
        src/basic/errno-from-name.h \
index 1d110c1b4adcb7a47ca48b6a4e4ff52ae354b26f..d410162462428cf398a9078c0f8c99819a266475 100644 (file)
@@ -114,9 +114,9 @@ fi
 # Find running cgroup controller
 with_cgroupctrl=
 AS_IF(  [test -f /proc/self/cgroup],
 # Find running cgroup controller
 with_cgroupctrl=
 AS_IF(  [test -f /proc/self/cgroup],
-        [with_cgroupctrl=`grep "^1:" /proc/self/cgroup | cut -d ':' -f 2`])
+        [with_cgroupctrl=`grep "^1:name=" /proc/self/cgroup | cut -d ':' -f 2`])
 AS_IF(  [test -z "$with_cgroupctrl"],
 AS_IF(  [test -z "$with_cgroupctrl"],
-        AC_MSG_ERROR([No running cgroup controller found]))
+        [with_cgroupctrl="name=elogind"])
 
 
 # ------------------------------------------------------------------------------
 
 
 # ------------------------------------------------------------------------------
@@ -298,6 +298,13 @@ AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers n
 AC_CHECK_HEADERS([linux/btrfs.h], [], [])
 AC_CHECK_HEADERS([linux/memfd.h], [], [])
 
 AC_CHECK_HEADERS([linux/btrfs.h], [], [])
 AC_CHECK_HEADERS([linux/memfd.h], [], [])
 
+AC_CHECK_HEADERS([printf.h], [have_printf_h=yes], [have_printf_h=no])
+AS_IF([test x$have_printf_h = xyes], [
+        AC_DEFINE(HAVE_PRINTF_H, 1, [Define if printf.h was found])
+])
+
+
+
 # unconditionally pull-in librt with old glibc versions
 dnl AC_SEARCH_LIBS([clock_gettime], [rt], [], [])
 dnl AC_SEARCH_LIBS([mq_unlink], [rt], [], [])
 # unconditionally pull-in librt with old glibc versions
 dnl AC_SEARCH_LIBS([clock_gettime], [rt], [], [])
 dnl AC_SEARCH_LIBS([mq_unlink], [rt], [], [])
index 5dc631eee410a97a8fa6e277f20a781a5dabd414..c83010d8ad8945d92b70d5b936eff3ef2b14e633 100644 (file)
@@ -461,7 +461,7 @@ static const char *controller_to_dirname(const char *controller) {
         if (e)
                 return e;
 
         if (e)
                 return e;
 
-                return controller;
+        return controller;
 }
 
 static int join_path_legacy(const char *controller, const char *path, const char *suffix, char **fs) {
 }
 
 static int join_path_legacy(const char *controller, const char *path, const char *suffix, char **fs) {
@@ -546,8 +546,9 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
                 r = join_path_unified(path, suffix, fs);
         else
                 r = join_path_legacy(controller, path, suffix, fs);
                 r = join_path_unified(path, suffix, fs);
         else
                 r = join_path_legacy(controller, path, suffix, fs);
-                if (r < 0)
-                        return r;
+
+        if (r < 0)
+                return r;
 
         path_kill_slashes(*fs);
         return 0;
 
         path_kill_slashes(*fs);
         return 0;
@@ -825,6 +826,8 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         }
 
         fs = procfs_file_alloca(pid, "cgroup");
         }
 
         fs = procfs_file_alloca(pid, "cgroup");
+        log_debug_elogind("Searching for PID %u in \"%s\" (controller \"%s\")",
+                          pid, fs, controller);
         f = fopen(fs, "re");
         if (!f)
                 return errno == ENOENT ? -ESRCH : -errno;
         f = fopen(fs, "re");
         if (!f)
                 return errno == ENOENT ? -ESRCH : -errno;
@@ -869,6 +872,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
                                 continue;
                 }
 
                                 continue;
                 }
 
+                log_debug_elogind("Found %s:%s", line, e+1);
                 p = strdup(e + 1);
                 if (!p)
                         return -ENOMEM;
                 p = strdup(e + 1);
                 if (!p)
                         return -ENOMEM;
@@ -1005,8 +1009,8 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
                  * via the "cgroup.populated" attribute. */
 
                 r = cg_get_path(controller, path, "cgroup.populated", &populated);
                  * via the "cgroup.populated" attribute. */
 
                 r = cg_get_path(controller, path, "cgroup.populated", &populated);
-        if (r < 0)
-                return r;
+                if (r < 0)
+                        return r;
 
                 r = read_one_line_file(populated, &t);
                 if (r == -ENOENT)
 
                 r = read_one_line_file(populated, &t);
                 if (r == -ENOENT)
@@ -1016,33 +1020,33 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
 
                 return streq(t, "0");
         } else {
 
                 return streq(t, "0");
         } else {
-        _cleanup_closedir_ DIR *d = NULL;
-        char *fn;
+                _cleanup_closedir_ DIR *d = NULL;
+                char *fn;
 
                 r = cg_is_empty(controller, path);
 
                 r = cg_is_empty(controller, path);
-        if (r <= 0)
-                return r;
+                if (r <= 0)
+                        return r;
 
 
-        r = cg_enumerate_subgroups(controller, path, &d);
-                if (r == -ENOENT)
-                        return 1;
-        if (r < 0)
+                r = cg_enumerate_subgroups(controller, path, &d);
+                        if (r == -ENOENT)
+                                return 1;
+                if (r < 0)
                         return r;
 
                         return r;
 
-        while ((r = cg_read_subgroup(d, &fn)) > 0) {
-                _cleanup_free_ char *p = NULL;
+                while ((r = cg_read_subgroup(d, &fn)) > 0) {
+                        _cleanup_free_ char *p = NULL;
 
 
-                p = strjoin(path, "/", fn, NULL);
-                free(fn);
-                if (!p)
-                        return -ENOMEM;
+                        p = strjoin(path, "/", fn, NULL);
+                        free(fn);
+                        if (!p)
+                                return -ENOMEM;
 
                         r = cg_is_empty_recursive(controller, p);
 
                         r = cg_is_empty_recursive(controller, p);
-                if (r <= 0)
+                        if (r <= 0)
+                                return r;
+                }
+                if (r < 0)
                         return r;
                         return r;
-        }
-        if (r < 0)
-                return r;
 
                 return true;
         }
 
                 return true;
         }
@@ -1725,7 +1729,7 @@ char *cg_escape(const char *p) {
                                 if (memcmp(p, n, l) != 0)
                                         continue;
 
                                 if (memcmp(p, n, l) != 0)
                                         continue;
 
-                                        need_prefix = true;
+                                need_prefix = true;
                                 break;
                         }
                 }
                                 break;
                         }
                 }
@@ -1734,7 +1738,7 @@ char *cg_escape(const char *p) {
         if (need_prefix)
                 return strappend("_", p);
 
         if (need_prefix)
                 return strappend("_", p);
 
-                return strdup(p);
+        return strdup(p);
 }
 
 char *cg_unescape(const char *p) {
 }
 
 char *cg_unescape(const char *p) {
index 5a702112f7c3af57a3b450e5dab12d5b90731e98..921c952f833dff4c76e7f8ff0cea554021171065 100644 (file)
@@ -27,8 +27,8 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <stddef.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <stddef.h>
-#include <printf.h>
 
 
+#include "parse-printf-format.h"
 #include "sd-messages.h"
 #include "log.h"
 #include "util.h"
 #include "sd-messages.h"
 #include "log.h"
 #include "util.h"
index 37c3f6774549f63fc6c50a7b8d6cdb2fc8aa7c67..cfe6459c16eb7e6dabbee118cf48eeb5a153f841 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/capability.h>
 #include <linux/neighbour.h>
 
 #include <linux/capability.h>
 #include <linux/neighbour.h>
 
+#include "musl_missing.h"
+
 #ifdef ARCH_MIPS
 #include <asm/sgidefs.h>
 #endif
 #ifdef ARCH_MIPS
 #include <asm/sgidefs.h>
 #endif
diff --git a/src/basic/musl_missing.c b/src/basic/musl_missing.c
new file mode 100644 (file)
index 0000000..bdec822
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __GLIBC__
+#include <string.h>
+#include "util.h"
+
+char *program_invocation_name       = NULL;
+char *program_invocation_short_name = NULL;
+#endif // __GLIBC__
+
+#include "musl_missing.h"
+
+static void elogind_free_program_name(void) {
+#ifndef __GLIBC__
+        if (program_invocation_name)
+                program_invocation_name       = mfree(program_invocation_name);
+        if (program_invocation_short_name)
+                program_invocation_short_name = mfree(program_invocation_short_name);
+#endif // __GLIBC__
+}
+
+void elogind_set_program_name(const char* pcall) {
+        assert(pcall && pcall[0]);
+        elogind_free_program_name();
+#ifndef __GLIBC__
+        program_invocation_name       = strdup(pcall);
+        program_invocation_short_name = strdup(basename(pcall));
+        atexit(elogind_free_program_name);
+#endif // __GLIBC__
+}
+
diff --git a/src/basic/musl_missing.h b/src/basic/musl_missing.h
new file mode 100644 (file)
index 0000000..f54319d
--- /dev/null
@@ -0,0 +1,94 @@
+#pragma once
+#ifndef ELOGIND_BASIC_MUSL_MISSING_H_INCLUDED
+#define ELOGIND_BASIC_MUSL_MISSING_H_INCLUDED
+
+
+/****************************************************************
+ * musl_missing.h - work around glibc extensions for musl libc.
+ *
+ * Implements glibc functions missing in musl libc as macros.
+ * Is to be included where these functions are used.
+ * Also defines some glibc only constants as either 0 or
+ * as found in the corresponding glibc header file.
+ *
+ * Juergen Buchmueller <pullmoll@t-online.de> for Void Linux
+ * Public Domain; no warranties whatsoever. Thank you Mr. P.
+ *
+ ****************************************************************/
+
+
+void elogind_set_program_name(const char* pcall);
+
+#if !defined(__GLIBC__)
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define strerror_r(e, m, k) (strerror_r(e, m, k) < 0 ? strdup("strerror_r() failed") : m);
+
+#ifndef _ERRNO_H
+extern char *program_invocation_name;
+extern char *program_invocation_short_name;
+#endif // errno.h included beforehand
+
+/*
+ * Possibly TODO according to http://man7.org/linux/man-pages/man3/getenv.3.html
+ * + test if the process's effective user ID does not match its real user ID or
+ *   the process's effective group ID does not match its real group ID;
+ *   typically this is the result of executing a set-user-ID or set-
+ *   group-ID program. Is calling issetugid() sufficient here?
+ * + test if the effective capability bit was set on the executable file
+ * + test if the process has a nonempty permitted capability set
+ */
+#if !defined(HAVE_SECURE_GETENV) && !defined(HAVE___SECURE_GETENV)
+#  define secure_getenv(name) \
+        (issetugid() ? NULL : getenv(name))
+#  define HAVE_SECURE_GETENV 1
+#endif // HAVE_[__]SECURE_GETENV
+
+/* Poor man's basename */
+#define basename(path) \
+        (strrchr(path, '/') ? strrchr(path, '/')+1 : path)
+
+/* strndupa may already be defined in another compatibility header */
+#if !defined(strndupa)
+#define strndupa(src, n) \
+        (__extension__ ({const char *in = (src);   \
+                size_t len = strnlen(in, (n)) + 1; \
+                char *out = (char *) alloca(len);  \
+                out[len-1] = '\0';                 \
+                (char *) memcpy(out, in, len-1);}) \
+        )
+#endif
+
+/* See http://man7.org/linux/man-pages/man3/canonicalize_file_name.3.html */
+#define canonicalize_file_name(path) \
+        realpath(path, NULL)
+
+typedef int (*__compar_fn_t)(const void *, const void *);
+
+/* GLOB_BRACE is another glibc extension - ignore it for musl libc */
+#define GLOB_BRACE 0
+
+/* getnameinfo(3) glibc extensions are undefined in musl libc */
+#define NI_IDN 0
+#define NI_IDN_USE_STD3_ASCII_RULES 0
+
+/* Taken from glibc's net/if_arp.h */
+#if !defined(ARPHRD_IEEE802154_PHY)
+#define ARPHRD_IEEE802154_PHY 805        /* IEEE 802.15.4 PHY header.  */
+#endif
+
+/* Shorthand for type of comparison functions. */
+#ifndef __COMPAR_FN_T
+# define __COMPAR_FN_T
+typedef int (*__compar_fn_t) (const void *, const void *);
+typedef __compar_fn_t comparison_fn_t;
+#endif
+
+
+#endif // !defined(__GLIBC__)
+
+#endif // ELOGIND_BASIC_MUSL_MISSING_H_INCLUDED
+
diff --git a/src/basic/parse-printf-format.c b/src/basic/parse-printf-format.c
new file mode 100644 (file)
index 0000000..fb1699a
--- /dev/null
@@ -0,0 +1,277 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
+
+  With parts from the musl C library
+  Copyright 2005-2014 Rich Felker, et al.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+#include <string.h>
+
+#include "parse-printf-format.h"
+
+#ifndef HAVE_PRINTF_H
+
+static const char *consume_nonarg(const char *fmt)
+{
+        do {
+                if (*fmt == '\0')
+                        return fmt;
+        } while (*fmt++ != '%');
+        return fmt;
+}
+
+static const char *consume_num(const char *fmt)
+{
+        for (;*fmt >= '0' && *fmt <= '9'; fmt++)
+                /* do nothing */;
+        return fmt;
+}
+
+static const char *consume_argn(const char *fmt, size_t *arg)
+{
+        const char *p = fmt;
+        size_t val = 0;
+
+        if (*p < '1' || *p > '9')
+                return fmt;
+        do {
+                val = 10*val + (*p++ - '0');
+        } while (*p >= '0' && *p <= '9');
+
+        if (*p != '$')
+                return fmt;
+        *arg = val;
+        return p+1;
+}
+
+static const char *consume_flags(const char *fmt)
+{
+        while (1) {
+                switch (*fmt) {
+                case '#':
+                case '0':
+                case '-':
+                case ' ':
+                case '+':
+                case '\'':
+                case 'I':
+                        fmt++;
+                        continue;
+                }
+                return fmt;
+        }
+}
+
+enum state {
+        BARE,
+        LPRE,
+        LLPRE,
+        HPRE,
+        HHPRE,
+        BIGLPRE,
+        ZTPRE,
+        JPRE,
+        STOP
+};
+
+enum type {
+        NONE,
+        PTR,
+        INT,
+        UINT,
+        ULLONG,
+        LONG,
+        ULONG,
+        SHORT,
+        USHORT,
+        CHAR,
+        UCHAR,
+        LLONG,
+        SIZET,
+        IMAX,
+        UMAX,
+        PDIFF,
+        UIPTR,
+        DBL,
+        LDBL,
+        MAXTYPE
+};
+
+static const short pa_types[MAXTYPE] = {
+        [NONE]   = PA_INT,
+        [PTR]    = PA_POINTER,
+        [INT]    = PA_INT,
+        [UINT]   = PA_INT,
+        [ULLONG] = PA_INT | PA_FLAG_LONG_LONG,
+        [LONG]   = PA_INT | PA_FLAG_LONG,
+        [ULONG]  = PA_INT | PA_FLAG_LONG,
+        [SHORT]  = PA_INT | PA_FLAG_SHORT,
+        [USHORT] = PA_INT | PA_FLAG_SHORT,
+        [CHAR]   = PA_CHAR,
+        [UCHAR]  = PA_CHAR,
+        [LLONG]  = PA_INT | PA_FLAG_LONG_LONG,
+        [SIZET]  = PA_INT | PA_FLAG_LONG,
+        [IMAX]   = PA_INT | PA_FLAG_LONG_LONG,
+        [UMAX]   = PA_INT | PA_FLAG_LONG_LONG,
+        [PDIFF]  = PA_INT | PA_FLAG_LONG_LONG,
+        [UIPTR]  = PA_INT | PA_FLAG_LONG,
+        [DBL]    = PA_DOUBLE,
+        [LDBL]   = PA_DOUBLE | PA_FLAG_LONG_DOUBLE
+};
+
+#define S(x) [(x)-'A']
+#define E(x) (STOP + (x))
+
+static const unsigned char states[]['z'-'A'+1] = {
+        { /* 0: bare types */
+                S('d') = E(INT), S('i') = E(INT),
+                S('o') = E(UINT),S('u') = E(UINT),S('x') = E(UINT), S('X') = E(UINT),
+                S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL),  S('a') = E(DBL),
+                S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL),  S('A') = E(DBL),
+                S('c') = E(CHAR),S('C') = E(INT),
+                S('s') = E(PTR), S('S') = E(PTR), S('p') = E(UIPTR),S('n') = E(PTR),
+                S('m') = E(NONE),
+                S('l') = LPRE,   S('h') = HPRE, S('L') = BIGLPRE,
+                S('z') = ZTPRE,  S('j') = JPRE, S('t') = ZTPRE
+        }, { /* 1: l-prefixed */
+                S('d') = E(LONG), S('i') = E(LONG),
+                S('o') = E(ULONG),S('u') = E(ULONG),S('x') = E(ULONG),S('X') = E(ULONG),
+                S('e') = E(DBL),  S('f') = E(DBL),  S('g') = E(DBL),  S('a') = E(DBL),
+                S('E') = E(DBL),  S('F') = E(DBL),  S('G') = E(DBL),  S('A') = E(DBL),
+                S('c') = E(INT),  S('s') = E(PTR),  S('n') = E(PTR),
+                S('l') = LLPRE
+        }, { /* 2: ll-prefixed */
+                S('d') = E(LLONG), S('i') = E(LLONG),
+                S('o') = E(ULLONG),S('u') = E(ULLONG),
+                S('x') = E(ULLONG),S('X') = E(ULLONG),
+                S('n') = E(PTR)
+        }, { /* 3: h-prefixed */
+                S('d') = E(SHORT), S('i') = E(SHORT),
+                S('o') = E(USHORT),S('u') = E(USHORT),
+                S('x') = E(USHORT),S('X') = E(USHORT),
+                S('n') = E(PTR),
+                S('h') = HHPRE
+        }, { /* 4: hh-prefixed */
+                S('d') = E(CHAR), S('i') = E(CHAR),
+                S('o') = E(UCHAR),S('u') = E(UCHAR),
+                S('x') = E(UCHAR),S('X') = E(UCHAR),
+                S('n') = E(PTR)
+        }, { /* 5: L-prefixed */
+                S('e') = E(LDBL),S('f') = E(LDBL),S('g') = E(LDBL), S('a') = E(LDBL),
+                S('E') = E(LDBL),S('F') = E(LDBL),S('G') = E(LDBL), S('A') = E(LDBL),
+                S('n') = E(PTR)
+        }, { /* 6: z- or t-prefixed (assumed to be same size) */
+                S('d') = E(PDIFF),S('i') = E(PDIFF),
+                S('o') = E(SIZET),S('u') = E(SIZET),
+                S('x') = E(SIZET),S('X') = E(SIZET),
+                S('n') = E(PTR)
+        }, { /* 7: j-prefixed */
+                S('d') = E(IMAX), S('i') = E(IMAX),
+                S('o') = E(UMAX), S('u') = E(UMAX),
+                S('x') = E(UMAX), S('X') = E(UMAX),
+                S('n') = E(PTR)
+        }
+};
+
+size_t parse_printf_format(const char *fmt, size_t n, int *types)
+{
+        size_t i = 0;
+        size_t last = 0;
+
+        memset(types, 0, n);
+
+        while (1) {
+                size_t arg;
+                unsigned int state;
+
+                fmt = consume_nonarg(fmt);
+                if (*fmt == '\0')
+                        break;
+                if (*fmt == '%') {
+                        fmt++;
+                        continue;
+                }
+                arg = 0;
+                fmt = consume_argn(fmt, &arg);
+                /* flags */
+                fmt = consume_flags(fmt);
+                /* width */
+                if (*fmt == '*') {
+                        size_t warg = 0;
+                        fmt = consume_argn(fmt+1, &warg);
+                        if (warg == 0)
+                                warg = ++i;
+                        if (warg > last)
+                                last = warg;
+                        if (warg <= n && types[warg-1] == NONE)
+                                types[warg-1] = INT;
+                } else
+                        fmt = consume_num(fmt);
+                /* precision */
+                if (*fmt == '.') {
+                        fmt++;
+                        if (*fmt == '*') {
+                                size_t parg = 0;
+                                fmt = consume_argn(fmt+1, &parg);
+                                if (parg == 0)
+                                        parg = ++i;
+                                if (parg > last)
+                                        last = parg;
+                                if (parg <= n && types[parg-1] == NONE)
+                                        types[parg-1] = INT;
+                        } else {
+                                if (*fmt == '-')
+                                        fmt++;
+                                fmt = consume_num(fmt);
+                        }
+                }
+                /* length modifier and conversion specifier */
+                state = BARE;
+                do {
+                        unsigned char c = *fmt++;
+
+                        if (c < 'A' || c > 'z')
+                                continue;
+                        state = states[state]S(c);
+                        if (state == 0)
+                                continue;
+                } while (state < STOP);
+
+                if (state == E(NONE))
+                        continue;
+
+                if (arg == 0)
+                        arg = ++i;
+                if (arg > last)
+                        last = arg;
+                if (arg <= n)
+                        types[arg-1] = state - STOP;
+        }
+
+        if (last > n)
+                last = n;
+        for (i = 0; i < last; i++)
+                types[i] = pa_types[types[i]];
+
+        return last;
+}
+
+#endif // HAVE_PRINTF_H
diff --git a/src/basic/parse-printf-format.h b/src/basic/parse-printf-format.h
new file mode 100644 (file)
index 0000000..b021355
--- /dev/null
@@ -0,0 +1,58 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
+
+  With parts from the GNU C Library
+  Copyright 1991-2014 Free Software Foundation, Inc.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include "config.h"
+
+#ifdef HAVE_PRINTF_H
+#include <printf.h>
+#else
+
+#include <stddef.h>
+
+enum {        /* C type: */
+  PA_INT,     /* int */
+  PA_CHAR,    /* int, cast to char */
+  PA_WCHAR,   /* wide char */
+  PA_STRING,  /* const char *, a '\0'-terminated string */
+  PA_WSTRING, /* const wchar_t *, wide character string */
+  PA_POINTER, /* void * */
+  PA_FLOAT,   /* float */
+  PA_DOUBLE,  /* double */
+  PA_LAST
+};
+
+/* Flag bits that can be set in a type returned by `parse_printf_format'.  */
+#define PA_FLAG_MASK        0xff00
+#define PA_FLAG_LONG_LONG   (1 << 8)
+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
+#define PA_FLAG_LONG        (1 << 9)
+#define PA_FLAG_SHORT       (1 << 10)
+#define PA_FLAG_PTR         (1 << 11)
+
+size_t parse_printf_format(const char *fmt, size_t n, int *types);
+
+#endif /* HAVE_PRINTF_H */
+
index e60dac8de82959ce817b198e16a56e4ff702cc11..559b0d6dfe598188d098ae3e638abcb270693c99 100644 (file)
@@ -21,6 +21,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <stdbool.h>
 
 #include <sys/socket.h>
 #include <stdbool.h>
 
index 3b956b8569cf124f93076f2bd091b808da2475c5..254e94ce8054ac0f4dc1f75806701ac1c4bfacdc 100644 (file)
@@ -890,7 +890,11 @@ union inotify_event_buffer {
         uint8_t raw[INOTIFY_EVENT_MAX];
 };
 
         uint8_t raw[INOTIFY_EVENT_MAX];
 };
 
-#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
+#ifdef __GLIBC__
+ #define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
+#else
+ #define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), 0)
+#endif
 
 // UNNEEDED int ptsname_malloc(int fd, char **ret);
 
 
 // UNNEEDED int ptsname_malloc(int fd, char **ret);
 
index e72c5c1e044501e60bb3bda93e3cf9c64cb54808..c0ce357f3db16be4a4d0a39bc3ca78566a4f87c6 100644 (file)
@@ -34,6 +34,7 @@ int main(int argc, char *argv[]) {
                 return EXIT_FAILURE;
         }
 
                 return EXIT_FAILURE;
         }
 
+        elogind_set_program_name(argv[0]);
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
index fe7fcb5c51cebc17f573fbbeef17a26bc64bfe73..14f40385b4282be05d6c151662c645c0034c9b1b 100644 (file)
@@ -207,6 +207,6 @@ void introspect_free(struct introspect *i) {
         if (i->f)
                 fclose(i->f);
 
         if (i->f)
                 fclose(i->f);
 
-                free(i->introspection);
+        free(i->introspection);
         zero(*i);
 }
         zero(*i);
 }
index f734ce9eee5d9524e72daf6effd4e75a37fd5c01..b60ad0c38603faf0ec12a59979ed46b332f8aa5d 100644 (file)
@@ -254,6 +254,7 @@ static void test_login(void) {
 }
 
 int main(int argc, char* argv[]) {
 }
 
 int main(int argc, char* argv[]) {
+        elogind_set_program_name(argv[0]);
         log_parse_environment();
         log_open();
 
         log_parse_environment();
         log_open();
 
index c53ea8add7c6c1efe2da0812d1117362ce6d1a28..89e529d01ba9a9253f04b337cb7bd552b06b6a13 100644 (file)
@@ -226,6 +226,7 @@ int main(int argc, char *argv[]) {
         _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
         int r;
 
         _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
         int r;
 
+        elogind_set_program_name(argv[0]);
         log_parse_environment();
         log_open();
 
         log_parse_environment();
         log_open();
 
index 080d64a0cdca6ba2728378b8c91fb58e1af425bb..d7b64f9e9e81654fb4d82b39add8fa830731f2a9 100644 (file)
@@ -1692,6 +1692,7 @@ int main(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
         int r;
 
         setlocale(LC_ALL, "");
+        elogind_set_program_name(argv[0]);
         log_parse_environment();
         log_open();
 
         log_parse_environment();
         log_open();
 
index 8748490f45f65eea1f864a1a4b36043c07e0034e..72889535e330b0176dc7115d4635d981491e2c4c 100644 (file)
@@ -1230,6 +1230,7 @@ int main(int argc, char *argv[]) {
         Manager *m = NULL;
         int r;
 
         Manager *m = NULL;
         int r;
 
+        elogind_set_program_name(argv[0]);
         log_set_target(LOG_TARGET_AUTO);
         log_set_facility(LOG_AUTH);
         log_parse_environment();
         log_set_target(LOG_TARGET_AUTO);
         log_set_facility(LOG_AUTH);
         log_parse_environment();
index 4c4275d1245eaf8c00cb75f257e332c3bf002d5f..e9322b627acebc8b8bc8a57771da341644d014cd 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "macro.h"
 #include "login-util.h"
 
 #include "macro.h"
 #include "login-util.h"
+#include "musl_missing.h"
 
 static void test_session_id_valid(void) {
         assert_se(session_id_valid("c1"));
 
 static void test_session_id_valid(void) {
         assert_se(session_id_valid("c1"));
@@ -32,6 +33,7 @@ static void test_session_id_valid(void) {
 }
 
 int main(int argc, char* argv[]) {
 }
 
 int main(int argc, char* argv[]) {
+        elogind_set_program_name(argv[0]);
         log_parse_environment();
         log_open();
 
         log_parse_environment();
         log_open();
 
index 7818d0273c8ce0aab75ee63a31b7fc95ce43538f..f1f3dc7e7edb41a3c5d9320ffa02b7557efe5217 100644 (file)
@@ -153,10 +153,14 @@ void pager_close(void) {
 
         /* Inform pager that we are done */
         fclose(stdout);
 
         /* Inform pager that we are done */
         fclose(stdout);
+#if defined(__GLIBC__)
         stdout = NULL;
         stdout = NULL;
+#endif // in musl-libc this is a const
 
         fclose(stderr);
 
         fclose(stderr);
+#if defined(__GLIBC__)
         stderr = NULL;
         stderr = NULL;
+#endif // in musl-libc this is a const
 
         kill(pager_pid, SIGCONT);
         (void) wait_for_terminate(pager_pid, NULL);
 
         kill(pager_pid, SIGCONT);
         (void) wait_for_terminate(pager_pid, NULL);