[systemd-commits] 5 commits - .gitignore Makefile.am src/analyze src/bus-proxyd src/cgtop src/core src/delta src/firstboot src/fsck src/getty-generator src/import src/initctl src/journal src/journal-remote src/libsystemd src/libsystemd-network src/libsystemd-terminal src/libudev src/login src/machine src/network src/notify src/nspawn src/quotacheck src/resolve src/run src/shared src/shutdownd src/systemctl src/sysusers src/test src/timedate src/tmpfiles src/tty-ask-password-agent src/udev src/update-utmp src/vconsole
Ronny Chevalier
rchevalier at kemper.freedesktop.org
Fri Apr 10 15:43:10 PDT 2015
.gitignore | 2
Makefile.am | 20
src/analyze/analyze.c | 1
src/bus-proxyd/bus-proxyd.c | 1
src/bus-proxyd/bus-xml-policy.c | 1
src/bus-proxyd/proxy.c | 1
src/bus-proxyd/stdio-bridge.c | 1
src/cgtop/cgtop.c | 1
src/core/automount.c | 2
src/core/busname.c | 1
src/core/cgroup.c | 1
src/core/dbus-manager.c | 1
src/core/execute.c | 3
src/core/failure-action.c | 1
src/core/job.c | 1
src/core/killall.c | 3
src/core/machine-id-setup.c | 1
src/core/main.c | 3
src/core/manager.c | 2
src/core/mount.c | 1
src/core/service.c | 2
src/core/shutdown.c | 2
src/core/socket.c | 1
src/core/swap.c | 1
src/core/transaction.c | 1
src/core/unit-printf.c | 1
src/core/unit.c | 2
src/delta/delta.c | 2
src/firstboot/firstboot.c | 2
src/fsck/fsck.c | 1
src/getty-generator/getty-generator.c | 2
src/import/export-tar.c | 1
src/import/import-tar.c | 1
src/import/importd.c | 1
src/import/pull-common.c | 1
src/import/pull-dkr.c | 1
src/import/pull-tar.c | 1
src/initctl/initctl.c | 1
src/journal-remote/journal-upload.c | 1
src/journal/coredump.c | 1
src/journal/coredumpctl.c | 2
src/journal/journal-file.c | 1
src/journal/journal-verify.c | 1
src/journal/journalctl.c | 1
src/journal/journald-console.c | 3
src/journal/journald-kmsg.c | 2
src/journal/journald-rate-limit.c | 1
src/journal/journald-server.c | 2
src/journal/journald-syslog.c | 2
src/journal/journald-wall.c | 2
src/journal/journald.c | 1
src/journal/sd-journal.c | 1
src/journal/stacktrace.c | 1
src/journal/test-compress.c | 1
src/journal/test-journal-verify.c | 1
src/libsystemd-network/sd-dhcp-client.c | 1
src/libsystemd-network/sd-dhcp6-client.c | 1
src/libsystemd-network/sd-ipv4ll.c | 1
src/libsystemd-network/sd-pppoe.c | 1
src/libsystemd-network/test-pppoe.c | 1
src/libsystemd-terminal/modeset.c | 2
src/libsystemd/sd-bus/bus-container.c | 1
src/libsystemd/sd-bus/bus-creds.c | 2
src/libsystemd/sd-bus/bus-dump.c | 2
src/libsystemd/sd-bus/bus-kernel.c | 1
src/libsystemd/sd-bus/bus-socket.c | 1
src/libsystemd/sd-bus/busctl.c | 1
src/libsystemd/sd-bus/test-bus-chat.c | 1
src/libsystemd/sd-id128/sd-id128.c | 1
src/libsystemd/sd-login/sd-login.c | 1
src/libsystemd/sd-login/test-login.c | 1
src/libsystemd/sd-rtnl/rtnl-message.c | 1
src/libudev/libudev-monitor.c | 1
src/login/inhibit.c | 2
src/login/loginctl.c | 2
src/login/logind-acl.c | 1
src/login/logind-action.c | 3
src/login/logind-core.c | 1
src/login/logind-dbus.c | 3
src/login/logind-inhibit.c | 1
src/login/logind-seat.c | 2
src/login/logind-session.c | 2
src/login/logind-user-dbus.c | 1
src/login/logind-user.c | 1
src/login/logind.c | 1
src/login/pam_systemd.c | 2
src/login/sysfs-show.c | 1
src/machine/machine-dbus.c | 2
src/machine/machine.c | 1
src/machine/machinectl.c | 2
src/machine/machined-dbus.c | 1
src/machine/machined.c | 1
src/network/networkctl.c | 1
src/notify/notify.c | 1
src/nspawn/nspawn.c | 4
src/quotacheck/quotacheck.c | 1
src/resolve/resolved-dns-scope.c | 1
src/resolve/resolved-dns-transaction.c | 1
src/resolve/resolved-manager.c | 1
src/run/run.c | 1
src/shared/ask-password-api.c | 3
src/shared/audit.c | 1
src/shared/cgroup-show.c | 3
src/shared/cgroup-util.c | 2
src/shared/clean-ipc.c | 1
src/shared/env-util.c | 144 +
src/shared/env-util.h | 3
src/shared/formats-util.h | 63
src/shared/hashmap.c | 1
src/shared/install-printf.c | 1
src/shared/log.c | 3
src/shared/logs-show.c | 3
src/shared/machine-pool.c | 1
src/shared/pager.c | 2
src/shared/process-util.c | 538 +++++
src/shared/process-util.h | 65
src/shared/random-util.c | 127 +
src/shared/random-util.h | 38
src/shared/smack-util.c | 1
src/shared/socket-util.c | 1
src/shared/spawn-ask-password-agent.c | 1
src/shared/spawn-polkit-agent.c | 1
src/shared/terminal-util.c | 1072 +++++++++++
src/shared/terminal-util.h | 109 +
src/shared/util.c | 1942 --------------------
src/shared/util.h | 183 -
src/shared/utmp-wtmp.c | 1
src/shared/virt.c | 1
src/shutdownd/shutdownd.c | 1
src/systemctl/systemctl.c | 3
src/sysusers/sysusers.c | 1
src/test/test-cgroup-util.c | 2
src/test/test-ellipsize.c | 1
src/test/test-fileio.c | 1
src/test/test-log.c | 1
src/test/test-namespace.c | 1
src/test/test-process-util.c | 139 +
src/test/test-strip-tab-ansi.c | 1
src/test/test-terminal-util.c | 84
src/test/test-tmpfiles.c | 1
src/test/test-util.c | 150 -
src/timedate/timedatectl.c | 1
src/tmpfiles/tmpfiles.c | 1
src/tty-ask-password-agent/tty-ask-password-agent.c | 2
src/udev/cdrom_id/cdrom_id.c | 1
src/udev/net/link-config.c | 1
src/udev/scsi_id/scsi_serial.c | 1
src/udev/udev-ctrl.c | 1
src/udev/udev-event.c | 1
src/udev/udev-node.c | 1
src/udev/udevadm-monitor.c | 1
src/udev/udevd.c | 1
src/update-utmp/update-utmp.c | 1
src/vconsole/vconsole-setup.c | 2
154 files changed, 2681 insertions(+), 2189 deletions(-)
New commits:
commit 3c8000956a66203de381135d417db8ddc2e127e2
Author: Ronny Chevalier <chevalier.ronny at gmail.com>
Date: Sat Apr 11 00:25:43 2015 +0200
shared: move replace_env* from util to env-util
diff --git a/src/shared/env-util.c b/src/shared/env-util.c
index 00c2cdd..ac7bbdc 100644
--- a/src/shared/env-util.c
+++ b/src/shared/env-util.c
@@ -448,3 +448,147 @@ char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const cha
return e;
}
+
+char *replace_env(const char *format, char **env) {
+ enum {
+ WORD,
+ CURLY,
+ VARIABLE
+ } state = WORD;
+
+ const char *e, *word = format;
+ char *r = NULL, *k;
+
+ assert(format);
+
+ for (e = format; *e; e ++) {
+
+ switch (state) {
+
+ case WORD:
+ if (*e == '$')
+ state = CURLY;
+ break;
+
+ case CURLY:
+ if (*e == '{') {
+ k = strnappend(r, word, e-word-1);
+ if (!k)
+ goto fail;
+
+ free(r);
+ r = k;
+
+ word = e-1;
+ state = VARIABLE;
+
+ } else if (*e == '$') {
+ k = strnappend(r, word, e-word);
+ if (!k)
+ goto fail;
+
+ free(r);
+ r = k;
+
+ word = e+1;
+ state = WORD;
+ } else
+ state = WORD;
+ break;
+
+ case VARIABLE:
+ if (*e == '}') {
+ const char *t;
+
+ t = strempty(strv_env_get_n(env, word+2, e-word-2));
+
+ k = strappend(r, t);
+ if (!k)
+ goto fail;
+
+ free(r);
+ r = k;
+
+ word = e+1;
+ state = WORD;
+ }
+ break;
+ }
+ }
+
+ k = strnappend(r, word, e-word);
+ if (!k)
+ goto fail;
+
+ free(r);
+ return k;
+
+fail:
+ free(r);
+ return NULL;
+}
+
+char **replace_env_argv(char **argv, char **env) {
+ char **ret, **i;
+ unsigned k = 0, l = 0;
+
+ l = strv_length(argv);
+
+ ret = new(char*, l+1);
+ if (!ret)
+ return NULL;
+
+ STRV_FOREACH(i, argv) {
+
+ /* If $FOO appears as single word, replace it by the split up variable */
+ if ((*i)[0] == '$' && (*i)[1] != '{') {
+ char *e;
+ char **w, **m = NULL;
+ unsigned q;
+
+ e = strv_env_get(env, *i+1);
+ if (e) {
+ int r;
+
+ r = strv_split_quoted(&m, e, UNQUOTE_RELAX);
+ if (r < 0) {
+ ret[k] = NULL;
+ strv_free(ret);
+ return NULL;
+ }
+ } else
+ m = NULL;
+
+ q = strv_length(m);
+ l = l + q - 1;
+
+ w = realloc(ret, sizeof(char*) * (l+1));
+ if (!w) {
+ ret[k] = NULL;
+ strv_free(ret);
+ strv_free(m);
+ return NULL;
+ }
+
+ ret = w;
+ if (m) {
+ memcpy(ret + k, m, q * sizeof(char*));
+ free(m);
+ }
+
+ k += q;
+ continue;
+ }
+
+ /* If ${FOO} appears as part of a word, replace it by the variable as-is */
+ ret[k] = replace_env(*i, env);
+ if (!ret[k]) {
+ strv_free(ret);
+ return NULL;
+ }
+ k++;
+ }
+
+ ret[k] = NULL;
+ return ret;
+}
diff --git a/src/shared/env-util.h b/src/shared/env-util.h
index 9de3621..803aa61 100644
--- a/src/shared/env-util.h
+++ b/src/shared/env-util.h
@@ -29,6 +29,9 @@ bool env_name_is_valid(const char *e);
bool env_value_is_valid(const char *e);
bool env_assignment_is_valid(const char *e);
+char *replace_env(const char *format, char **env);
+char **replace_env_argv(char **argv, char **env);
+
bool strv_env_is_valid(char **e);
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
diff --git a/src/shared/util.c b/src/shared/util.c
index 508b5d1..53f8488 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2083,150 +2083,6 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
}
}
-char *replace_env(const char *format, char **env) {
- enum {
- WORD,
- CURLY,
- VARIABLE
- } state = WORD;
-
- const char *e, *word = format;
- char *r = NULL, *k;
-
- assert(format);
-
- for (e = format; *e; e ++) {
-
- switch (state) {
-
- case WORD:
- if (*e == '$')
- state = CURLY;
- break;
-
- case CURLY:
- if (*e == '{') {
- k = strnappend(r, word, e-word-1);
- if (!k)
- goto fail;
-
- free(r);
- r = k;
-
- word = e-1;
- state = VARIABLE;
-
- } else if (*e == '$') {
- k = strnappend(r, word, e-word);
- if (!k)
- goto fail;
-
- free(r);
- r = k;
-
- word = e+1;
- state = WORD;
- } else
- state = WORD;
- break;
-
- case VARIABLE:
- if (*e == '}') {
- const char *t;
-
- t = strempty(strv_env_get_n(env, word+2, e-word-2));
-
- k = strappend(r, t);
- if (!k)
- goto fail;
-
- free(r);
- r = k;
-
- word = e+1;
- state = WORD;
- }
- break;
- }
- }
-
- k = strnappend(r, word, e-word);
- if (!k)
- goto fail;
-
- free(r);
- return k;
-
-fail:
- free(r);
- return NULL;
-}
-
-char **replace_env_argv(char **argv, char **env) {
- char **ret, **i;
- unsigned k = 0, l = 0;
-
- l = strv_length(argv);
-
- ret = new(char*, l+1);
- if (!ret)
- return NULL;
-
- STRV_FOREACH(i, argv) {
-
- /* If $FOO appears as single word, replace it by the split up variable */
- if ((*i)[0] == '$' && (*i)[1] != '{') {
- char *e;
- char **w, **m = NULL;
- unsigned q;
-
- e = strv_env_get(env, *i+1);
- if (e) {
- int r;
-
- r = strv_split_quoted(&m, e, UNQUOTE_RELAX);
- if (r < 0) {
- ret[k] = NULL;
- strv_free(ret);
- return NULL;
- }
- } else
- m = NULL;
-
- q = strv_length(m);
- l = l + q - 1;
-
- w = realloc(ret, sizeof(char*) * (l+1));
- if (!w) {
- ret[k] = NULL;
- strv_free(ret);
- strv_free(m);
- return NULL;
- }
-
- ret = w;
- if (m) {
- memcpy(ret + k, m, q * sizeof(char*));
- free(m);
- }
-
- k += q;
- continue;
- }
-
- /* If ${FOO} appears as part of a word, replace it by the variable as-is */
- ret[k] = replace_env(*i, env);
- if (!ret[k]) {
- strv_free(ret);
- return NULL;
- }
- k++;
- }
-
- ret[k] = NULL;
- return ret;
-}
-
int files_same(const char *filea, const char *fileb) {
struct stat a, b;
diff --git a/src/shared/util.h b/src/shared/util.h
index f54722f..9409ad9 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -220,9 +220,6 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
char *strappend(const char *s, const char *suffix);
char *strnappend(const char *s, const char *suffix, size_t length);
-char *replace_env(const char *format, char **env);
-char **replace_env_argv(char **argv, char **env);
-
int readlinkat_malloc(int fd, const char *p, char **ret);
int readlink_malloc(const char *p, char **r);
int readlink_value(const char *p, char **ret);
commit 288a74cce597f81d3ba01d8a5ca7d2ba5b654b7e
Author: Ronny Chevalier <chevalier.ronny at gmail.com>
Date: Fri Apr 10 23:15:59 2015 +0200
shared: add terminal-util.[ch]
diff --git a/.gitignore b/.gitignore
index 7330c80..bcf21fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -256,6 +256,7 @@
/test-tables
/test-term-page
/test-term-parser
+/test-terminal-util
/test-time
/test-tmpfiles
/test-udev
diff --git a/Makefile.am b/Makefile.am
index f348ef9..114d4a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -903,6 +903,8 @@ libsystemd_shared_la_SOURCES = \
src/shared/process-util.h \
src/shared/random-util.c \
src/shared/random-util.h \
+ src/shared/terminal-util.c \
+ src/shared/terminal-util.h \
src/shared/uid-range.c \
src/shared/uid-range.h \
src/shared/nss-util.h \
@@ -1394,6 +1396,7 @@ tests += \
test-ellipsize \
test-util \
test-process-util \
+ test-terminal-util \
test-path-lookup \
test-ring \
test-barrier \
@@ -1675,6 +1678,12 @@ test_process_util_SOURCES = \
test_process_util_LDADD = \
libsystemd-shared.la
+test_terminal_util_SOURCES = \
+ src/test/test-terminal-util.c
+
+test_terminal_util_LDADD = \
+ libsystemd-shared.la
+
test_path_lookup_SOURCES = \
src/test/test-path-lookup.c
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 7abe969..17fc5c8 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -38,6 +38,7 @@
#include "hashmap.h"
#include "pager.h"
#include "analyze-verify.h"
+#include "terminal-util.h"
#define SCALE_X (0.1 / 1000.0) /* pixels per us */
#define SCALE_Y (20.0)
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index f951c37..a390cf3 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -29,6 +29,7 @@
#include <getopt.h>
#include "path-util.h"
+#include "terminal-util.h"
#include "util.h"
#include "hashmap.h"
#include "cgroup-util.h"
diff --git a/src/core/execute.c b/src/core/execute.c
index b00d510..bbd0d2c 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -78,6 +78,7 @@
#include "cap-list.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
#ifdef HAVE_APPARMOR
#include "apparmor-util.h"
diff --git a/src/core/failure-action.c b/src/core/failure-action.c
index ffeb5cd..7c6abb3 100644
--- a/src/core/failure-action.c
+++ b/src/core/failure-action.c
@@ -27,6 +27,7 @@
#include "bus-error.h"
#include "special.h"
#include "failure-action.h"
+#include "terminal-util.h"
static void log_and_status(Manager *m, const char *message) {
log_warning("%s", message);
diff --git a/src/core/job.c b/src/core/job.c
index 0230f93..e92e24e 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -33,6 +33,7 @@
#include "async.h"
#include "virt.h"
#include "dbus.h"
+#include "terminal-util.h"
Job* job_new_raw(Unit *unit) {
Job *j;
diff --git a/src/core/killall.c b/src/core/killall.c
index 31bec01..6e85923 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -29,6 +29,7 @@
#include "set.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
#define TIMEOUT_USEC (10 * USEC_PER_SEC)
diff --git a/src/core/main.c b/src/core/main.c
index 80a51ee..af28ac6 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -74,6 +74,7 @@
#include "kmod-setup.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
static enum {
ACTION_RUN,
diff --git a/src/core/manager.c b/src/core/manager.c
index 6d1729b..2b04644 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -72,6 +72,7 @@
#include "bus-kernel.h"
#include "time-util.h"
#include "process-util.h"
+#include "terminal-util.h"
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index f037a38..aba16b4 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -43,6 +43,7 @@
#include "def.h"
#include "switch-root.h"
#include "process-util.h"
+#include "terminal-util.h"
#define FINALIZE_ATTEMPTS 50
diff --git a/src/core/transaction.c b/src/core/transaction.c
index 64c2af5..5974b1e 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -25,6 +25,7 @@
#include "bus-common-errors.h"
#include "bus-error.h"
#include "transaction.h"
+#include "terminal-util.h"
static void transaction_unlink_job(Transaction *tr, Job *j, bool delete_dependencies);
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 106c036..c764bb4 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -33,6 +33,7 @@
#include "build.h"
#include "strv.h"
#include "process-util.h"
+#include "terminal-util.h"
static const char prefixes[] =
"/etc\0"
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index c92f379..37326df 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -35,6 +35,7 @@
#include "random-util.h"
#include "locale-util.h"
#include "ask-password-api.h"
+#include "terminal-util.h"
static char *arg_root = NULL;
static char *arg_locale = NULL; /* $LANG */
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index 0f59f5a..d4688d3 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -32,6 +32,7 @@
#include "fileio.h"
#include "path-util.h"
#include "process-util.h"
+#include "terminal-util.h"
static const char *arg_dest = "/tmp";
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
index 4f6ddfa..bcb0ff9 100644
--- a/src/journal/coredumpctl.c
+++ b/src/journal/coredumpctl.c
@@ -38,6 +38,7 @@
#include "compress.h"
#include "sigbus.h"
#include "process-util.h"
+#include "terminal-util.h"
static enum {
ACTION_NONE,
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 146c10b..ce734d8 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -32,6 +32,7 @@
#include "journal-verify.h"
#include "lookup3.h"
#include "compress.h"
+#include "terminal-util.h"
static void draw_progress(uint64_t p, usec_t *last_usec) {
unsigned n, i, j, k;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 40c84b9..a5ed41d 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -60,6 +60,7 @@
#include "mkdir.h"
#include "bus-util.h"
#include "bus-error.h"
+#include "terminal-util.h"
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index 6c15530..307bdc3 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -28,6 +28,7 @@
#include "journald-console.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
static bool prefix_timestamp(void) {
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
index 8008f74..d24502d 100644
--- a/src/journal/test-journal-verify.c
+++ b/src/journal/test-journal-verify.c
@@ -28,6 +28,7 @@
#include "rm-rf.h"
#include "journal-file.h"
#include "journal-verify.h"
+#include "terminal-util.h"
#define N_ENTRIES 6000
#define RANDOM_RANGE 77
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index d722680..9165dd7 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -25,6 +25,7 @@
#include "macro.h"
#include "cap-list.h"
#include "formats-util.h"
+#include "terminal-util.h"
#include "bus-message.h"
#include "bus-internal.h"
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index d52dbdf..39caa4e 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -36,6 +36,7 @@
#include "bus-signature.h"
#include "bus-type.h"
#include "busctl-introspect.h"
+#include "terminal-util.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 7393eb3..4a5a618 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -42,6 +42,7 @@
#include "spawn-polkit-agent.h"
#include "verbs.h"
#include "process-util.h"
+#include "terminal-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index 29e7ed0..f635fb1 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -29,6 +29,7 @@
#include "logind-action.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
int manager_handle_action(
Manager *m,
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index e8da59a..440c32a 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -31,6 +31,7 @@
#include "bus-error.h"
#include "udev-util.h"
#include "logind.h"
+#include "terminal-util.h"
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
Device *d;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 6bf9205..76070a3 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -42,6 +42,7 @@
#include "logind.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 4c0bebd..11d24ce 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -30,6 +30,7 @@
#include "util.h"
#include "mkdir.h"
#include "formats-util.h"
+#include "terminal-util.h"
Seat *seat_new(Manager *m, const char *id) {
Seat *s;
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index cebc90c..6a450b0 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -38,6 +38,7 @@
#include "bus-error.h"
#include "logind-session.h"
#include "formats-util.h"
+#include "terminal-util.h"
#define RELEASE_USEC (20*USEC_PER_SEC)
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index a0fabfe..cdd45ac 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -41,6 +41,7 @@
#include "fileio.h"
#include "bus-error.h"
#include "formats-util.h"
+#include "terminal-util.h"
static int parse_argv(
pam_handle_t *handle,
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index 9bd9152..9a9fb76 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -27,6 +27,7 @@
#include "sysfs-show.h"
#include "path-util.h"
#include "udev-util.h"
+#include "terminal-util.h"
static int show_sysfs_one(
struct udev *udev,
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 87e15d7..26cd5b8 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -53,6 +53,7 @@
#include "verbs.h"
#include "import-util.h"
#include "process-util.h"
+#include "terminal-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 9716499..69b4ab4 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -41,6 +41,7 @@
#include "socket-util.h"
#include "ether-addr-util.h"
#include "verbs.h"
+#include "terminal-util.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 6417a8c..6d4aadd 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -94,6 +94,7 @@
#include "local-addresses.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index ad1a773..a3a2e51 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -36,6 +36,7 @@
#include "mkdir.h"
#include "strv.h"
#include "random-util.h"
+#include "terminal-util.h"
#include "ask-password-api.h"
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index 0f263e9..1a2c4b2 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -31,6 +31,7 @@
#include "path-util.h"
#include "cgroup-util.h"
#include "cgroup-show.h"
+#include "terminal-util.h"
static int compare(const void *a, const void *b) {
const pid_t *p = a, *q = b;
diff --git a/src/shared/log.c b/src/shared/log.c
index 7edcf1f..85c0605 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -36,6 +36,7 @@
#include "socket-util.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
#define SNDBUF_SIZE (8*1024*1024)
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 7a7a1e9..27f4072 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -33,6 +33,7 @@
#include "journal-internal.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
/* up to three lines (each up to 100 characters),
or 300 characters, whichever is less */
diff --git a/src/shared/pager.c b/src/shared/pager.c
index b5a584b..58b62fd 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -29,6 +29,7 @@
#include "util.h"
#include "process-util.h"
#include "macro.h"
+#include "terminal-util.h"
static pid_t pager_pid = 0;
diff --git a/src/shared/terminal-util.c b/src/shared/terminal-util.c
new file mode 100644
index 0000000..f5b6590
--- /dev/null
+++ b/src/shared/terminal-util.c
@@ -0,0 +1,1072 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <time.h>
+#include <assert.h>
+#include <poll.h>
+#include <linux/vt.h>
+#include <linux/tiocl.h>
+#include <linux/kd.h>
+
+#include "terminal-util.h"
+#include "time-util.h"
+#include "process-util.h"
+#include "util.h"
+#include "fileio.h"
+#include "path-util.h"
+
+static volatile unsigned cached_columns = 0;
+static volatile unsigned cached_lines = 0;
+
+int chvt(int vt) {
+ _cleanup_close_ int fd;
+
+ fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ if (vt < 0) {
+ int tiocl[2] = {
+ TIOCL_GETKMSGREDIRECT,
+ 0
+ };
+
+ if (ioctl(fd, TIOCLINUX, tiocl) < 0)
+ return -errno;
+
+ vt = tiocl[0] <= 0 ? 1 : tiocl[0];
+ }
+
+ if (ioctl(fd, VT_ACTIVATE, vt) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
+ struct termios old_termios, new_termios;
+ char c, line[LINE_MAX];
+
+ assert(f);
+ assert(ret);
+
+ if (tcgetattr(fileno(f), &old_termios) >= 0) {
+ new_termios = old_termios;
+
+ new_termios.c_lflag &= ~ICANON;
+ new_termios.c_cc[VMIN] = 1;
+ new_termios.c_cc[VTIME] = 0;
+
+ if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
+ size_t k;
+
+ if (t != USEC_INFINITY) {
+ if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
+ tcsetattr(fileno(f), TCSADRAIN, &old_termios);
+ return -ETIMEDOUT;
+ }
+ }
+
+ k = fread(&c, 1, 1, f);
+
+ tcsetattr(fileno(f), TCSADRAIN, &old_termios);
+
+ if (k <= 0)
+ return -EIO;
+
+ if (need_nl)
+ *need_nl = c != '\n';
+
+ *ret = c;
+ return 0;
+ }
+ }
+
+ if (t != USEC_INFINITY) {
+ if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
+ return -ETIMEDOUT;
+ }
+
+ errno = 0;
+ if (!fgets(line, sizeof(line), f))
+ return errno ? -errno : -EIO;
+
+ truncate_nl(line);
+
+ if (strlen(line) != 1)
+ return -EBADMSG;
+
+ if (need_nl)
+ *need_nl = false;
+
+ *ret = line[0];
+ return 0;
+}
+
+int ask_char(char *ret, const char *replies, const char *text, ...) {
+ int r;
+
+ assert(ret);
+ assert(replies);
+ assert(text);
+
+ for (;;) {
+ va_list ap;
+ char c;
+ bool need_nl = true;
+
+ if (on_tty())
+ fputs(ANSI_HIGHLIGHT_ON, stdout);
+
+ va_start(ap, text);
+ vprintf(text, ap);
+ va_end(ap);
+
+ if (on_tty())
+ fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+ fflush(stdout);
+
+ r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl);
+ if (r < 0) {
+
+ if (r == -EBADMSG) {
+ puts("Bad input, please try again.");
+ continue;
+ }
+
+ putchar('\n');
+ return r;
+ }
+
+ if (need_nl)
+ putchar('\n');
+
+ if (strchr(replies, c)) {
+ *ret = c;
+ return 0;
+ }
+
+ puts("Read unexpected character, please try again.");
+ }
+}
+
+int ask_string(char **ret, const char *text, ...) {
+ assert(ret);
+ assert(text);
+
+ for (;;) {
+ char line[LINE_MAX];
+ va_list ap;
+
+ if (on_tty())
+ fputs(ANSI_HIGHLIGHT_ON, stdout);
+
+ va_start(ap, text);
+ vprintf(text, ap);
+ va_end(ap);
+
+ if (on_tty())
+ fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+ fflush(stdout);
+
+ errno = 0;
+ if (!fgets(line, sizeof(line), stdin))
+ return errno ? -errno : -EIO;
+
+ if (!endswith(line, "\n"))
+ putchar('\n');
+ else {
+ char *s;
+
+ if (isempty(line))
+ continue;
+
+ truncate_nl(line);
+ s = strdup(line);
+ if (!s)
+ return -ENOMEM;
+
+ *ret = s;
+ return 0;
+ }
+ }
+}
+
+int reset_terminal_fd(int fd, bool switch_to_text) {
+ struct termios termios;
+ int r = 0;
+
+ /* Set terminal to some sane defaults */
+
+ assert(fd >= 0);
+
+ /* We leave locked terminal attributes untouched, so that
+ * Plymouth may set whatever it wants to set, and we don't
+ * interfere with that. */
+
+ /* Disable exclusive mode, just in case */
+ ioctl(fd, TIOCNXCL);
+
+ /* Switch to text mode */
+ if (switch_to_text)
+ ioctl(fd, KDSETMODE, KD_TEXT);
+
+ /* Enable console unicode mode */
+ ioctl(fd, KDSKBMODE, K_UNICODE);
+
+ if (tcgetattr(fd, &termios) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ /* We only reset the stuff that matters to the software. How
+ * hardware is set up we don't touch assuming that somebody
+ * else will do that for us */
+
+ termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
+ termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
+ termios.c_oflag |= ONLCR;
+ termios.c_cflag |= CREAD;
+ termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
+
+ termios.c_cc[VINTR] = 03; /* ^C */
+ termios.c_cc[VQUIT] = 034; /* ^\ */
+ termios.c_cc[VERASE] = 0177;
+ termios.c_cc[VKILL] = 025; /* ^X */
+ termios.c_cc[VEOF] = 04; /* ^D */
+ termios.c_cc[VSTART] = 021; /* ^Q */
+ termios.c_cc[VSTOP] = 023; /* ^S */
+ termios.c_cc[VSUSP] = 032; /* ^Z */
+ termios.c_cc[VLNEXT] = 026; /* ^V */
+ termios.c_cc[VWERASE] = 027; /* ^W */
+ termios.c_cc[VREPRINT] = 022; /* ^R */
+ termios.c_cc[VEOL] = 0;
+ termios.c_cc[VEOL2] = 0;
+
+ termios.c_cc[VTIME] = 0;
+ termios.c_cc[VMIN] = 1;
+
+ if (tcsetattr(fd, TCSANOW, &termios) < 0)
+ r = -errno;
+
+finish:
+ /* Just in case, flush all crap out */
+ tcflush(fd, TCIOFLUSH);
+
+ return r;
+}
+
+int reset_terminal(const char *name) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ return reset_terminal_fd(fd, true);
+}
+
+int open_terminal(const char *name, int mode) {
+ int fd, r;
+ unsigned c = 0;
+
+ /*
+ * If a TTY is in the process of being closed opening it might
+ * cause EIO. This is horribly awful, but unlikely to be
+ * changed in the kernel. Hence we work around this problem by
+ * retrying a couple of times.
+ *
+ * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
+ */
+
+ assert(!(mode & O_CREAT));
+
+ for (;;) {
+ fd = open(name, mode, 0);
+ if (fd >= 0)
+ break;
+
+ if (errno != EIO)
+ return -errno;
+
+ /* Max 1s in total */
+ if (c >= 20)
+ return -errno;
+
+ usleep(50 * USEC_PER_MSEC);
+ c++;
+ }
+
+ r = isatty(fd);
+ if (r < 0) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ if (!r) {
+ safe_close(fd);
+ return -ENOTTY;
+ }
+
+ return fd;
+}
+
+int acquire_terminal(
+ const char *name,
+ bool fail,
+ bool force,
+ bool ignore_tiocstty_eperm,
+ usec_t timeout) {
+
+ int fd = -1, notify = -1, r = 0, wd = -1;
+ usec_t ts = 0;
+
+ assert(name);
+
+ /* We use inotify to be notified when the tty is closed. We
+ * create the watch before checking if we can actually acquire
+ * it, so that we don't lose any event.
+ *
+ * Note: strictly speaking this actually watches for the
+ * device being closed, it does *not* really watch whether a
+ * tty loses its controlling process. However, unless some
+ * rogue process uses TIOCNOTTY on /dev/tty *after* closing
+ * its tty otherwise this will not become a problem. As long
+ * as the administrator makes sure not configure any service
+ * on the same tty as an untrusted user this should not be a
+ * problem. (Which he probably should not do anyway.) */
+
+ if (timeout != USEC_INFINITY)
+ ts = now(CLOCK_MONOTONIC);
+
+ if (!fail && !force) {
+ notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
+ if (notify < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ wd = inotify_add_watch(notify, name, IN_CLOSE);
+ if (wd < 0) {
+ r = -errno;
+ goto fail;
+ }
+ }
+
+ for (;;) {
+ struct sigaction sa_old, sa_new = {
+ .sa_handler = SIG_IGN,
+ .sa_flags = SA_RESTART,
+ };
+
+ if (notify >= 0) {
+ r = flush_fd(notify);
+ if (r < 0)
+ goto fail;
+ }
+
+ /* We pass here O_NOCTTY only so that we can check the return
+ * value TIOCSCTTY and have a reliable way to figure out if we
+ * successfully became the controlling process of the tty */
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
+ * if we already own the tty. */
+ assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
+
+ /* First, try to get the tty */
+ if (ioctl(fd, TIOCSCTTY, force) < 0)
+ r = -errno;
+
+ assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
+
+ /* Sometimes it makes sense to ignore TIOCSCTTY
+ * returning EPERM, i.e. when very likely we already
+ * are have this controlling terminal. */
+ if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
+ r = 0;
+
+ if (r < 0 && (force || fail || r != -EPERM)) {
+ goto fail;
+ }
+
+ if (r >= 0)
+ break;
+
+ assert(!fail);
+ assert(!force);
+ assert(notify >= 0);
+
+ for (;;) {
+ union inotify_event_buffer buffer;
+ struct inotify_event *e;
+ ssize_t l;
+
+ if (timeout != USEC_INFINITY) {
+ usec_t n;
+
+ n = now(CLOCK_MONOTONIC);
+ if (ts + timeout < n) {
+ r = -ETIMEDOUT;
+ goto fail;
+ }
+
+ r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
+ if (r < 0)
+ goto fail;
+
+ if (r == 0) {
+ r = -ETIMEDOUT;
+ goto fail;
+ }
+ }
+
+ l = read(notify, &buffer, sizeof(buffer));
+ if (l < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+
+ r = -errno;
+ goto fail;
+ }
+
+ FOREACH_INOTIFY_EVENT(e, buffer, l) {
+ if (e->wd != wd || !(e->mask & IN_CLOSE)) {
+ r = -EIO;
+ goto fail;
+ }
+ }
+
+ break;
+ }
+
+ /* We close the tty fd here since if the old session
+ * ended our handle will be dead. It's important that
+ * we do this after sleeping, so that we don't enter
+ * an endless loop. */
+ fd = safe_close(fd);
+ }
+
+ safe_close(notify);
+
+ r = reset_terminal_fd(fd, true);
+ if (r < 0)
+ log_warning_errno(r, "Failed to reset terminal: %m");
+
+ return fd;
+
+fail:
+ safe_close(fd);
+ safe_close(notify);
+
+ return r;
+}
+
+int release_terminal(void) {
+ static const struct sigaction sa_new = {
+ .sa_handler = SIG_IGN,
+ .sa_flags = SA_RESTART,
+ };
+
+ _cleanup_close_ int fd = -1;
+ struct sigaction sa_old;
+ int r = 0;
+
+ fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
+ * by our own TIOCNOTTY */
+ assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
+
+ if (ioctl(fd, TIOCNOTTY) < 0)
+ r = -errno;
+
+ assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
+
+ return r;
+}
+
+int terminal_vhangup_fd(int fd) {
+ assert(fd >= 0);
+
+ if (ioctl(fd, TIOCVHANGUP) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int terminal_vhangup(const char *name) {
+ _cleanup_close_ int fd;
+
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ return terminal_vhangup_fd(fd);
+}
+
+int vt_disallocate(const char *name) {
+ int fd, r;
+ unsigned u;
+
+ /* Deallocate the VT if possible. If not possible
+ * (i.e. because it is the active one), at least clear it
+ * entirely (including the scrollback buffer) */
+
+ if (!startswith(name, "/dev/"))
+ return -EINVAL;
+
+ if (!tty_is_vc(name)) {
+ /* So this is not a VT. I guess we cannot deallocate
+ * it then. But let's at least clear the screen */
+
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ loop_write(fd,
+ "\033[r" /* clear scrolling region */
+ "\033[H" /* move home */
+ "\033[2J", /* clear screen */
+ 10, false);
+ safe_close(fd);
+
+ return 0;
+ }
+
+ if (!startswith(name, "/dev/tty"))
+ return -EINVAL;
+
+ r = safe_atou(name+8, &u);
+ if (r < 0)
+ return r;
+
+ if (u <= 0)
+ return -EINVAL;
+
+ /* Try to deallocate */
+ fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ r = ioctl(fd, VT_DISALLOCATE, u);
+ safe_close(fd);
+
+ if (r >= 0)
+ return 0;
+
+ if (errno != EBUSY)
+ return -errno;
+
+ /* Couldn't deallocate, so let's clear it fully with
+ * scrollback */
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ loop_write(fd,
+ "\033[r" /* clear scrolling region */
+ "\033[H" /* move home */
+ "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
+ 10, false);
+ safe_close(fd);
+
+ return 0;
+}
+
+void warn_melody(void) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return;
+
+ /* Yeah, this is synchronous. Kinda sucks. But well... */
+
+ ioctl(fd, KIOCSOUND, (int)(1193180/440));
+ usleep(125*USEC_PER_MSEC);
+
+ ioctl(fd, KIOCSOUND, (int)(1193180/220));
+ usleep(125*USEC_PER_MSEC);
+
+ ioctl(fd, KIOCSOUND, (int)(1193180/220));
+ usleep(125*USEC_PER_MSEC);
+
+ ioctl(fd, KIOCSOUND, 0);
+}
+
+int make_console_stdio(void) {
+ int fd, r;
+
+ /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
+
+ fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to acquire terminal: %m");
+
+ r = make_stdio(fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to duplicate terminal fd: %m");
+
+ return 0;
+}
+
+int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
+ static const char status_indent[] = " "; /* "[" STATUS "] " */
+ _cleanup_free_ char *s = NULL;
+ _cleanup_close_ int fd = -1;
+ struct iovec iovec[6] = {};
+ int n = 0;
+ static bool prev_ephemeral;
+
+ assert(format);
+
+ /* This is independent of logging, as status messages are
+ * optional and go exclusively to the console. */
+
+ if (vasprintf(&s, format, ap) < 0)
+ return log_oom();
+
+ fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ if (ellipse) {
+ char *e;
+ size_t emax, sl;
+ int c;
+
+ c = fd_columns(fd);
+ if (c <= 0)
+ c = 80;
+
+ sl = status ? sizeof(status_indent)-1 : 0;
+
+ emax = c - sl - 1;
+ if (emax < 3)
+ emax = 3;
+
+ e = ellipsize(s, emax, 50);
+ if (e) {
+ free(s);
+ s = e;
+ }
+ }
+
+ if (prev_ephemeral)
+ IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
+ prev_ephemeral = ephemeral;
+
+ if (status) {
+ if (!isempty(status)) {
+ IOVEC_SET_STRING(iovec[n++], "[");
+ IOVEC_SET_STRING(iovec[n++], status);
+ IOVEC_SET_STRING(iovec[n++], "] ");
+ } else
+ IOVEC_SET_STRING(iovec[n++], status_indent);
+ }
+
+ IOVEC_SET_STRING(iovec[n++], s);
+ if (!ephemeral)
+ IOVEC_SET_STRING(iovec[n++], "\n");
+
+ if (writev(fd, iovec, n) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
+ va_list ap;
+ int r;
+
+ assert(format);
+
+ va_start(ap, format);
+ r = status_vprintf(status, ellipse, ephemeral, format, ap);
+ va_end(ap);
+
+ return r;
+}
+
+bool tty_is_vc(const char *tty) {
+ assert(tty);
+
+ return vtnr_from_tty(tty) >= 0;
+}
+
+bool tty_is_console(const char *tty) {
+ assert(tty);
+
+ if (startswith(tty, "/dev/"))
+ tty += 5;
+
+ return streq(tty, "console");
+}
+
+int vtnr_from_tty(const char *tty) {
+ int i, r;
+
+ assert(tty);
+
+ if (startswith(tty, "/dev/"))
+ tty += 5;
+
+ if (!startswith(tty, "tty") )
+ return -EINVAL;
+
+ if (tty[3] < '0' || tty[3] > '9')
+ return -EINVAL;
+
+ r = safe_atoi(tty+3, &i);
+ if (r < 0)
+ return r;
+
+ if (i < 0 || i > 63)
+ return -EINVAL;
+
+ return i;
+}
+
+char *resolve_dev_console(char **active) {
+ char *tty;
+
+ /* Resolve where /dev/console is pointing to, if /sys is actually ours
+ * (i.e. not read-only-mounted which is a sign for container setups) */
+
+ if (path_is_read_only_fs("/sys") > 0)
+ return NULL;
+
+ if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
+ return NULL;
+
+ /* If multiple log outputs are configured the last one is what
+ * /dev/console points to */
+ tty = strrchr(*active, ' ');
+ if (tty)
+ tty++;
+ else
+ tty = *active;
+
+ if (streq(tty, "tty0")) {
+ char *tmp;
+
+ /* Get the active VC (e.g. tty1) */
+ if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
+ free(*active);
+ tty = *active = tmp;
+ }
+ }
+
+ return tty;
+}
+
+bool tty_is_vc_resolve(const char *tty) {
+ _cleanup_free_ char *active = NULL;
+
+ assert(tty);
+
+ if (startswith(tty, "/dev/"))
+ tty += 5;
+
+ if (streq(tty, "console")) {
+ tty = resolve_dev_console(&active);
+ if (!tty)
+ return false;
+ }
+
+ return tty_is_vc(tty);
+}
+
+const char *default_term_for_tty(const char *tty) {
+ assert(tty);
+
+ return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt220";
+}
+
+int fd_columns(int fd) {
+ struct winsize ws = {};
+
+ if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
+ return -errno;
+
+ if (ws.ws_col <= 0)
+ return -EIO;
+
+ return ws.ws_col;
+}
+
+unsigned columns(void) {
+ const char *e;
+ int c;
+
+ if (_likely_(cached_columns > 0))
+ return cached_columns;
+
+ c = 0;
+ e = getenv("COLUMNS");
+ if (e)
+ (void) safe_atoi(e, &c);
+
+ if (c <= 0)
+ c = fd_columns(STDOUT_FILENO);
+
+ if (c <= 0)
+ c = 80;
+
+ cached_columns = c;
+ return cached_columns;
+}
+
+int fd_lines(int fd) {
+ struct winsize ws = {};
+
+ if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
+ return -errno;
+
+ if (ws.ws_row <= 0)
+ return -EIO;
+
+ return ws.ws_row;
+}
+
+unsigned lines(void) {
+ const char *e;
+ int l;
+
+ if (_likely_(cached_lines > 0))
+ return cached_lines;
+
+ l = 0;
+ e = getenv("LINES");
+ if (e)
+ (void) safe_atoi(e, &l);
+
+ if (l <= 0)
+ l = fd_lines(STDOUT_FILENO);
+
+ if (l <= 0)
+ l = 24;
+
+ cached_lines = l;
+ return cached_lines;
+}
+
+/* intended to be used as a SIGWINCH sighandler */
+void columns_lines_cache_reset(int signum) {
+ cached_columns = 0;
+ cached_lines = 0;
+}
+
+bool on_tty(void) {
+ static int cached_on_tty = -1;
+
+ if (_unlikely_(cached_on_tty < 0))
+ cached_on_tty = isatty(STDOUT_FILENO) > 0;
+
+ return cached_on_tty;
+}
+
+int make_stdio(int fd) {
+ int r, s, t;
+
+ assert(fd >= 0);
+
+ r = dup2(fd, STDIN_FILENO);
+ s = dup2(fd, STDOUT_FILENO);
+ t = dup2(fd, STDERR_FILENO);
+
+ if (fd >= 3)
+ safe_close(fd);
+
+ if (r < 0 || s < 0 || t < 0)
+ return -errno;
+
+ /* Explicitly unset O_CLOEXEC, since if fd was < 3, then
+ * dup2() was a NOP and the bit hence possibly set. */
+ fd_cloexec(STDIN_FILENO, false);
+ fd_cloexec(STDOUT_FILENO, false);
+ fd_cloexec(STDERR_FILENO, false);
+
+ return 0;
+}
+
+int make_null_stdio(void) {
+ int null_fd;
+
+ null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
+ if (null_fd < 0)
+ return -errno;
+
+ return make_stdio(null_fd);
+}
+
+int getttyname_malloc(int fd, char **ret) {
+ size_t l = 100;
+ int r;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ for (;;) {
+ char path[l];
+
+ r = ttyname_r(fd, path, sizeof(path));
+ if (r == 0) {
+ const char *p;
+ char *c;
+
+ p = startswith(path, "/dev/");
+ c = strdup(p ?: path);
+ if (!c)
+ return -ENOMEM;
+
+ *ret = c;
+ return 0;
+ }
+
+ if (r != ERANGE)
+ return -r;
+
+ l *= 2;
+ }
+
+ return 0;
+}
+
+int getttyname_harder(int fd, char **r) {
+ int k;
+ char *s = NULL;
+
+ k = getttyname_malloc(fd, &s);
+ if (k < 0)
+ return k;
+
+ if (streq(s, "tty")) {
+ free(s);
+ return get_ctty(0, NULL, r);
+ }
+
+ *r = s;
+ return 0;
+}
+
+int get_ctty_devnr(pid_t pid, dev_t *d) {
+ int r;
+ _cleanup_free_ char *line = NULL;
+ const char *p;
+ unsigned long ttynr;
+
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "stat");
+ r = read_one_line_file(p, &line);
+ if (r < 0)
+ return r;
+
+ p = strrchr(line, ')');
+ if (!p)
+ return -EIO;
+
+ p++;
+
+ if (sscanf(p, " "
+ "%*c " /* state */
+ "%*d " /* ppid */
+ "%*d " /* pgrp */
+ "%*d " /* session */
+ "%lu ", /* ttynr */
+ &ttynr) != 1)
+ return -EIO;
+
+ if (major(ttynr) == 0 && minor(ttynr) == 0)
+ return -ENOENT;
+
+ if (d)
+ *d = (dev_t) ttynr;
+
+ return 0;
+}
+
+int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
+ char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
+ _cleanup_free_ char *s = NULL;
+ const char *p;
+ dev_t devnr;
+ int k;
+
+ assert(r);
+
+ k = get_ctty_devnr(pid, &devnr);
+ if (k < 0)
+ return k;
+
+ sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
+
+ k = readlink_malloc(fn, &s);
+ if (k < 0) {
+
+ if (k != -ENOENT)
+ return k;
+
+ /* This is an ugly hack */
+ if (major(devnr) == 136) {
+ if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
+ return -ENOMEM;
+ } else {
+ /* Probably something like the ptys which have no
+ * symlink in /dev/char. Let's return something
+ * vaguely useful. */
+
+ b = strdup(fn + 5);
+ if (!b)
+ return -ENOMEM;
+ }
+ } else {
+ if (startswith(s, "/dev/"))
+ p = s + 5;
+ else if (startswith(s, "../"))
+ p = s + 3;
+ else
+ p = s;
+
+ b = strdup(p);
+ if (!b)
+ return -ENOMEM;
+ }
+
+ *r = b;
+ if (_devnr)
+ *_devnr = devnr;
+
+ return 0;
+}
diff --git a/src/shared/terminal-util.h b/src/shared/terminal-util.h
new file mode 100644
index 0000000..188714f
--- /dev/null
+++ b/src/shared/terminal-util.h
@@ -0,0 +1,109 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <stdbool.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "macro.h"
+#include "time-util.h"
+
+#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
+#define ANSI_RED_ON "\x1B[31m"
+#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
+#define ANSI_GREEN_ON "\x1B[32m"
+#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
+#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
+#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m"
+#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
+#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
+
+int reset_terminal_fd(int fd, bool switch_to_text);
+int reset_terminal(const char *name);
+
+int open_terminal(const char *name, int mode);
+int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
+int release_terminal(void);
+
+int terminal_vhangup_fd(int fd);
+int terminal_vhangup(const char *name);
+
+int chvt(int vt);
+
+int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
+int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
+int ask_string(char **ret, const char *text, ...) _printf_(2, 3);
+
+int vt_disallocate(const char *name);
+
+char *resolve_dev_console(char **active);
+bool tty_is_vc(const char *tty);
+bool tty_is_vc_resolve(const char *tty);
+bool tty_is_console(const char *tty) _pure_;
+int vtnr_from_tty(const char *tty);
+const char *default_term_for_tty(const char *tty);
+
+void warn_melody(void);
+
+int make_stdio(int fd);
+int make_null_stdio(void);
+int make_console_stdio(void);
+
+int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0);
+int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5);
+
+int fd_columns(int fd);
+unsigned columns(void);
+int fd_lines(int fd);
+unsigned lines(void);
+void columns_lines_cache_reset(int _unused_ signum);
+
+bool on_tty(void);
+
+static inline const char *ansi_highlight(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_ON : "";
+}
+
+static inline const char *ansi_highlight_red(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_RED_ON : "";
+}
+
+static inline const char *ansi_highlight_green(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_GREEN_ON : "";
+}
+
+static inline const char *ansi_highlight_yellow(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_YELLOW_ON : "";
+}
+
+static inline const char *ansi_highlight_blue(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_BLUE_ON : "";
+}
+
+static inline const char *ansi_highlight_off(void) {
+ return on_tty() ? ANSI_HIGHLIGHT_OFF : "";
+}
+
+int get_ctty_devnr(pid_t pid, dev_t *d);
+int get_ctty(pid_t, dev_t *_devnr, char **r);
+
+int getttyname_malloc(int fd, char **r);
+int getttyname_harder(int fd, char **r);
diff --git a/src/shared/util.c b/src/shared/util.c
index e4c4dd9..508b5d1 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -35,9 +35,6 @@
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
-#include <linux/vt.h>
-#include <linux/tiocl.h>
-#include <termios.h>
#include <stdarg.h>
#include <poll.h>
#include <ctype.h>
@@ -45,7 +42,6 @@
#include <sys/utsname.h>
#include <pwd.h>
#include <netinet/ip.h>
-#include <linux/kd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <glob.h>
@@ -95,6 +91,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "random-util.h"
+#include "terminal-util.h"
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
@@ -102,9 +99,6 @@ assert_cc(EAGAIN == EWOULDBLOCK);
int saved_argc = 0;
char **saved_argv = NULL;
-static volatile unsigned cached_columns = 0;
-static volatile unsigned cached_lines = 0;
-
size_t page_size(void) {
static thread_local size_t pgsz = 0;
long r;
@@ -1509,301 +1503,6 @@ bool fstype_is_network(const char *fstype) {
return nulstr_contains(table, fstype);
}
-int chvt(int vt) {
- _cleanup_close_ int fd;
-
- fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- if (vt < 0) {
- int tiocl[2] = {
- TIOCL_GETKMSGREDIRECT,
- 0
- };
-
- if (ioctl(fd, TIOCLINUX, tiocl) < 0)
- return -errno;
-
- vt = tiocl[0] <= 0 ? 1 : tiocl[0];
- }
-
- if (ioctl(fd, VT_ACTIVATE, vt) < 0)
- return -errno;
-
- return 0;
-}
-
-int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
- struct termios old_termios, new_termios;
- char c, line[LINE_MAX];
-
- assert(f);
- assert(ret);
-
- if (tcgetattr(fileno(f), &old_termios) >= 0) {
- new_termios = old_termios;
-
- new_termios.c_lflag &= ~ICANON;
- new_termios.c_cc[VMIN] = 1;
- new_termios.c_cc[VTIME] = 0;
-
- if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
- size_t k;
-
- if (t != USEC_INFINITY) {
- if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
- tcsetattr(fileno(f), TCSADRAIN, &old_termios);
- return -ETIMEDOUT;
- }
- }
-
- k = fread(&c, 1, 1, f);
-
- tcsetattr(fileno(f), TCSADRAIN, &old_termios);
-
- if (k <= 0)
- return -EIO;
-
- if (need_nl)
- *need_nl = c != '\n';
-
- *ret = c;
- return 0;
- }
- }
-
- if (t != USEC_INFINITY) {
- if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
- return -ETIMEDOUT;
- }
-
- errno = 0;
- if (!fgets(line, sizeof(line), f))
- return errno ? -errno : -EIO;
-
- truncate_nl(line);
-
- if (strlen(line) != 1)
- return -EBADMSG;
-
- if (need_nl)
- *need_nl = false;
-
- *ret = line[0];
- return 0;
-}
-
-int ask_char(char *ret, const char *replies, const char *text, ...) {
- int r;
-
- assert(ret);
- assert(replies);
- assert(text);
-
- for (;;) {
- va_list ap;
- char c;
- bool need_nl = true;
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_ON, stdout);
-
- va_start(ap, text);
- vprintf(text, ap);
- va_end(ap);
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_OFF, stdout);
-
- fflush(stdout);
-
- r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl);
- if (r < 0) {
-
- if (r == -EBADMSG) {
- puts("Bad input, please try again.");
- continue;
- }
-
- putchar('\n');
- return r;
- }
-
- if (need_nl)
- putchar('\n');
-
- if (strchr(replies, c)) {
- *ret = c;
- return 0;
- }
-
- puts("Read unexpected character, please try again.");
- }
-}
-
-int ask_string(char **ret, const char *text, ...) {
- assert(ret);
- assert(text);
-
- for (;;) {
- char line[LINE_MAX];
- va_list ap;
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_ON, stdout);
-
- va_start(ap, text);
- vprintf(text, ap);
- va_end(ap);
-
- if (on_tty())
- fputs(ANSI_HIGHLIGHT_OFF, stdout);
-
- fflush(stdout);
-
- errno = 0;
- if (!fgets(line, sizeof(line), stdin))
- return errno ? -errno : -EIO;
-
- if (!endswith(line, "\n"))
- putchar('\n');
- else {
- char *s;
-
- if (isempty(line))
- continue;
-
- truncate_nl(line);
- s = strdup(line);
- if (!s)
- return -ENOMEM;
-
- *ret = s;
- return 0;
- }
- }
-}
-
-int reset_terminal_fd(int fd, bool switch_to_text) {
- struct termios termios;
- int r = 0;
-
- /* Set terminal to some sane defaults */
-
- assert(fd >= 0);
-
- /* We leave locked terminal attributes untouched, so that
- * Plymouth may set whatever it wants to set, and we don't
- * interfere with that. */
-
- /* Disable exclusive mode, just in case */
- ioctl(fd, TIOCNXCL);
-
- /* Switch to text mode */
- if (switch_to_text)
- ioctl(fd, KDSETMODE, KD_TEXT);
-
- /* Enable console unicode mode */
- ioctl(fd, KDSKBMODE, K_UNICODE);
-
- if (tcgetattr(fd, &termios) < 0) {
- r = -errno;
- goto finish;
- }
-
- /* We only reset the stuff that matters to the software. How
- * hardware is set up we don't touch assuming that somebody
- * else will do that for us */
-
- termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
- termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
- termios.c_oflag |= ONLCR;
- termios.c_cflag |= CREAD;
- termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
-
- termios.c_cc[VINTR] = 03; /* ^C */
- termios.c_cc[VQUIT] = 034; /* ^\ */
- termios.c_cc[VERASE] = 0177;
- termios.c_cc[VKILL] = 025; /* ^X */
- termios.c_cc[VEOF] = 04; /* ^D */
- termios.c_cc[VSTART] = 021; /* ^Q */
- termios.c_cc[VSTOP] = 023; /* ^S */
- termios.c_cc[VSUSP] = 032; /* ^Z */
- termios.c_cc[VLNEXT] = 026; /* ^V */
- termios.c_cc[VWERASE] = 027; /* ^W */
- termios.c_cc[VREPRINT] = 022; /* ^R */
- termios.c_cc[VEOL] = 0;
- termios.c_cc[VEOL2] = 0;
-
- termios.c_cc[VTIME] = 0;
- termios.c_cc[VMIN] = 1;
-
- if (tcsetattr(fd, TCSANOW, &termios) < 0)
- r = -errno;
-
-finish:
- /* Just in case, flush all crap out */
- tcflush(fd, TCIOFLUSH);
-
- return r;
-}
-
-int reset_terminal(const char *name) {
- _cleanup_close_ int fd = -1;
-
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- return reset_terminal_fd(fd, true);
-}
-
-int open_terminal(const char *name, int mode) {
- int fd, r;
- unsigned c = 0;
-
- /*
- * If a TTY is in the process of being closed opening it might
- * cause EIO. This is horribly awful, but unlikely to be
- * changed in the kernel. Hence we work around this problem by
- * retrying a couple of times.
- *
- * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
- */
-
- assert(!(mode & O_CREAT));
-
- for (;;) {
- fd = open(name, mode, 0);
- if (fd >= 0)
- break;
-
- if (errno != EIO)
- return -errno;
-
- /* Max 1s in total */
- if (c >= 20)
- return -errno;
-
- usleep(50 * USEC_PER_MSEC);
- c++;
- }
-
- r = isatty(fd);
- if (r < 0) {
- safe_close(fd);
- return -errno;
- }
-
- if (!r) {
- safe_close(fd);
- return -ENOTTY;
- }
-
- return fd;
-}
-
int flush_fd(int fd) {
struct pollfd pollfd = {
.fd = fd,
@@ -1840,185 +1539,6 @@ int flush_fd(int fd) {
}
}
-int acquire_terminal(
- const char *name,
- bool fail,
- bool force,
- bool ignore_tiocstty_eperm,
- usec_t timeout) {
-
- int fd = -1, notify = -1, r = 0, wd = -1;
- usec_t ts = 0;
-
- assert(name);
-
- /* We use inotify to be notified when the tty is closed. We
- * create the watch before checking if we can actually acquire
- * it, so that we don't lose any event.
- *
- * Note: strictly speaking this actually watches for the
- * device being closed, it does *not* really watch whether a
- * tty loses its controlling process. However, unless some
- * rogue process uses TIOCNOTTY on /dev/tty *after* closing
- * its tty otherwise this will not become a problem. As long
- * as the administrator makes sure not configure any service
- * on the same tty as an untrusted user this should not be a
- * problem. (Which he probably should not do anyway.) */
-
- if (timeout != USEC_INFINITY)
- ts = now(CLOCK_MONOTONIC);
-
- if (!fail && !force) {
- notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
- if (notify < 0) {
- r = -errno;
- goto fail;
- }
-
- wd = inotify_add_watch(notify, name, IN_CLOSE);
- if (wd < 0) {
- r = -errno;
- goto fail;
- }
- }
-
- for (;;) {
- struct sigaction sa_old, sa_new = {
- .sa_handler = SIG_IGN,
- .sa_flags = SA_RESTART,
- };
-
- if (notify >= 0) {
- r = flush_fd(notify);
- if (r < 0)
- goto fail;
- }
-
- /* We pass here O_NOCTTY only so that we can check the return
- * value TIOCSCTTY and have a reliable way to figure out if we
- * successfully became the controlling process of the tty */
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
- * if we already own the tty. */
- assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
-
- /* First, try to get the tty */
- if (ioctl(fd, TIOCSCTTY, force) < 0)
- r = -errno;
-
- assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
-
- /* Sometimes it makes sense to ignore TIOCSCTTY
- * returning EPERM, i.e. when very likely we already
- * are have this controlling terminal. */
- if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
- r = 0;
-
- if (r < 0 && (force || fail || r != -EPERM)) {
- goto fail;
- }
-
- if (r >= 0)
- break;
-
- assert(!fail);
- assert(!force);
- assert(notify >= 0);
-
- for (;;) {
- union inotify_event_buffer buffer;
- struct inotify_event *e;
- ssize_t l;
-
- if (timeout != USEC_INFINITY) {
- usec_t n;
-
- n = now(CLOCK_MONOTONIC);
- if (ts + timeout < n) {
- r = -ETIMEDOUT;
- goto fail;
- }
-
- r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
- if (r < 0)
- goto fail;
-
- if (r == 0) {
- r = -ETIMEDOUT;
- goto fail;
- }
- }
-
- l = read(notify, &buffer, sizeof(buffer));
- if (l < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
-
- r = -errno;
- goto fail;
- }
-
- FOREACH_INOTIFY_EVENT(e, buffer, l) {
- if (e->wd != wd || !(e->mask & IN_CLOSE)) {
- r = -EIO;
- goto fail;
- }
- }
-
- break;
- }
-
- /* We close the tty fd here since if the old session
- * ended our handle will be dead. It's important that
- * we do this after sleeping, so that we don't enter
- * an endless loop. */
- fd = safe_close(fd);
- }
-
- safe_close(notify);
-
- r = reset_terminal_fd(fd, true);
- if (r < 0)
- log_warning_errno(r, "Failed to reset terminal: %m");
-
- return fd;
-
-fail:
- safe_close(fd);
- safe_close(notify);
-
- return r;
-}
-
-int release_terminal(void) {
- static const struct sigaction sa_new = {
- .sa_handler = SIG_IGN,
- .sa_flags = SA_RESTART,
- };
-
- _cleanup_close_ int fd = -1;
- struct sigaction sa_old;
- int r = 0;
-
- fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
- * by our own TIOCNOTTY */
- assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
-
- if (ioctl(fd, TIOCNOTTY) < 0)
- r = -errno;
-
- assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
-
- return r;
-}
-
int sigaction_many(const struct sigaction *sa, ...) {
va_list ap;
int r = 0, sig;
@@ -2303,40 +1823,6 @@ int parse_size(const char *t, off_t base, off_t *size) {
return 0;
}
-int make_stdio(int fd) {
- int r, s, t;
-
- assert(fd >= 0);
-
- r = dup2(fd, STDIN_FILENO);
- s = dup2(fd, STDOUT_FILENO);
- t = dup2(fd, STDERR_FILENO);
-
- if (fd >= 3)
- safe_close(fd);
-
- if (r < 0 || s < 0 || t < 0)
- return -errno;
-
- /* Explicitly unset O_CLOEXEC, since if fd was < 3, then
- * dup2() was a NOP and the bit hence possibly set. */
- fd_cloexec(STDIN_FILENO, false);
- fd_cloexec(STDOUT_FILENO, false);
- fd_cloexec(STDERR_FILENO, false);
-
- return 0;
-}
-
-int make_null_stdio(void) {
- int null_fd;
-
- null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
- if (null_fd < 0)
- return -errno;
-
- return make_stdio(null_fd);
-}
-
bool is_device_path(const char *path) {
/* Returns true on paths that refer to a device, either in
@@ -2460,202 +1946,61 @@ char* gethostname_malloc(void) {
return strdup(u.sysname);
}
-bool hostname_is_set(void) {
- struct utsname u;
-
- assert_se(uname(&u) >= 0);
-
- return !isempty(u.nodename) && !streq(u.nodename, "(none)");
-}
-
-char *lookup_uid(uid_t uid) {
- long bufsize;
- char *name;
- _cleanup_free_ char *buf = NULL;
- struct passwd pwbuf, *pw = NULL;
-
- /* Shortcut things to avoid NSS lookups */
- if (uid == 0)
- return strdup("root");
-
- bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (bufsize <= 0)
- bufsize = 4096;
-
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
-
- if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
- return strdup(pw->pw_name);
-
- if (asprintf(&name, UID_FMT, uid) < 0)
- return NULL;
-
- return name;
-}
-
-char* getlogname_malloc(void) {
- uid_t uid;
- struct stat st;
-
- if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
- uid = st.st_uid;
- else
- uid = getuid();
-
- return lookup_uid(uid);
-}
-
-char *getusername_malloc(void) {
- const char *e;
-
- e = getenv("USER");
- if (e)
- return strdup(e);
-
- return lookup_uid(getuid());
-}
-
-int getttyname_malloc(int fd, char **ret) {
- size_t l = 100;
- int r;
-
- assert(fd >= 0);
- assert(ret);
-
- for (;;) {
- char path[l];
-
- r = ttyname_r(fd, path, sizeof(path));
- if (r == 0) {
- const char *p;
- char *c;
-
- p = startswith(path, "/dev/");
- c = strdup(p ?: path);
- if (!c)
- return -ENOMEM;
-
- *ret = c;
- return 0;
- }
-
- if (r != ERANGE)
- return -r;
-
- l *= 2;
- }
-
- return 0;
-}
-
-int getttyname_harder(int fd, char **r) {
- int k;
- char *s = NULL;
-
- k = getttyname_malloc(fd, &s);
- if (k < 0)
- return k;
-
- if (streq(s, "tty")) {
- free(s);
- return get_ctty(0, NULL, r);
- }
-
- *r = s;
- return 0;
-}
-
-int get_ctty_devnr(pid_t pid, dev_t *d) {
- int r;
- _cleanup_free_ char *line = NULL;
- const char *p;
- unsigned long ttynr;
-
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "stat");
- r = read_one_line_file(p, &line);
- if (r < 0)
- return r;
-
- p = strrchr(line, ')');
- if (!p)
- return -EIO;
-
- p++;
+bool hostname_is_set(void) {
+ struct utsname u;
- if (sscanf(p, " "
- "%*c " /* state */
- "%*d " /* ppid */
- "%*d " /* pgrp */
- "%*d " /* session */
- "%lu ", /* ttynr */
- &ttynr) != 1)
- return -EIO;
+ assert_se(uname(&u) >= 0);
- if (major(ttynr) == 0 && minor(ttynr) == 0)
- return -ENOENT;
+ return !isempty(u.nodename) && !streq(u.nodename, "(none)");
+}
- if (d)
- *d = (dev_t) ttynr;
+char *lookup_uid(uid_t uid) {
+ long bufsize;
+ char *name;
+ _cleanup_free_ char *buf = NULL;
+ struct passwd pwbuf, *pw = NULL;
- return 0;
-}
+ /* Shortcut things to avoid NSS lookups */
+ if (uid == 0)
+ return strdup("root");
-int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
- char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
- _cleanup_free_ char *s = NULL;
- const char *p;
- dev_t devnr;
- int k;
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize <= 0)
+ bufsize = 4096;
- assert(r);
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
- k = get_ctty_devnr(pid, &devnr);
- if (k < 0)
- return k;
+ if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
+ return strdup(pw->pw_name);
- sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
+ if (asprintf(&name, UID_FMT, uid) < 0)
+ return NULL;
- k = readlink_malloc(fn, &s);
- if (k < 0) {
+ return name;
+}
- if (k != -ENOENT)
- return k;
+char* getlogname_malloc(void) {
+ uid_t uid;
+ struct stat st;
- /* This is an ugly hack */
- if (major(devnr) == 136) {
- if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
- return -ENOMEM;
- } else {
- /* Probably something like the ptys which have no
- * symlink in /dev/char. Let's return something
- * vaguely useful. */
+ if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
+ uid = st.st_uid;
+ else
+ uid = getuid();
- b = strdup(fn + 5);
- if (!b)
- return -ENOMEM;
- }
- } else {
- if (startswith(s, "/dev/"))
- p = s + 5;
- else if (startswith(s, "../"))
- p = s + 3;
- else
- p = s;
+ return lookup_uid(uid);
+}
- b = strdup(p);
- if (!b)
- return -ENOMEM;
- }
+char *getusername_malloc(void) {
+ const char *e;
- *r = b;
- if (_devnr)
- *_devnr = devnr;
+ e = getenv("USER");
+ if (e)
+ return strdup(e);
- return 0;
+ return lookup_uid(getuid());
}
bool is_temporary_fs(const struct statfs *s) {
@@ -2738,84 +2083,6 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
}
}
-int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
- static const char status_indent[] = " "; /* "[" STATUS "] " */
- _cleanup_free_ char *s = NULL;
- _cleanup_close_ int fd = -1;
- struct iovec iovec[6] = {};
- int n = 0;
- static bool prev_ephemeral;
-
- assert(format);
-
- /* This is independent of logging, as status messages are
- * optional and go exclusively to the console. */
-
- if (vasprintf(&s, format, ap) < 0)
- return log_oom();
-
- fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- if (ellipse) {
- char *e;
- size_t emax, sl;
- int c;
-
- c = fd_columns(fd);
- if (c <= 0)
- c = 80;
-
- sl = status ? sizeof(status_indent)-1 : 0;
-
- emax = c - sl - 1;
- if (emax < 3)
- emax = 3;
-
- e = ellipsize(s, emax, 50);
- if (e) {
- free(s);
- s = e;
- }
- }
-
- if (prev_ephemeral)
- IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
- prev_ephemeral = ephemeral;
-
- if (status) {
- if (!isempty(status)) {
- IOVEC_SET_STRING(iovec[n++], "[");
- IOVEC_SET_STRING(iovec[n++], status);
- IOVEC_SET_STRING(iovec[n++], "] ");
- } else
- IOVEC_SET_STRING(iovec[n++], status_indent);
- }
-
- IOVEC_SET_STRING(iovec[n++], s);
- if (!ephemeral)
- IOVEC_SET_STRING(iovec[n++], "\n");
-
- if (writev(fd, iovec, n) < 0)
- return -errno;
-
- return 0;
-}
-
-int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
- va_list ap;
- int r;
-
- assert(format);
-
- va_start(ap, format);
- r = status_vprintf(status, ellipse, ephemeral, format, ap);
- va_end(ap);
-
- return r;
-}
-
char *replace_env(const char *format, char **env) {
enum {
WORD,
@@ -2960,89 +2227,6 @@ char **replace_env_argv(char **argv, char **env) {
return ret;
}
-int fd_columns(int fd) {
- struct winsize ws = {};
-
- if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
- return -errno;
-
- if (ws.ws_col <= 0)
- return -EIO;
-
- return ws.ws_col;
-}
-
-unsigned columns(void) {
- const char *e;
- int c;
-
- if (_likely_(cached_columns > 0))
- return cached_columns;
-
- c = 0;
- e = getenv("COLUMNS");
- if (e)
- (void) safe_atoi(e, &c);
-
- if (c <= 0)
- c = fd_columns(STDOUT_FILENO);
-
- if (c <= 0)
- c = 80;
-
- cached_columns = c;
- return cached_columns;
-}
-
-int fd_lines(int fd) {
- struct winsize ws = {};
-
- if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
- return -errno;
-
- if (ws.ws_row <= 0)
- return -EIO;
-
- return ws.ws_row;
-}
-
-unsigned lines(void) {
- const char *e;
- int l;
-
- if (_likely_(cached_lines > 0))
- return cached_lines;
-
- l = 0;
- e = getenv("LINES");
- if (e)
- (void) safe_atoi(e, &l);
-
- if (l <= 0)
- l = fd_lines(STDOUT_FILENO);
-
- if (l <= 0)
- l = 24;
-
- cached_lines = l;
- return cached_lines;
-}
-
-/* intended to be used as a SIGWINCH sighandler */
-void columns_lines_cache_reset(int signum) {
- cached_columns = 0;
- cached_lines = 0;
-}
-
-bool on_tty(void) {
- static int cached_on_tty = -1;
-
- if (_unlikely_(cached_on_tty < 0))
- cached_on_tty = isatty(STDOUT_FILENO) > 0;
-
- return cached_on_tty;
-}
-
int files_same(const char *filea, const char *fileb) {
struct stat a, b;
@@ -3351,101 +2535,6 @@ char *fstab_node_to_udev_node(const char *p) {
return strdup(p);
}
-bool tty_is_vc(const char *tty) {
- assert(tty);
-
- return vtnr_from_tty(tty) >= 0;
-}
-
-bool tty_is_console(const char *tty) {
- assert(tty);
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- return streq(tty, "console");
-}
-
-int vtnr_from_tty(const char *tty) {
- int i, r;
-
- assert(tty);
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- if (!startswith(tty, "tty") )
- return -EINVAL;
-
- if (tty[3] < '0' || tty[3] > '9')
- return -EINVAL;
-
- r = safe_atoi(tty+3, &i);
- if (r < 0)
- return r;
-
- if (i < 0 || i > 63)
- return -EINVAL;
-
- return i;
-}
-
-char *resolve_dev_console(char **active) {
- char *tty;
-
- /* Resolve where /dev/console is pointing to, if /sys is actually ours
- * (i.e. not read-only-mounted which is a sign for container setups) */
-
- if (path_is_read_only_fs("/sys") > 0)
- return NULL;
-
- if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
- return NULL;
-
- /* If multiple log outputs are configured the last one is what
- * /dev/console points to */
- tty = strrchr(*active, ' ');
- if (tty)
- tty++;
- else
- tty = *active;
-
- if (streq(tty, "tty0")) {
- char *tmp;
-
- /* Get the active VC (e.g. tty1) */
- if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
- free(*active);
- tty = *active = tmp;
- }
- }
-
- return tty;
-}
-
-bool tty_is_vc_resolve(const char *tty) {
- _cleanup_free_ char *active = NULL;
-
- assert(tty);
-
- if (startswith(tty, "/dev/"))
- tty += 5;
-
- if (streq(tty, "console")) {
- tty = resolve_dev_console(&active);
- if (!tty)
- return false;
- }
-
- return tty_is_vc(tty);
-}
-
-const char *default_term_for_tty(const char *tty) {
- assert(tty);
-
- return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt220";
-}
-
bool dirent_is_file(const struct dirent *de) {
assert(de);
@@ -3798,94 +2887,6 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
return 0;
}
-int terminal_vhangup_fd(int fd) {
- assert(fd >= 0);
-
- if (ioctl(fd, TIOCVHANGUP) < 0)
- return -errno;
-
- return 0;
-}
-
-int terminal_vhangup(const char *name) {
- _cleanup_close_ int fd;
-
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- return terminal_vhangup_fd(fd);
-}
-
-int vt_disallocate(const char *name) {
- int fd, r;
- unsigned u;
-
- /* Deallocate the VT if possible. If not possible
- * (i.e. because it is the active one), at least clear it
- * entirely (including the scrollback buffer) */
-
- if (!startswith(name, "/dev/"))
- return -EINVAL;
-
- if (!tty_is_vc(name)) {
- /* So this is not a VT. I guess we cannot deallocate
- * it then. But let's at least clear the screen */
-
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- loop_write(fd,
- "\033[r" /* clear scrolling region */
- "\033[H" /* move home */
- "\033[2J", /* clear screen */
- 10, false);
- safe_close(fd);
-
- return 0;
- }
-
- if (!startswith(name, "/dev/tty"))
- return -EINVAL;
-
- r = safe_atou(name+8, &u);
- if (r < 0)
- return r;
-
- if (u <= 0)
- return -EINVAL;
-
- /* Try to deallocate */
- fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- r = ioctl(fd, VT_DISALLOCATE, u);
- safe_close(fd);
-
- if (r >= 0)
- return 0;
-
- if (errno != EBUSY)
- return -errno;
-
- /* Couldn't deallocate, so let's clear it fully with
- * scrollback */
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return fd;
-
- loop_write(fd,
- "\033[r" /* clear scrolling region */
- "\033[H" /* move home */
- "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
- 10, false);
- safe_close(fd);
-
- return 0;
-}
-
int symlink_atomic(const char *from, const char *to) {
_cleanup_free_ char *t = NULL;
int r;
@@ -4898,43 +3899,6 @@ bool in_initrd(void) {
return saved;
}
-void warn_melody(void) {
- _cleanup_close_ int fd = -1;
-
- fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0)
- return;
-
- /* Yeah, this is synchronous. Kinda sucks. But well... */
-
- ioctl(fd, KIOCSOUND, (int)(1193180/440));
- usleep(125*USEC_PER_MSEC);
-
- ioctl(fd, KIOCSOUND, (int)(1193180/220));
- usleep(125*USEC_PER_MSEC);
-
- ioctl(fd, KIOCSOUND, (int)(1193180/220));
- usleep(125*USEC_PER_MSEC);
-
- ioctl(fd, KIOCSOUND, 0);
-}
-
-int make_console_stdio(void) {
- int fd, r;
-
- /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
-
- fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY);
- if (fd < 0)
- return log_error_errno(fd, "Failed to acquire terminal: %m");
-
- r = make_stdio(fd);
- if (r < 0)
- return log_error_errno(r, "Failed to duplicate terminal fd: %m");
-
- return 0;
-}
-
int get_home_dir(char **_h) {
struct passwd *p;
const char *e;
diff --git a/src/shared/util.h b/src/shared/util.h
index 4d5162f..f54722f 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -63,16 +63,6 @@
#define FORMAT_BYTES_MAX 8
-#define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
-#define ANSI_RED_ON "\x1B[31m"
-#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
-#define ANSI_GREEN_ON "\x1B[32m"
-#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m"
-#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
-#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m"
-#define ANSI_HIGHLIGHT_OFF "\x1B[0m"
-#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
-
size_t page_size(void) _pure_;
#define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
@@ -279,10 +269,6 @@ bool hidden_file(const char *filename) _pure_;
bool chars_intersect(const char *a, const char *b) _pure_;
-int make_stdio(int fd);
-int make_null_stdio(void);
-int make_console_stdio(void);
-
/* For basic lookup tables with strictly enumerated entries */
#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
scope const char *name##_to_string(type i) { \
@@ -348,19 +334,6 @@ int close_all_fds(const int except[], unsigned n_except);
bool fstype_is_network(const char *fstype);
-int chvt(int vt);
-
-int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
-int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
-int ask_string(char **ret, const char *text, ...) _printf_(2, 3);
-
-int reset_terminal_fd(int fd, bool switch_to_text);
-int reset_terminal(const char *name);
-
-int open_terminal(const char *name, int mode);
-int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout);
-int release_terminal(void);
-
int flush_fd(int fd);
int ignore_signals(int sig, ...);
@@ -388,12 +361,6 @@ char* gethostname_malloc(void);
char* getlogname_malloc(void);
char* getusername_malloc(void);
-int getttyname_malloc(int fd, char **r);
-int getttyname_harder(int fd, char **r);
-
-int get_ctty_devnr(pid_t pid, dev_t *d);
-int get_ctty(pid_t, dev_t *_devnr, char **r);
-
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
@@ -404,43 +371,8 @@ int pipe_eof(int fd);
cpu_set_t* cpu_set_malloc(unsigned *ncpus);
-int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0);
-int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5);
-
#define xsprintf(buf, fmt, ...) assert_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf))
-int fd_columns(int fd);
-unsigned columns(void);
-int fd_lines(int fd);
-unsigned lines(void);
-void columns_lines_cache_reset(int _unused_ signum);
-
-bool on_tty(void);
-
-static inline const char *ansi_highlight(void) {
- return on_tty() ? ANSI_HIGHLIGHT_ON : "";
-}
-
-static inline const char *ansi_highlight_red(void) {
- return on_tty() ? ANSI_HIGHLIGHT_RED_ON : "";
-}
-
-static inline const char *ansi_highlight_green(void) {
- return on_tty() ? ANSI_HIGHLIGHT_GREEN_ON : "";
-}
-
-static inline const char *ansi_highlight_yellow(void) {
- return on_tty() ? ANSI_HIGHLIGHT_YELLOW_ON : "";
-}
-
-static inline const char *ansi_highlight_blue(void) {
- return on_tty() ? ANSI_HIGHLIGHT_BLUE_ON : "";
-}
-
-static inline const char *ansi_highlight_off(void) {
- return on_tty() ? ANSI_HIGHLIGHT_OFF : "";
-}
-
int files_same(const char *filea, const char *fileb);
int running_in_chroot(void);
@@ -462,13 +394,6 @@ DIR *xopendirat(int dirfd, const char *name, int flags);
char *fstab_node_to_udev_node(const char *p);
-char *resolve_dev_console(char **active);
-bool tty_is_vc(const char *tty);
-bool tty_is_vc_resolve(const char *tty);
-bool tty_is_console(const char *tty) _pure_;
-int vtnr_from_tty(const char *tty);
-const char *default_term_for_tty(const char *tty);
-
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
bool nulstr_contains(const char*nulstr, const char *needle);
@@ -482,10 +407,6 @@ bool machine_name_is_valid(const char *s) _pure_;
char* strshorten(char *s, size_t l);
-int terminal_vhangup_fd(int fd);
-int terminal_vhangup(const char *name);
-
-int vt_disallocate(const char *name);
int symlink_atomic(const char *from, const char *to);
int mknod_atomic(const char *path, mode_t mode, dev_t dev);
@@ -583,8 +504,6 @@ bool http_etag_is_valid(const char *etag);
bool in_initrd(void);
-void warn_melody(void);
-
int get_home_dir(char **ret);
int get_shell(char **_ret);
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index 7fb6fe3..d6c4cc8 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -30,6 +30,7 @@
#include "macro.h"
#include "path-util.h"
#include "utmp-wtmp.h"
+#include "terminal-util.h"
int utmp_get_runlevel(int *runlevel, int *previous) {
struct utmpx *found, lookup = { .ut_type = RUN_LVL };
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 04b7e7b..75d709d 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -71,6 +71,7 @@
#include "efivars.h"
#include "formats-util.h"
#include "process-util.h"
+#include "terminal-util.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
diff --git a/src/test/test-ellipsize.c b/src/test/test-ellipsize.c
index 6a2f9aa..27df908 100644
--- a/src/test/test-ellipsize.c
+++ b/src/test/test-ellipsize.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include "util.h"
+#include "terminal-util.h"
#include "def.h"
static void test_one(const char *p) {
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index a17ef14..1de100c 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -28,6 +28,7 @@
#include "util.h"
#include "macro.h"
#include "virt.h"
+#include "terminal-util.h"
static void test_get_process_comm(void) {
struct stat st;
diff --git a/src/test/test-strip-tab-ansi.c b/src/test/test-strip-tab-ansi.c
index 5016906..3584548 100644
--- a/src/test/test-strip-tab-ansi.c
+++ b/src/test/test-strip-tab-ansi.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include "util.h"
+#include "terminal-util.h"
int main(int argc, char *argv[]) {
char *p;
diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c
new file mode 100644
index 0000000..d81fdb9
--- /dev/null
+++ b/src/test/test-terminal-util.c
@@ -0,0 +1,84 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2013 Thomas H.P. Andersen
+
+ 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 <stdio.h>
+#include <stdbool.h>
+
+#include "terminal-util.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+
+static void test_default_term_for_tty(void) {
+ puts(default_term_for_tty("/dev/tty23"));
+ puts(default_term_for_tty("/dev/ttyS23"));
+ puts(default_term_for_tty("/dev/tty0"));
+ puts(default_term_for_tty("/dev/pty0"));
+ puts(default_term_for_tty("/dev/pts/0"));
+ puts(default_term_for_tty("/dev/console"));
+ puts(default_term_for_tty("tty23"));
+ puts(default_term_for_tty("ttyS23"));
+ puts(default_term_for_tty("tty0"));
+ puts(default_term_for_tty("pty0"));
+ puts(default_term_for_tty("pts/0"));
+ puts(default_term_for_tty("console"));
+}
+
+static void test_read_one_char(void) {
+ _cleanup_fclose_ FILE *file = NULL;
+ char r;
+ bool need_nl;
+ char name[] = "/tmp/test-read_one_char.XXXXXX";
+ int fd;
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+ file = fdopen(fd, "r+");
+ assert_se(file);
+ assert_se(fputs("c\n", file) >= 0);
+ rewind(file);
+
+ assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
+ assert_se(!need_nl);
+ assert_se(r == 'c');
+ assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+ rewind(file);
+ assert_se(fputs("foobar\n", file) >= 0);
+ rewind(file);
+ assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+ rewind(file);
+ assert_se(fputs("\n", file) >= 0);
+ rewind(file);
+ assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+ unlink(name);
+}
+
+int main(int argc, char *argv[]) {
+ log_parse_environment();
+ log_open();
+
+ test_default_term_for_tty();
+ test_read_one_char();
+
+ return 0;
+}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index bfd4df9..fdb772d 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -522,21 +522,6 @@ static void test_foreach_word_quoted(void) {
true);
}
-static void test_default_term_for_tty(void) {
- puts(default_term_for_tty("/dev/tty23"));
- puts(default_term_for_tty("/dev/ttyS23"));
- puts(default_term_for_tty("/dev/tty0"));
- puts(default_term_for_tty("/dev/pty0"));
- puts(default_term_for_tty("/dev/pts/0"));
- puts(default_term_for_tty("/dev/console"));
- puts(default_term_for_tty("tty23"));
- puts(default_term_for_tty("ttyS23"));
- puts(default_term_for_tty("tty0"));
- puts(default_term_for_tty("pty0"));
- puts(default_term_for_tty("pts/0"));
- puts(default_term_for_tty("console"));
-}
-
static void test_memdup_multiply(void) {
int org[] = {1, 2, 3};
int *dup;
@@ -981,38 +966,6 @@ static void test_readlink_and_make_absolute(void) {
assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
-static void test_read_one_char(void) {
- _cleanup_fclose_ FILE *file = NULL;
- char r;
- bool need_nl;
- char name[] = "/tmp/test-read_one_char.XXXXXX";
- int fd;
-
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
- file = fdopen(fd, "r+");
- assert_se(file);
- assert_se(fputs("c\n", file) >= 0);
- rewind(file);
-
- assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
- assert_se(!need_nl);
- assert_se(r == 'c');
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
-
- rewind(file);
- assert_se(fputs("foobar\n", file) >= 0);
- rewind(file);
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
-
- rewind(file);
- assert_se(fputs("\n", file) >= 0);
- rewind(file);
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
-
- unlink(name);
-}
-
static void test_ignore_signals(void) {
assert_se(ignore_signals(SIGINT, -1) >= 0);
assert_se(kill(getpid(), SIGINT) >= 0);
@@ -1525,7 +1478,6 @@ int main(int argc, char *argv[]) {
test_cunescape();
test_foreach_word();
test_foreach_word_quoted();
- test_default_term_for_tty();
test_memdup_multiply();
test_hostname_is_valid();
test_u64log2();
@@ -1552,7 +1504,6 @@ int main(int argc, char *argv[]) {
test_close_nointr();
test_unlink_noerrno();
test_readlink_and_make_absolute();
- test_read_one_char();
test_ignore_signals();
test_strshorten();
test_strjoina();
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 0a41f05..61b6e76 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -33,6 +33,7 @@
#include "build.h"
#include "strv.h"
#include "pager.h"
+#include "terminal-util.h"
static bool arg_no_pager = false;
static bool arg_ask_password = true;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 8f4031a..8cd6cab 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -43,6 +43,7 @@
#include "build.h"
#include "def.h"
#include "process-util.h"
+#include "terminal-util.h"
static enum {
ACTION_LIST,
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index 3f93524..6c782b3 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -36,6 +36,7 @@
#include "virt.h"
#include "fileio.h"
#include "process-util.h"
+#include "terminal-util.h"
static bool is_vconsole(int fd) {
unsigned char data[1];
commit 3df3e884ae1237ef0d4d23b0e80f4ffda95ac135
Author: Ronny Chevalier <chevalier.ronny at gmail.com>
Date: Fri Apr 10 22:27:10 2015 +0200
shared: add random-util.[ch]
diff --git a/Makefile.am b/Makefile.am
index ceb1d7d..f348ef9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -901,6 +901,8 @@ libsystemd_shared_la_SOURCES = \
src/shared/memfd-util.h \
src/shared/process-util.c \
src/shared/process-util.h \
+ src/shared/random-util.c \
+ src/shared/random-util.h \
src/shared/uid-range.c \
src/shared/uid-range.h \
src/shared/nss-util.h \
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index a37ca17..c92f379 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -32,6 +32,7 @@
#include "mkdir.h"
#include "time-util.h"
#include "path-util.h"
+#include "random-util.h"
#include "locale-util.h"
#include "ask-password-api.h"
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 6bbcc6d..a432eb0 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -34,6 +34,7 @@
#include "journal-authenticate.h"
#include "lookup3.h"
#include "compress.h"
+#include "random-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem))
diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
index 6d779d2..6f83035 100644
--- a/src/journal/journald-rate-limit.c
+++ b/src/journal/journald-rate-limit.c
@@ -26,6 +26,7 @@
#include "list.h"
#include "util.h"
#include "hashmap.h"
+#include "random-util.h"
#define POOLS_MAX 5
#define BUCKETS_MAX 127
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
index ae41c0c..41a566d 100644
--- a/src/journal/test-compress.c
+++ b/src/journal/test-compress.c
@@ -20,6 +20,7 @@
#include "compress.h"
#include "util.h"
#include "macro.h"
+#include "random-util.h"
#ifdef HAVE_XZ
# define XZ_OK 0
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 4224e01..c44392e 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -28,6 +28,7 @@
#include "util.h"
#include "refcnt.h"
+#include "random-util.h"
#include "async.h"
#include "dhcp-protocol.h"
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 3db1cb0..9d88d46 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -28,6 +28,7 @@
#include "udev-util.h"
#include "util.h"
#include "refcnt.h"
+#include "random-util.h"
#include "network-internal.h"
#include "sd-dhcp6-client.h"
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 02f2f9e..9e04db9 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -27,6 +27,7 @@
#include "siphash24.h"
#include "list.h"
#include "refcnt.h"
+#include "random-util.h"
#include "ipv4ll-internal.h"
#include "sd-ipv4ll.h"
diff --git a/src/libsystemd-network/sd-pppoe.c b/src/libsystemd-network/sd-pppoe.c
index 601f3bd..1de8a5e 100644
--- a/src/libsystemd-network/sd-pppoe.c
+++ b/src/libsystemd-network/sd-pppoe.c
@@ -33,6 +33,7 @@
#include "event-util.h"
#include "util.h"
+#include "random-util.h"
#include "socket-util.h"
#include "async.h"
#include "refcnt.h"
diff --git a/src/libsystemd-terminal/modeset.c b/src/libsystemd-terminal/modeset.c
index cccaaba..621d6c4 100644
--- a/src/libsystemd-terminal/modeset.c
+++ b/src/libsystemd-terminal/modeset.c
@@ -40,11 +40,13 @@
#include <systemd/sd-login.h>
#include <termios.h>
#include <unistd.h>
+
#include "build.h"
#include "grdev.h"
#include "macro.h"
#include "sysview.h"
#include "util.h"
+#include "random-util.h"
typedef struct Modeset Modeset;
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index f0ffedc..46f2181 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -26,6 +26,7 @@
#include "util.h"
#include "macro.h"
#include "sd-id128.h"
+#include "random-util.h"
_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) {
unsigned n;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 9607532..6417a8c 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -52,6 +52,7 @@
#include <blkid/blkid.h>
#endif
+#include "random-util.h"
#include "sd-daemon.h"
#include "sd-bus.h"
#include "sd-id128.h"
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index ba116de..b2bc092 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -27,6 +27,7 @@
#include "af-list.h"
#include "resolved-dns-domain.h"
#include "resolved-dns-scope.h"
+#include "random-util.h"
#define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
#define MULTICAST_RATELIMIT_BURST 1000
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index bc1a90d..2149389 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -22,6 +22,7 @@
#include "af-list.h"
#include "resolved-dns-transaction.h"
+#include "random-util.h"
DnsTransaction* dns_transaction_free(DnsTransaction *t) {
DnsQuery *q;
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index adaa6c6..a10a327 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -31,6 +31,7 @@
#include "utf8.h"
#include "fileio-label.h"
#include "ordered-set.h"
+#include "random-util.h"
#include "resolved-dns-domain.h"
#include "resolved-conf.h"
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index dfc89d2..ad1a773 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -35,6 +35,7 @@
#include "formats-util.h"
#include "mkdir.h"
#include "strv.h"
+#include "random-util.h"
#include "ask-password-api.h"
diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c
index 48d7502..d8ea9d5 100644
--- a/src/shared/hashmap.c
+++ b/src/shared/hashmap.c
@@ -30,6 +30,7 @@
#include "siphash24.h"
#include "strv.h"
#include "mempool.h"
+#include "random-util.h"
#ifdef ENABLE_DEBUG_HASHMAP
#include "list.h"
diff --git a/src/shared/random-util.c b/src/shared/random-util.c
new file mode 100644
index 0000000..88f5182
--- /dev/null
+++ b/src/shared/random-util.c
@@ -0,0 +1,127 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/auxv.h>
+#include <linux/random.h>
+
+#include "random-util.h"
+#include "time-util.h"
+#include "missing.h"
+#include "util.h"
+
+int dev_urandom(void *p, size_t n) {
+ static int have_syscall = -1;
+
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ /* Gathers some randomness from the kernel. This call will
+ * never block, and will always return some data from the
+ * kernel, regardless if the random pool is fully initialized
+ * or not. It thus makes no guarantee for the quality of the
+ * returned entropy, but is good enough for or usual usecases
+ * of seeding the hash functions for hashtable */
+
+ /* Use the getrandom() syscall unless we know we don't have
+ * it, or when the requested size is too large for it. */
+ if (have_syscall != 0 || (size_t) (int) n != n) {
+ r = getrandom(p, n, GRND_NONBLOCK);
+ if (r == (int) n) {
+ have_syscall = true;
+ return 0;
+ }
+
+ if (r < 0) {
+ if (errno == ENOSYS)
+ /* we lack the syscall, continue with
+ * reading from /dev/urandom */
+ have_syscall = false;
+ else if (errno == EAGAIN)
+ /* not enough entropy for now. Let's
+ * remember to use the syscall the
+ * next time, again, but also read
+ * from /dev/urandom for now, which
+ * doesn't care about the current
+ * amount of entropy. */
+ have_syscall = true;
+ else
+ return -errno;
+ } else
+ /* too short read? */
+ return -ENODATA;
+ }
+
+ fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return errno == ENOENT ? -ENOSYS : -errno;
+
+ return loop_read_exact(fd, p, n, true);
+}
+
+void initialize_srand(void) {
+ static bool srand_called = false;
+ unsigned x;
+#ifdef HAVE_SYS_AUXV_H
+ void *auxv;
+#endif
+
+ if (srand_called)
+ return;
+
+ x = 0;
+
+#ifdef HAVE_SYS_AUXV_H
+ /* The kernel provides us with a bit of entropy in auxv, so
+ * let's try to make use of that to seed the pseudo-random
+ * generator. It's better than nothing... */
+
+ auxv = (void*) getauxval(AT_RANDOM);
+ if (auxv)
+ x ^= *(unsigned*) auxv;
+#endif
+
+ x ^= (unsigned) now(CLOCK_REALTIME);
+ x ^= (unsigned) gettid();
+
+ srand(x);
+ srand_called = true;
+}
+
+void random_bytes(void *p, size_t n) {
+ uint8_t *q;
+ int r;
+
+ r = dev_urandom(p, n);
+ if (r >= 0)
+ return;
+
+ /* If some idiot made /dev/urandom unavailable to us, he'll
+ * get a PRNG instead. */
+
+ initialize_srand();
+
+ for (q = p; q < (uint8_t*) p + n; q ++)
+ *q = rand();
+}
diff --git a/src/shared/random-util.h b/src/shared/random-util.h
new file mode 100644
index 0000000..f7862c8
--- /dev/null
+++ b/src/shared/random-util.h
@@ -0,0 +1,38 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <stdint.h>
+
+int dev_urandom(void *p, size_t n);
+void random_bytes(void *p, size_t n);
+void initialize_srand(void);
+
+static inline uint64_t random_u64(void) {
+ uint64_t u;
+ random_bytes(&u, sizeof(u));
+ return u;
+}
+
+static inline uint32_t random_u32(void) {
+ uint32_t u;
+ random_bytes(&u, sizeof(u));
+ return u;
+}
diff --git a/src/shared/util.c b/src/shared/util.c
index d4753f1..e4c4dd9 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -94,6 +94,7 @@
#include "sparse-endian.h"
#include "formats-util.h"
#include "process-util.h"
+#include "random-util.h"
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
@@ -2387,101 +2388,6 @@ char* dirname_malloc(const char *path) {
return dir;
}
-int dev_urandom(void *p, size_t n) {
- static int have_syscall = -1;
-
- _cleanup_close_ int fd = -1;
- int r;
-
- /* Gathers some randomness from the kernel. This call will
- * never block, and will always return some data from the
- * kernel, regardless if the random pool is fully initialized
- * or not. It thus makes no guarantee for the quality of the
- * returned entropy, but is good enough for or usual usecases
- * of seeding the hash functions for hashtable */
-
- /* Use the getrandom() syscall unless we know we don't have
- * it, or when the requested size is too large for it. */
- if (have_syscall != 0 || (size_t) (int) n != n) {
- r = getrandom(p, n, GRND_NONBLOCK);
- if (r == (int) n) {
- have_syscall = true;
- return 0;
- }
-
- if (r < 0) {
- if (errno == ENOSYS)
- /* we lack the syscall, continue with
- * reading from /dev/urandom */
- have_syscall = false;
- else if (errno == EAGAIN)
- /* not enough entropy for now. Let's
- * remember to use the syscall the
- * next time, again, but also read
- * from /dev/urandom for now, which
- * doesn't care about the current
- * amount of entropy. */
- have_syscall = true;
- else
- return -errno;
- } else
- /* too short read? */
- return -ENODATA;
- }
-
- fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0)
- return errno == ENOENT ? -ENOSYS : -errno;
-
- return loop_read_exact(fd, p, n, true);
-}
-
-void initialize_srand(void) {
- static bool srand_called = false;
- unsigned x;
-#ifdef HAVE_SYS_AUXV_H
- void *auxv;
-#endif
-
- if (srand_called)
- return;
-
- x = 0;
-
-#ifdef HAVE_SYS_AUXV_H
- /* The kernel provides us with a bit of entropy in auxv, so
- * let's try to make use of that to seed the pseudo-random
- * generator. It's better than nothing... */
-
- auxv = (void*) getauxval(AT_RANDOM);
- if (auxv)
- x ^= *(unsigned*) auxv;
-#endif
-
- x ^= (unsigned) now(CLOCK_REALTIME);
- x ^= (unsigned) gettid();
-
- srand(x);
- srand_called = true;
-}
-
-void random_bytes(void *p, size_t n) {
- uint8_t *q;
- int r;
-
- r = dev_urandom(p, n);
- if (r >= 0)
- return;
-
- /* If some idiot made /dev/urandom unavailable to us, he'll
- * get a PRNG instead. */
-
- initialize_srand();
-
- for (q = p; q < (uint8_t*) p + n; q ++)
- *q = rand();
-}
-
void rename_process(const char name[8]) {
assert(name);
diff --git a/src/shared/util.h b/src/shared/util.h
index b939d7f..4d5162f 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -283,22 +283,6 @@ int make_stdio(int fd);
int make_null_stdio(void);
int make_console_stdio(void);
-int dev_urandom(void *p, size_t n);
-void random_bytes(void *p, size_t n);
-void initialize_srand(void);
-
-static inline uint64_t random_u64(void) {
- uint64_t u;
- random_bytes(&u, sizeof(u));
- return u;
-}
-
-static inline uint32_t random_u32(void) {
- uint32_t u;
- random_bytes(&u, sizeof(u));
- return u;
-}
-
/* For basic lookup tables with strictly enumerated entries */
#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \
scope const char *name##_to_string(type i) { \
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index 54a5075..3d74ae5 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -36,6 +36,7 @@
#include "libudev.h"
#include "libudev-private.h"
+#include "random-util.h"
/* device info */
static unsigned int cd_cd_rom;
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 86d09bb..00052dd 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -37,6 +37,7 @@
#include "conf-files.h"
#include "rtnl-util.h"
#include "network-internal.h"
+#include "random-util.h"
struct link_config_ctx {
LIST_HEAD(link_config, links);
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
index dcfff1d..3691a69 100644
--- a/src/udev/scsi_id/scsi_serial.c
+++ b/src/udev/scsi_id/scsi_serial.c
@@ -37,6 +37,7 @@
#include "libudev-private.h"
#include "scsi.h"
#include "scsi_id.h"
+#include "random-util.h"
/*
* A priority based list of id, naa, and binary/ascii for the identifier
commit 0b452006de98294d1690f045f6ea2f7f6630ec3b
Author: Ronny Chevalier <chevalier.ronny at gmail.com>
Date: Fri Apr 10 19:10:00 2015 +0200
shared: add process-util.[ch]
diff --git a/.gitignore b/.gitignore
index 875ada5..7330c80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -234,6 +234,7 @@
/test-path-util
/test-pppoe
/test-prioq
+/test-process-util
/test-pty
/test-qcow2
/test-ratelimit
diff --git a/Makefile.am b/Makefile.am
index 0a57389..ceb1d7d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -899,6 +899,8 @@ libsystemd_shared_la_SOURCES = \
src/shared/base-filesystem.h \
src/shared/memfd-util.c \
src/shared/memfd-util.h \
+ src/shared/process-util.c \
+ src/shared/process-util.h \
src/shared/uid-range.c \
src/shared/uid-range.h \
src/shared/nss-util.h \
@@ -1389,6 +1391,7 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-process-util \
test-path-lookup \
test-ring \
test-barrier \
@@ -1664,6 +1667,12 @@ test_util_LDADD = \
libsystemd-label.la \
libsystemd-shared.la
+test_process_util_SOURCES = \
+ src/test/test-process-util.c
+
+test_process_util_LDADD = \
+ libsystemd-shared.la
+
test_path_lookup_SOURCES = \
src/test/test-path-lookup.c
diff --git a/src/core/automount.c b/src/core/automount.c
index e1ca2a4..ce484ff 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -41,6 +41,7 @@
#include "bus-util.h"
#include "bus-error.h"
#include "formats-util.h"
+#include "process-util.h"
static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
[AUTOMOUNT_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 6b8abb4..e337c0f 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -22,6 +22,7 @@
#include <fcntl.h>
#include <fnmatch.h>
+#include "process-util.h"
#include "path-util.h"
#include "special.h"
#include "cgroup-util.h"
diff --git a/src/core/execute.c b/src/core/execute.c
index c87e900..b00d510 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -77,6 +77,7 @@
#include "bus-endpoint.h"
#include "cap-list.h"
#include "formats-util.h"
+#include "process-util.h"
#ifdef HAVE_APPARMOR
#include "apparmor-util.h"
diff --git a/src/core/killall.c b/src/core/killall.c
index 5040514..31bec01 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -28,6 +28,7 @@
#include "killall.h"
#include "set.h"
#include "formats-util.h"
+#include "process-util.h"
#define TIMEOUT_USEC (10 * USEC_PER_SEC)
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index 2ffb2a7..e083c5b 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -36,6 +36,7 @@
#include "virt.h"
#include "fileio.h"
#include "path-util.h"
+#include "process-util.h"
static int shorten_uuid(char destination[34], const char source[36]) {
unsigned i, j;
diff --git a/src/core/main.c b/src/core/main.c
index 5d1aed8..80a51ee 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -73,6 +73,7 @@
#include "smack-setup.h"
#include "kmod-setup.h"
#include "formats-util.h"
+#include "process-util.h"
static enum {
ACTION_RUN,
diff --git a/src/core/manager.c b/src/core/manager.c
index 1c912fc..6d1729b 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -71,6 +71,7 @@
#include "dbus-manager.h"
#include "bus-kernel.h"
#include "time-util.h"
+#include "process-util.h"
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
diff --git a/src/core/service.c b/src/core/service.c
index c6ea655..fa818fc 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -46,6 +46,7 @@
#include "bus-util.h"
#include "bus-kernel.h"
#include "formats-util.h"
+#include "process-util.h"
static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 70a461e..f037a38 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -42,6 +42,7 @@
#include "cgroup-util.h"
#include "def.h"
#include "switch-root.h"
+#include "process-util.h"
#define FINALIZE_ATTEMPTS 50
diff --git a/src/core/unit.c b/src/core/unit.c
index 4b9c406..3aa1bf2 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -47,6 +47,7 @@
#include "execute.h"
#include "dropin.h"
#include "formats-util.h"
+#include "process-util.h"
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 9f1f8f3..106c036 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -32,6 +32,7 @@
#include "pager.h"
#include "build.h"
#include "strv.h"
+#include "process-util.h"
static const char prefixes[] =
"/etc\0"
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 7eaf902..6a0f67f 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -32,6 +32,7 @@
#include "sd-device.h"
#include "util.h"
+#include "process-util.h"
#include "special.h"
#include "bus-util.h"
#include "bus-error.h"
diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c
index f8f5fb3..0f59f5a 100644
--- a/src/getty-generator/getty-generator.c
+++ b/src/getty-generator/getty-generator.c
@@ -31,6 +31,7 @@
#include "virt.h"
#include "fileio.h"
#include "path-util.h"
+#include "process-util.h"
static const char *arg_dest = "/tmp";
diff --git a/src/import/export-tar.c b/src/import/export-tar.c
index 9bd0251..73e1fae 100644
--- a/src/import/export-tar.c
+++ b/src/import/export-tar.c
@@ -27,6 +27,7 @@
#include "btrfs-util.h"
#include "import-common.h"
#include "export-tar.h"
+#include "process-util.h"
#define COPY_BUFFER_SIZE (16*1024)
diff --git a/src/import/import-tar.c b/src/import/import-tar.c
index 6ec5504..12701bf 100644
--- a/src/import/import-tar.c
+++ b/src/import/import-tar.c
@@ -35,6 +35,7 @@
#include "import-compress.h"
#include "import-common.h"
#include "import-tar.h"
+#include "process-util.h"
struct TarImport {
sd_event *event;
diff --git a/src/import/importd.c b/src/import/importd.c
index 998e960..d4da4b2 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -33,6 +33,7 @@
#include "machine-pool.h"
#include "path-util.h"
#include "import-util.h"
+#include "process-util.h"
typedef struct Transfer Transfer;
typedef struct Manager Manager;
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index 5732353..59091ba 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -29,6 +29,7 @@
#include "capability.h"
#include "pull-job.h"
#include "pull-common.h"
+#include "process-util.h"
#define FILENAME_ESCAPE "/.#\"\'"
diff --git a/src/import/pull-dkr.c b/src/import/pull-dkr.c
index c922bac..0eefec5 100644
--- a/src/import/pull-dkr.c
+++ b/src/import/pull-dkr.c
@@ -37,6 +37,7 @@
#include "pull-common.h"
#include "import-common.h"
#include "pull-dkr.h"
+#include "process-util.h"
typedef enum DkrProgress {
DKR_SEARCHING,
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 0efa07d..27a9af8 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -38,6 +38,7 @@
#include "pull-job.h"
#include "pull-common.h"
#include "pull-tar.h"
+#include "process-util.h"
typedef enum TarProgress {
TAR_DOWNLOADING,
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 4e23e48..1c747aa 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -48,6 +48,7 @@
#include "capability.h"
#include "journald-native.h"
#include "coredump-vacuum.h"
+#include "process-util.h"
/* The maximum size up to which we process coredumps */
#define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU))
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
index 4026a1c..4f6ddfa 100644
--- a/src/journal/coredumpctl.c
+++ b/src/journal/coredumpctl.c
@@ -37,6 +37,7 @@
#include "journal-internal.h"
#include "compress.h"
#include "sigbus.h"
+#include "process-util.h"
static enum {
ACTION_NONE,
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index 4ccacd7..6c15530 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -27,6 +27,7 @@
#include "journald-server.h"
#include "journald-console.h"
#include "formats-util.h"
+#include "process-util.h"
static bool prefix_timestamp(void) {
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index cb4bc38..e5be7f7 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -32,6 +32,7 @@
#include "journald-kmsg.h"
#include "journald-syslog.h"
#include "formats-util.h"
+#include "process-util.h"
void server_forward_kmsg(
Server *s,
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 7e20b96..5e07ce3 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -51,6 +51,7 @@
#include "journald-server.h"
#include "acl-util.h"
#include "formats-util.h"
+#include "process-util.h"
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 6c46a30..26fdf62 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -32,6 +32,7 @@
#include "journald-console.h"
#include "journald-wall.h"
#include "formats-util.h"
+#include "process-util.h"
/* Warn once every 30s if we missed syslog message */
#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
index b4e0717..5298e45 100644
--- a/src/journal/journald-wall.c
+++ b/src/journal/journald-wall.c
@@ -23,6 +23,7 @@
#include "journald-server.h"
#include "journald-wall.h"
#include "formats-util.h"
+#include "process-util.h"
void server_forward_wall(
Server *s,
diff --git a/src/libsystemd-network/test-pppoe.c b/src/libsystemd-network/test-pppoe.c
index 40d04fd..9c8d6f7 100644
--- a/src/libsystemd-network/test-pppoe.c
+++ b/src/libsystemd-network/test-pppoe.c
@@ -31,6 +31,7 @@
#include "event-util.h"
#include "sd-rtnl.h"
#include "sd-pppoe.h"
+#include "process-util.h"
static void pppoe_handler(sd_pppoe *ppp, int event, void *userdata) {
static int pppoe_state = -1;
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 3b3a5d3..f157c25 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include "util.h"
+#include "process-util.h"
#include "bus-internal.h"
#include "bus-socket.h"
#include "bus-container.h"
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 4141cc3..a5d3574 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -24,6 +24,7 @@
#include "util.h"
#include "formats-util.h"
+#include "process-util.h"
#include "capability.h"
#include "cgroup-util.h"
#include "fileio.h"
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index 1f78e4b..57cfb5d 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -32,6 +32,7 @@
#include "build.h"
#include "strv.h"
#include "formats-util.h"
+#include "process-util.h"
static const char* arg_what = "idle:sleep:shutdown";
static const char* arg_who = NULL;
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index ec102ae..7393eb3 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -41,6 +41,7 @@
#include "cgroup-util.h"
#include "spawn-polkit-agent.h"
#include "verbs.h"
+#include "process-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index d7ae175..29e7ed0 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -28,6 +28,7 @@
#include "bus-error.h"
#include "logind-action.h"
#include "formats-util.h"
+#include "process-util.h"
int manager_handle_action(
Manager *m,
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 45aedad..6bf9205 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -41,6 +41,7 @@
#include "efivars.h"
#include "logind.h"
#include "formats-util.h"
+#include "process-util.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 6cc46af..2d710a9 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -43,6 +43,7 @@
#include "machine.h"
#include "machine-dbus.h"
#include "formats-util.h"
+#include "process-util.h"
static int property_get_id(
sd_bus *bus,
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 688c510..87e15d7 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -52,6 +52,7 @@
#include "copy.h"
#include "verbs.h"
#include "import-util.h"
+#include "process-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 8ec6743..9607532 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -92,6 +92,7 @@
#include "fw-util.h"
#include "local-addresses.h"
#include "formats-util.h"
+#include "process-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
index 819706a..a729f59 100644
--- a/src/quotacheck/quotacheck.c
+++ b/src/quotacheck/quotacheck.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include "util.h"
+#include "process-util.h"
static bool arg_skip = false;
static bool arg_force = false;
diff --git a/src/shared/audit.c b/src/shared/audit.c
index 4c1496f..84181d3 100644
--- a/src/shared/audit.c
+++ b/src/shared/audit.c
@@ -25,6 +25,7 @@
#include "macro.h"
#include "audit.h"
#include "util.h"
+#include "process-util.h"
#include "fileio.h"
int audit_session_from_pid(pid_t pid, uint32_t *id) {
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index fed72ac..0f263e9 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -26,6 +26,7 @@
#include "util.h"
#include "formats-util.h"
+#include "process-util.h"
#include "macro.h"
#include "path-util.h"
#include "cgroup-util.h"
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 481708f..5b04702 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -34,6 +34,7 @@
#include "macro.h"
#include "util.h"
#include "formats-util.h"
+#include "process-util.h"
#include "path-util.h"
#include "unit-name.h"
#include "fileio.h"
diff --git a/src/shared/log.c b/src/shared/log.c
index 32ec581..7edcf1f 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -35,6 +35,7 @@
#include "macro.h"
#include "socket-util.h"
#include "formats-util.h"
+#include "process-util.h"
#define SNDBUF_SIZE (8*1024*1024)
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index e179b8a..7a7a1e9 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -32,6 +32,7 @@
#include "hashmap.h"
#include "journal-internal.h"
#include "formats-util.h"
+#include "process-util.h"
/* up to three lines (each up to 100 characters),
or 300 characters, whichever is less */
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
index 0fae623..41aa1b7 100644
--- a/src/shared/machine-pool.c
+++ b/src/shared/machine-pool.c
@@ -25,6 +25,7 @@
#include <sys/mount.h>
#include "util.h"
+#include "process-util.h"
#include "mkdir.h"
#include "btrfs-util.h"
#include "path-util.h"
diff --git a/src/shared/pager.c b/src/shared/pager.c
index f12bfb3..b5a584b 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -27,6 +27,7 @@
#include "pager.h"
#include "util.h"
+#include "process-util.h"
#include "macro.h"
static pid_t pager_pid = 0;
diff --git a/src/shared/process-util.c b/src/shared/process-util.c
new file mode 100644
index 0000000..92a69f5
--- /dev/null
+++ b/src/shared/process-util.c
@@ -0,0 +1,538 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <stdbool.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include "process-util.h"
+#include "fileio.h"
+#include "util.h"
+#include "log.h"
+
+int get_process_state(pid_t pid) {
+ const char *p;
+ char state;
+ int r;
+ _cleanup_free_ char *line = NULL;
+
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "stat");
+ r = read_one_line_file(p, &line);
+ if (r < 0)
+ return r;
+
+ p = strrchr(line, ')');
+ if (!p)
+ return -EIO;
+
+ p++;
+
+ if (sscanf(p, " %c", &state) != 1)
+ return -EIO;
+
+ return (unsigned char) state;
+}
+
+int get_process_comm(pid_t pid, char **name) {
+ const char *p;
+ int r;
+
+ assert(name);
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "comm");
+
+ r = read_one_line_file(p, name);
+ if (r == -ENOENT)
+ return -ESRCH;
+
+ return r;
+}
+
+int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char *r = NULL, *k;
+ const char *p;
+ int c;
+
+ assert(line);
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "cmdline");
+
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ if (max_length == 0) {
+ size_t len = 0, allocated = 0;
+
+ while ((c = getc(f)) != EOF) {
+
+ if (!GREEDY_REALLOC(r, allocated, len+2)) {
+ free(r);
+ return -ENOMEM;
+ }
+
+ r[len++] = isprint(c) ? c : ' ';
+ }
+
+ if (len > 0)
+ r[len-1] = 0;
+
+ } else {
+ bool space = false;
+ size_t left;
+
+ r = new(char, max_length);
+ if (!r)
+ return -ENOMEM;
+
+ k = r;
+ left = max_length;
+ while ((c = getc(f)) != EOF) {
+
+ if (isprint(c)) {
+ if (space) {
+ if (left <= 4)
+ break;
+
+ *(k++) = ' ';
+ left--;
+ space = false;
+ }
+
+ if (left <= 4)
+ break;
+
+ *(k++) = (char) c;
+ left--;
+ } else
+ space = true;
+ }
+
+ if (left <= 4) {
+ size_t n = MIN(left-1, 3U);
+ memcpy(k, "...", n);
+ k[n] = 0;
+ } else
+ *k = 0;
+ }
+
+ /* Kernel threads have no argv[] */
+ if (isempty(r)) {
+ _cleanup_free_ char *t = NULL;
+ int h;
+
+ free(r);
+
+ if (!comm_fallback)
+ return -ENOENT;
+
+ h = get_process_comm(pid, &t);
+ if (h < 0)
+ return h;
+
+ r = strjoin("[", t, "]", NULL);
+ if (!r)
+ return -ENOMEM;
+ }
+
+ *line = r;
+ return 0;
+}
+
+int is_kernel_thread(pid_t pid) {
+ const char *p;
+ size_t count;
+ char c;
+ bool eof;
+ FILE *f;
+
+ if (pid == 0)
+ return 0;
+
+ assert(pid > 0);
+
+ p = procfs_file_alloca(pid, "cmdline");
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ count = fread(&c, 1, 1, f);
+ eof = feof(f);
+ fclose(f);
+
+ /* Kernel threads have an empty cmdline */
+
+ if (count <= 0)
+ return eof ? 1 : -errno;
+
+ return 0;
+}
+
+int get_process_capeff(pid_t pid, char **capeff) {
+ const char *p;
+
+ assert(capeff);
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "status");
+
+ return get_status_field(p, "\nCapEff:", capeff);
+}
+
+static int get_process_link_contents(const char *proc_file, char **name) {
+ int r;
+
+ assert(proc_file);
+ assert(name);
+
+ r = readlink_malloc(proc_file, name);
+ if (r < 0)
+ return r == -ENOENT ? -ESRCH : r;
+
+ return 0;
+}
+
+int get_process_exe(pid_t pid, char **name) {
+ const char *p;
+ char *d;
+ int r;
+
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "exe");
+ r = get_process_link_contents(p, name);
+ if (r < 0)
+ return r;
+
+ d = endswith(*name, " (deleted)");
+ if (d)
+ *d = '\0';
+
+ return 0;
+}
+
+static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char line[LINE_MAX];
+ const char *p;
+
+ assert(field);
+ assert(uid);
+
+ if (pid == 0)
+ return getuid();
+
+ p = procfs_file_alloca(pid, "status");
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ FOREACH_LINE(line, f, return -errno) {
+ char *l;
+
+ l = strstrip(line);
+
+ if (startswith(l, field)) {
+ l += strlen(field);
+ l += strspn(l, WHITESPACE);
+
+ l[strcspn(l, WHITESPACE)] = 0;
+
+ return parse_uid(l, uid);
+ }
+ }
+
+ return -EIO;
+}
+
+int get_process_uid(pid_t pid, uid_t *uid) {
+ return get_process_id(pid, "Uid:", uid);
+}
+
+int get_process_gid(pid_t pid, gid_t *gid) {
+ assert_cc(sizeof(uid_t) == sizeof(gid_t));
+ return get_process_id(pid, "Gid:", gid);
+}
+
+int get_process_cwd(pid_t pid, char **cwd) {
+ const char *p;
+
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "cwd");
+
+ return get_process_link_contents(p, cwd);
+}
+
+int get_process_root(pid_t pid, char **root) {
+ const char *p;
+
+ assert(pid >= 0);
+
+ p = procfs_file_alloca(pid, "root");
+
+ return get_process_link_contents(p, root);
+}
+
+int get_process_environ(pid_t pid, char **env) {
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_free_ char *outcome = NULL;
+ int c;
+ const char *p;
+ size_t allocated = 0, sz = 0;
+
+ assert(pid >= 0);
+ assert(env);
+
+ p = procfs_file_alloca(pid, "environ");
+
+ f = fopen(p, "re");
+ if (!f)
+ return -errno;
+
+ while ((c = fgetc(f)) != EOF) {
+ if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
+ return -ENOMEM;
+
+ if (c == '\0')
+ outcome[sz++] = '\n';
+ else
+ sz += cescape_char(c, outcome + sz);
+ }
+
+ outcome[sz] = '\0';
+ *env = outcome;
+ outcome = NULL;
+
+ return 0;
+}
+
+int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
+ int r;
+ _cleanup_free_ char *line = NULL;
+ long unsigned ppid;
+ const char *p;
+
+ assert(pid >= 0);
+ assert(_ppid);
+
+ if (pid == 0) {
+ *_ppid = getppid();
+ return 0;
+ }
+
+ p = procfs_file_alloca(pid, "stat");
+ r = read_one_line_file(p, &line);
+ if (r < 0)
+ return r;
+
+ /* Let's skip the pid and comm fields. The latter is enclosed
+ * in () but does not escape any () in its value, so let's
+ * skip over it manually */
+
+ p = strrchr(line, ')');
+ if (!p)
+ return -EIO;
+
+ p++;
+
+ if (sscanf(p, " "
+ "%*c " /* state */
+ "%lu ", /* ppid */
+ &ppid) != 1)
+ return -EIO;
+
+ if ((long unsigned) (pid_t) ppid != ppid)
+ return -ERANGE;
+
+ *_ppid = (pid_t) ppid;
+
+ return 0;
+}
+
+int wait_for_terminate(pid_t pid, siginfo_t *status) {
+ siginfo_t dummy;
+
+ assert(pid >= 1);
+
+ if (!status)
+ status = &dummy;
+
+ for (;;) {
+ zero(*status);
+
+ if (waitid(P_PID, pid, status, WEXITED) < 0) {
+
+ if (errno == EINTR)
+ continue;
+
+ return -errno;
+ }
+
+ return 0;
+ }
+}
+
+/*
+ * Return values:
+ * < 0 : wait_for_terminate() failed to get the state of the
+ * process, the process was terminated by a signal, or
+ * failed for an unknown reason.
+ * >=0 : The process terminated normally, and its exit code is
+ * returned.
+ *
+ * That is, success is indicated by a return value of zero, and an
+ * error is indicated by a non-zero value.
+ *
+ * A warning is emitted if the process terminates abnormally,
+ * and also if it returns non-zero unless check_exit_code is true.
+ */
+int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
+ int r;
+ siginfo_t status;
+
+ assert(name);
+ assert(pid > 1);
+
+ r = wait_for_terminate(pid, &status);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to wait for %s: %m", name);
+
+ if (status.si_code == CLD_EXITED) {
+ if (status.si_status != 0)
+ log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
+ "%s failed with error code %i.", name, status.si_status);
+ else
+ log_debug("%s succeeded.", name);
+
+ return status.si_status;
+ } else if (status.si_code == CLD_KILLED ||
+ status.si_code == CLD_DUMPED) {
+
+ log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
+ return -EPROTO;
+ }
+
+ log_warning("%s failed due to unknown reason.", name);
+ return -EPROTO;
+}
+
+int kill_and_sigcont(pid_t pid, int sig) {
+ int r;
+
+ r = kill(pid, sig) < 0 ? -errno : 0;
+
+ if (r >= 0)
+ kill(pid, SIGCONT);
+
+ return r;
+}
+
+int getenv_for_pid(pid_t pid, const char *field, char **_value) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char *value = NULL;
+ int r;
+ bool done = false;
+ size_t l;
+ const char *path;
+
+ assert(pid >= 0);
+ assert(field);
+ assert(_value);
+
+ path = procfs_file_alloca(pid, "environ");
+
+ f = fopen(path, "re");
+ if (!f)
+ return -errno;
+
+ l = strlen(field);
+ r = 0;
+
+ do {
+ char line[LINE_MAX];
+ unsigned i;
+
+ for (i = 0; i < sizeof(line)-1; i++) {
+ int c;
+
+ c = getc(f);
+ if (_unlikely_(c == EOF)) {
+ done = true;
+ break;
+ } else if (c == 0)
+ break;
+
+ line[i] = c;
+ }
+ line[i] = 0;
+
+ if (memcmp(line, field, l) == 0 && line[l] == '=') {
+ value = strdup(line + l + 1);
+ if (!value)
+ return -ENOMEM;
+
+ r = 1;
+ break;
+ }
+
+ } while (!done);
+
+ *_value = value;
+ return r;
+}
+
+bool pid_is_unwaited(pid_t pid) {
+ /* Checks whether a PID is still valid at all, including a zombie */
+
+ if (pid <= 0)
+ return false;
+
+ if (kill(pid, 0) >= 0)
+ return true;
+
+ return errno != ESRCH;
+}
+
+bool pid_is_alive(pid_t pid) {
+ int r;
+
+ /* Checks whether a PID is still valid and not a zombie */
+
+ if (pid <= 0)
+ return false;
+
+ r = get_process_state(pid);
+ if (r == -ENOENT || r == 'Z')
+ return false;
+
+ return true;
+}
diff --git a/src/shared/process-util.h b/src/shared/process-util.h
new file mode 100644
index 0000000..07431d0
--- /dev/null
+++ b/src/shared/process-util.h
@@ -0,0 +1,65 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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 <stdbool.h>
+#include <sys/types.h>
+#include <alloca.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include "formats-util.h"
+
+#define procfs_file_alloca(pid, field) \
+ ({ \
+ pid_t _pid_ = (pid); \
+ const char *_r_; \
+ if (_pid_ == 0) { \
+ _r_ = ("/proc/self/" field); \
+ } else { \
+ _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
+ sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
+ } \
+ _r_; \
+ })
+
+int get_process_state(pid_t pid);
+int get_process_comm(pid_t pid, char **name);
+int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
+int get_process_exe(pid_t pid, char **name);
+int get_process_uid(pid_t pid, uid_t *uid);
+int get_process_gid(pid_t pid, gid_t *gid);
+int get_process_capeff(pid_t pid, char **capeff);
+int get_process_cwd(pid_t pid, char **cwd);
+int get_process_root(pid_t pid, char **root);
+int get_process_environ(pid_t pid, char **environ);
+
+int wait_for_terminate(pid_t pid, siginfo_t *status);
+int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
+
+int kill_and_sigcont(pid_t pid, int sig);
+pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
+void rename_process(const char name[8]);
+int is_kernel_thread(pid_t pid);
+int getenv_for_pid(pid_t pid, const char *field, char **_value);
+
+bool pid_is_alive(pid_t pid);
+bool pid_is_unwaited(pid_t pid);
diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c
index a73a996..2e24b1e 100644
--- a/src/shared/smack-util.c
+++ b/src/shared/smack-util.c
@@ -24,6 +24,7 @@
#include <sys/xattr.h>
#include "util.h"
+#include "process-util.h"
#include "path-util.h"
#include "fileio.h"
#include "smack-util.h"
diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c
index 0d74588..70466d1 100644
--- a/src/shared/spawn-ask-password-agent.c
+++ b/src/shared/spawn-ask-password-agent.c
@@ -25,6 +25,7 @@
#include "log.h"
#include "util.h"
+#include "process-util.h"
#include "spawn-ask-password-agent.h"
static pid_t agent_pid = 0;
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
index bc1810d..4db249e 100644
--- a/src/shared/spawn-polkit-agent.c
+++ b/src/shared/spawn-polkit-agent.c
@@ -27,6 +27,7 @@
#include "log.h"
#include "util.h"
+#include "process-util.h"
#include "spawn-polkit-agent.h"
#ifdef ENABLE_POLKIT
diff --git a/src/shared/util.c b/src/shared/util.c
index 7321f1b..d4753f1 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -93,6 +93,7 @@
#include "def.h"
#include "sparse-endian.h"
#include "formats-util.h"
+#include "process-util.h"
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
@@ -185,7 +186,7 @@ char* first_word(const char *s, const char *word) {
return (char*) p;
}
-static size_t cescape_char(char c, char *buf) {
+size_t cescape_char(char c, char *buf) {
char * buf_old = buf;
switch (c) {
@@ -598,49 +599,6 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
return current;
}
-int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
- int r;
- _cleanup_free_ char *line = NULL;
- long unsigned ppid;
- const char *p;
-
- assert(pid >= 0);
- assert(_ppid);
-
- if (pid == 0) {
- *_ppid = getppid();
- return 0;
- }
-
- p = procfs_file_alloca(pid, "stat");
- r = read_one_line_file(p, &line);
- if (r < 0)
- return r;
-
- /* Let's skip the pid and comm fields. The latter is enclosed
- * in () but does not escape any () in its value, so let's
- * skip over it manually */
-
- p = strrchr(line, ')');
- if (!p)
- return -EIO;
-
- p++;
-
- if (sscanf(p, " "
- "%*c " /* state */
- "%lu ", /* ppid */
- &ppid) != 1)
- return -EIO;
-
- if ((long unsigned) (pid_t) ppid != ppid)
- return -ERANGE;
-
- *_ppid = (pid_t) ppid;
-
- return 0;
-}
-
int fchmod_umask(int fd, mode_t m) {
mode_t u;
int r;
@@ -659,308 +617,6 @@ char *truncate_nl(char *s) {
return s;
}
-int get_process_state(pid_t pid) {
- const char *p;
- char state;
- int r;
- _cleanup_free_ char *line = NULL;
-
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "stat");
- r = read_one_line_file(p, &line);
- if (r < 0)
- return r;
-
- p = strrchr(line, ')');
- if (!p)
- return -EIO;
-
- p++;
-
- if (sscanf(p, " %c", &state) != 1)
- return -EIO;
-
- return (unsigned char) state;
-}
-
-int get_process_comm(pid_t pid, char **name) {
- const char *p;
- int r;
-
- assert(name);
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "comm");
-
- r = read_one_line_file(p, name);
- if (r == -ENOENT)
- return -ESRCH;
-
- return r;
-}
-
-int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
- _cleanup_fclose_ FILE *f = NULL;
- char *r = NULL, *k;
- const char *p;
- int c;
-
- assert(line);
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "cmdline");
-
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- if (max_length == 0) {
- size_t len = 0, allocated = 0;
-
- while ((c = getc(f)) != EOF) {
-
- if (!GREEDY_REALLOC(r, allocated, len+2)) {
- free(r);
- return -ENOMEM;
- }
-
- r[len++] = isprint(c) ? c : ' ';
- }
-
- if (len > 0)
- r[len-1] = 0;
-
- } else {
- bool space = false;
- size_t left;
-
- r = new(char, max_length);
- if (!r)
- return -ENOMEM;
-
- k = r;
- left = max_length;
- while ((c = getc(f)) != EOF) {
-
- if (isprint(c)) {
- if (space) {
- if (left <= 4)
- break;
-
- *(k++) = ' ';
- left--;
- space = false;
- }
-
- if (left <= 4)
- break;
-
- *(k++) = (char) c;
- left--;
- } else
- space = true;
- }
-
- if (left <= 4) {
- size_t n = MIN(left-1, 3U);
- memcpy(k, "...", n);
- k[n] = 0;
- } else
- *k = 0;
- }
-
- /* Kernel threads have no argv[] */
- if (isempty(r)) {
- _cleanup_free_ char *t = NULL;
- int h;
-
- free(r);
-
- if (!comm_fallback)
- return -ENOENT;
-
- h = get_process_comm(pid, &t);
- if (h < 0)
- return h;
-
- r = strjoin("[", t, "]", NULL);
- if (!r)
- return -ENOMEM;
- }
-
- *line = r;
- return 0;
-}
-
-int is_kernel_thread(pid_t pid) {
- const char *p;
- size_t count;
- char c;
- bool eof;
- FILE *f;
-
- if (pid == 0)
- return 0;
-
- assert(pid > 0);
-
- p = procfs_file_alloca(pid, "cmdline");
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- count = fread(&c, 1, 1, f);
- eof = feof(f);
- fclose(f);
-
- /* Kernel threads have an empty cmdline */
-
- if (count <= 0)
- return eof ? 1 : -errno;
-
- return 0;
-}
-
-int get_process_capeff(pid_t pid, char **capeff) {
- const char *p;
-
- assert(capeff);
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "status");
-
- return get_status_field(p, "\nCapEff:", capeff);
-}
-
-static int get_process_link_contents(const char *proc_file, char **name) {
- int r;
-
- assert(proc_file);
- assert(name);
-
- r = readlink_malloc(proc_file, name);
- if (r < 0)
- return r == -ENOENT ? -ESRCH : r;
-
- return 0;
-}
-
-int get_process_exe(pid_t pid, char **name) {
- const char *p;
- char *d;
- int r;
-
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "exe");
- r = get_process_link_contents(p, name);
- if (r < 0)
- return r;
-
- d = endswith(*name, " (deleted)");
- if (d)
- *d = '\0';
-
- return 0;
-}
-
-static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
- const char *p;
-
- assert(field);
- assert(uid);
-
- if (pid == 0)
- return getuid();
-
- p = procfs_file_alloca(pid, "status");
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- FOREACH_LINE(line, f, return -errno) {
- char *l;
-
- l = strstrip(line);
-
- if (startswith(l, field)) {
- l += strlen(field);
- l += strspn(l, WHITESPACE);
-
- l[strcspn(l, WHITESPACE)] = 0;
-
- return parse_uid(l, uid);
- }
- }
-
- return -EIO;
-}
-
-int get_process_uid(pid_t pid, uid_t *uid) {
- return get_process_id(pid, "Uid:", uid);
-}
-
-int get_process_gid(pid_t pid, gid_t *gid) {
- assert_cc(sizeof(uid_t) == sizeof(gid_t));
- return get_process_id(pid, "Gid:", gid);
-}
-
-int get_process_cwd(pid_t pid, char **cwd) {
- const char *p;
-
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "cwd");
-
- return get_process_link_contents(p, cwd);
-}
-
-int get_process_root(pid_t pid, char **root) {
- const char *p;
-
- assert(pid >= 0);
-
- p = procfs_file_alloca(pid, "root");
-
- return get_process_link_contents(p, root);
-}
-
-int get_process_environ(pid_t pid, char **env) {
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *outcome = NULL;
- int c;
- const char *p;
- size_t allocated = 0, sz = 0;
-
- assert(pid >= 0);
- assert(env);
-
- p = procfs_file_alloca(pid, "environ");
-
- f = fopen(p, "re");
- if (!f)
- return -errno;
-
- while ((c = fgetc(f)) != EOF) {
- if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
- return -ENOMEM;
-
- if (c == '\0')
- outcome[sz++] = '\n';
- else
- sz += cescape_char(c, outcome + sz);
- }
-
- outcome[sz] = '\0';
- *env = outcome;
- outcome = NULL;
-
- return 0;
-}
-
char *strnappend(const char *s, const char *suffix, size_t b) {
size_t a;
char *r;
@@ -3676,73 +3332,6 @@ static char *unquote(const char *s, const char* quotes) {
return strdup(s);
}
-int wait_for_terminate(pid_t pid, siginfo_t *status) {
- siginfo_t dummy;
-
- assert(pid >= 1);
-
- if (!status)
- status = &dummy;
-
- for (;;) {
- zero(*status);
-
- if (waitid(P_PID, pid, status, WEXITED) < 0) {
-
- if (errno == EINTR)
- continue;
-
- return -errno;
- }
-
- return 0;
- }
-}
-
-/*
- * Return values:
- * < 0 : wait_for_terminate() failed to get the state of the
- * process, the process was terminated by a signal, or
- * failed for an unknown reason.
- * >=0 : The process terminated normally, and its exit code is
- * returned.
- *
- * That is, success is indicated by a return value of zero, and an
- * error is indicated by a non-zero value.
- *
- * A warning is emitted if the process terminates abnormally,
- * and also if it returns non-zero unless check_exit_code is true.
- */
-int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
- int r;
- siginfo_t status;
-
- assert(name);
- assert(pid > 1);
-
- r = wait_for_terminate(pid, &status);
- if (r < 0)
- return log_warning_errno(r, "Failed to wait for %s: %m", name);
-
- if (status.si_code == CLD_EXITED) {
- if (status.si_status != 0)
- log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
- "%s failed with error code %i.", name, status.si_status);
- else
- log_debug("%s succeeded.", name);
-
- return status.si_status;
- } else if (status.si_code == CLD_KILLED ||
- status.si_code == CLD_DUMPED) {
-
- log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
- return -EPROTO;
- }
-
- log_warning("%s failed due to unknown reason.", name);
- return -EPROTO;
-}
-
noreturn void freeze(void) {
/* Make sure nobody waits for us on a socket anymore */
@@ -4119,17 +3708,6 @@ void execute_directories(const char* const* directories, usec_t timeout, char *a
wait_for_terminate_and_warn(name, executor_pid, true);
}
-int kill_and_sigcont(pid_t pid, int sig) {
- int r;
-
- r = kill(pid, sig) < 0 ? -errno : 0;
-
- if (r >= 0)
- kill(pid, SIGCONT);
-
- return r;
-}
-
bool nulstr_contains(const char*nulstr, const char *needle) {
const char *i;
@@ -5338,60 +4916,6 @@ int setrlimit_closest(int resource, const struct rlimit *rlim) {
return 0;
}
-int getenv_for_pid(pid_t pid, const char *field, char **_value) {
- _cleanup_fclose_ FILE *f = NULL;
- char *value = NULL;
- int r;
- bool done = false;
- size_t l;
- const char *path;
-
- assert(pid >= 0);
- assert(field);
- assert(_value);
-
- path = procfs_file_alloca(pid, "environ");
-
- f = fopen(path, "re");
- if (!f)
- return -errno;
-
- l = strlen(field);
- r = 0;
-
- do {
- char line[LINE_MAX];
- unsigned i;
-
- for (i = 0; i < sizeof(line)-1; i++) {
- int c;
-
- c = getc(f);
- if (_unlikely_(c == EOF)) {
- done = true;
- break;
- } else if (c == 0)
- break;
-
- line[i] = c;
- }
- line[i] = 0;
-
- if (memcmp(line, field, l) == 0 && line[l] == '=') {
- value = strdup(line + l + 1);
- if (!value)
- return -ENOMEM;
-
- r = 1;
- break;
- }
-
- } while (!done);
-
- *_value = value;
- return r;
-}
-
bool http_etag_is_valid(const char *etag) {
if (isempty(etag))
return false;
@@ -6497,33 +6021,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) {
return 0;
}
-bool pid_is_unwaited(pid_t pid) {
- /* Checks whether a PID is still valid at all, including a zombie */
-
- if (pid <= 0)
- return false;
-
- if (kill(pid, 0) >= 0)
- return true;
-
- return errno != ESRCH;
-}
-
-bool pid_is_alive(pid_t pid) {
- int r;
-
- /* Checks whether a PID is still valid and not a zombie */
-
- if (pid <= 0)
- return false;
-
- r = get_process_state(pid);
- if (r == -ENOENT || r == 'Z')
- return false;
-
- return true;
-}
-
int getpeercred(int fd, struct ucred *ucred) {
socklen_t n = sizeof(struct ucred);
struct ucred u;
diff --git a/src/shared/util.h b/src/shared/util.h
index d17b987..b939d7f 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -227,8 +227,6 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
-pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
-
char *strappend(const char *s, const char *suffix);
char *strnappend(const char *s, const char *suffix, size_t length);
@@ -252,17 +250,6 @@ char *file_in_same_dir(const char *path, const char *filename);
int rmdir_parents(const char *path, const char *stop);
-int get_process_state(pid_t pid);
-int get_process_comm(pid_t pid, char **name);
-int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
-int get_process_exe(pid_t pid, char **name);
-int get_process_uid(pid_t pid, uid_t *uid);
-int get_process_gid(pid_t pid, gid_t *gid);
-int get_process_capeff(pid_t pid, char **capeff);
-int get_process_cwd(pid_t pid, char **cwd);
-int get_process_root(pid_t pid, char **root);
-int get_process_environ(pid_t pid, char **environ);
-
char hexchar(int x) _const_;
int unhexchar(char c) _const_;
char octchar(int x) _const_;
@@ -271,6 +258,7 @@ char decchar(int x) _const_;
int undecchar(char c) _const_;
char *cescape(const char *s);
+size_t cescape_char(char c, char *buf);
typedef enum UnescapeFlags {
UNESCAPE_RELAX = 1,
@@ -406,8 +394,6 @@ bool is_device_path(const char *path);
int dir_is_empty(const char *path);
char* dirname_malloc(const char *path);
-void rename_process(const char name[8]);
-
void sigset_add_many(sigset_t *ss, ...);
int sigprocmask_many(int how, ...);
@@ -482,9 +468,6 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
int touch(const char *path);
-int wait_for_terminate(pid_t pid, siginfo_t *status);
-int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
-
noreturn void freeze(void);
bool null_or_empty(struct stat *st) _pure_;
@@ -504,8 +487,6 @@ const char *default_term_for_tty(const char *tty);
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
-int kill_and_sigcont(pid_t pid, int sig);
-
bool nulstr_contains(const char*nulstr, const char *needle);
bool plymouth_running(void);
@@ -604,8 +585,6 @@ int fd_wait_for_event(int fd, int event, usec_t timeout);
void* memdup(const void *p, size_t l) _alloc_(2);
-int is_kernel_thread(pid_t pid);
-
int fd_inc_sndbuf(int fd, size_t n);
int fd_inc_rcvbuf(int fd, size_t n);
@@ -613,8 +592,6 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
int setrlimit_closest(int resource, const struct rlimit *rlim);
-int getenv_for_pid(pid_t pid, const char *field, char **_value);
-
bool http_url_is_valid(const char *url) _pure_;
bool documentation_url_is_valid(const char *url) _pure_;
@@ -891,19 +868,6 @@ int unlink_noerrno(const char *path);
_d_; \
})
-#define procfs_file_alloca(pid, field) \
- ({ \
- pid_t _pid_ = (pid); \
- const char *_r_; \
- if (_pid_ == 0) { \
- _r_ = ("/proc/self/" field); \
- } else { \
- _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
- sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
- } \
- _r_; \
- })
-
bool id128_is_valid(const char *s) _pure_;
int split_pair(const char *s, const char *sep, char **l, char **r);
@@ -931,9 +895,6 @@ int container_get_leader(const char *machine, pid_t *pid);
int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd);
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd);
-bool pid_is_alive(pid_t pid);
-bool pid_is_unwaited(pid_t pid);
-
int getpeercred(int fd, struct ucred *ucred);
int getpeersec(int fd, char **ret);
diff --git a/src/shared/virt.c b/src/shared/virt.c
index 54c4655..1299a75 100644
--- a/src/shared/virt.c
+++ b/src/shared/virt.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include "util.h"
+#include "process-util.h"
#include "virt.h"
#include "fileio.h"
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 915482f..04b7e7b 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -70,6 +70,7 @@
#include "dropin.h"
#include "efivars.h"
#include "formats-util.h"
+#include "process-util.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index c0f4abe..aca4f86 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -24,6 +24,7 @@
#include "cgroup-util.h"
#include "test-helper.h"
#include "formats-util.h"
+#include "process-util.h"
static void check_p_d_u(const char *path, int code, const char *result) {
_cleanup_free_ char *unit = NULL;
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index 63e4a19..4c31b77 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include "util.h"
+#include "process-util.h"
#include "fileio.h"
#include "strv.h"
#include "env-util.h"
diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c
index 2397db5..7d7e08d 100644
--- a/src/test/test-namespace.c
+++ b/src/test/test-namespace.c
@@ -23,6 +23,7 @@
#include "namespace.h"
#include "util.h"
+#include "process-util.h"
static void test_tmpdir(const char *id, const char *A, const char *B) {
_cleanup_free_ char *a, *b;
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
new file mode 100644
index 0000000..a17ef14
--- /dev/null
+++ b/src/test/test-process-util.c
@@ -0,0 +1,138 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2013 Thomas H.P. Andersen
+
+ 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 <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "process-util.h"
+#include "log.h"
+#include "util.h"
+#include "macro.h"
+#include "virt.h"
+
+static void test_get_process_comm(void) {
+ struct stat st;
+ _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
+ _cleanup_free_ char *env = NULL;
+ pid_t e;
+ uid_t u;
+ gid_t g;
+ dev_t h;
+ int r;
+ pid_t me;
+
+ if (stat("/proc/1/comm", &st) == 0) {
+ assert_se(get_process_comm(1, &a) >= 0);
+ log_info("pid1 comm: '%s'", a);
+ } else {
+ log_warning("/proc/1/comm does not exist.");
+ }
+
+ assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
+ log_info("pid1 cmdline: '%s'", c);
+
+ assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
+ log_info("pid1 cmdline truncated: '%s'", d);
+
+ assert_se(get_parent_of_pid(1, &e) >= 0);
+ log_info("pid1 ppid: "PID_FMT, e);
+ assert_se(e == 0);
+
+ assert_se(is_kernel_thread(1) == 0);
+
+ r = get_process_exe(1, &f);
+ assert_se(r >= 0 || r == -EACCES);
+ log_info("pid1 exe: '%s'", strna(f));
+
+ assert_se(get_process_uid(1, &u) == 0);
+ log_info("pid1 uid: "UID_FMT, u);
+ assert_se(u == 0);
+
+ assert_se(get_process_gid(1, &g) == 0);
+ log_info("pid1 gid: "GID_FMT, g);
+ assert_se(g == 0);
+
+ me = getpid();
+
+ r = get_process_cwd(me, &cwd);
+ assert_se(r >= 0 || r == -EACCES);
+ log_info("pid1 cwd: '%s'", cwd);
+
+ r = get_process_root(me, &root);
+ assert_se(r >= 0 || r == -EACCES);
+ log_info("pid1 root: '%s'", root);
+
+ r = get_process_environ(me, &env);
+ assert_se(r >= 0 || r == -EACCES);
+ log_info("self strlen(environ): '%zu'", strlen(env));
+
+ if (!detect_container(NULL))
+ assert_se(get_ctty_devnr(1, &h) == -ENOENT);
+
+ getenv_for_pid(1, "PATH", &i);
+ log_info("pid1 $PATH: '%s'", strna(i));
+}
+
+static void test_pid_is_unwaited(void) {
+ pid_t pid;
+
+ pid = fork();
+ assert_se(pid >= 0);
+ if (pid == 0) {
+ _exit(EXIT_SUCCESS);
+ } else {
+ int status;
+
+ waitpid(pid, &status, 0);
+ assert_se(!pid_is_unwaited(pid));
+ }
+ assert_se(pid_is_unwaited(getpid()));
+ assert_se(!pid_is_unwaited(-1));
+}
+
+static void test_pid_is_alive(void) {
+ pid_t pid;
+
+ pid = fork();
+ assert_se(pid >= 0);
+ if (pid == 0) {
+ _exit(EXIT_SUCCESS);
+ } else {
+ int status;
+
+ waitpid(pid, &status, 0);
+ assert_se(!pid_is_alive(pid));
+ }
+ assert_se(pid_is_alive(getpid()));
+ assert_se(!pid_is_alive(-1));
+}
+
+int main(int argc, char *argv[]) {
+ log_parse_environment();
+ log_open();
+
+ test_get_process_comm();
+ test_pid_is_unwaited();
+ test_pid_is_alive();
+
+ return 0;
+}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 4d36eb2..bfd4df9 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -37,6 +37,7 @@
#include "fileio.h"
#include "conf-parser.h"
#include "virt.h"
+#include "process-util.h"
static void test_streq_ptr(void) {
assert_se(streq_ptr(NULL, NULL));
@@ -572,69 +573,6 @@ static void test_u64log2(void) {
assert_se(u64log2(1024*1024+5) == 20);
}
-static void test_get_process_comm(void) {
- struct stat st;
- _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
- _cleanup_free_ char *env = NULL;
- pid_t e;
- uid_t u;
- gid_t g;
- dev_t h;
- int r;
- pid_t me;
-
- if (stat("/proc/1/comm", &st) == 0) {
- assert_se(get_process_comm(1, &a) >= 0);
- log_info("pid1 comm: '%s'", a);
- } else {
- log_warning("/proc/1/comm does not exist.");
- }
-
- assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
- log_info("pid1 cmdline: '%s'", c);
-
- assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
- log_info("pid1 cmdline truncated: '%s'", d);
-
- assert_se(get_parent_of_pid(1, &e) >= 0);
- log_info("pid1 ppid: "PID_FMT, e);
- assert_se(e == 0);
-
- assert_se(is_kernel_thread(1) == 0);
-
- r = get_process_exe(1, &f);
- assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 exe: '%s'", strna(f));
-
- assert_se(get_process_uid(1, &u) == 0);
- log_info("pid1 uid: "UID_FMT, u);
- assert_se(u == 0);
-
- assert_se(get_process_gid(1, &g) == 0);
- log_info("pid1 gid: "GID_FMT, g);
- assert_se(g == 0);
-
- me = getpid();
-
- r = get_process_cwd(me, &cwd);
- assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 cwd: '%s'", cwd);
-
- r = get_process_root(me, &root);
- assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 root: '%s'", root);
-
- r = get_process_environ(me, &env);
- assert_se(r >= 0 || r == -EACCES);
- log_info("self strlen(environ): '%zu'", strlen(env));
-
- if (!detect_container(NULL))
- assert_se(get_ctty_devnr(1, &h) == -ENOENT);
-
- getenv_for_pid(1, "PATH", &i);
- log_info("pid1 $PATH: '%s'", strna(i));
-}
-
static void test_protect_errno(void) {
errno = 12;
{
@@ -1138,40 +1076,6 @@ static void test_is_symlink(void) {
unlink(name_link);
}
-static void test_pid_is_unwaited(void) {
- pid_t pid;
-
- pid = fork();
- assert_se(pid >= 0);
- if (pid == 0) {
- _exit(EXIT_SUCCESS);
- } else {
- int status;
-
- waitpid(pid, &status, 0);
- assert_se(!pid_is_unwaited(pid));
- }
- assert_se(pid_is_unwaited(getpid()));
- assert_se(!pid_is_unwaited(-1));
-}
-
-static void test_pid_is_alive(void) {
- pid_t pid;
-
- pid = fork();
- assert_se(pid >= 0);
- if (pid == 0) {
- _exit(EXIT_SUCCESS);
- } else {
- int status;
-
- waitpid(pid, &status, 0);
- assert_se(!pid_is_alive(pid));
- }
- assert_se(pid_is_alive(getpid()));
- assert_se(!pid_is_alive(-1));
-}
-
static void test_search_and_fopen(void) {
const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
char name[] = "/tmp/test-search_and_fopen.XXXXXX";
@@ -1625,7 +1529,6 @@ int main(int argc, char *argv[]) {
test_memdup_multiply();
test_hostname_is_valid();
test_u64log2();
- test_get_process_comm();
test_protect_errno();
test_parse_size();
test_config_parse_iec_off();
@@ -1654,8 +1557,6 @@ int main(int argc, char *argv[]) {
test_strshorten();
test_strjoina();
test_is_symlink();
- test_pid_is_unwaited();
- test_pid_is_alive();
test_search_and_fopen();
test_search_and_fopen_nulstr();
test_glob_exists();
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 47093b8..8f4031a 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -42,6 +42,7 @@
#include "strv.h"
#include "build.h"
#include "def.h"
+#include "process-util.h"
static enum {
ACTION_LIST,
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index 243e51d..3f93524 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -35,6 +35,7 @@
#include "log.h"
#include "virt.h"
#include "fileio.h"
+#include "process-util.h"
static bool is_vconsole(int fd) {
unsigned char data[1];
commit 6482f6269c87d2249e52e889a63adbdd50f2d691
Author: Ronny Chevalier <chevalier.ronny at gmail.com>
Date: Fri Apr 10 20:43:52 2015 +0200
shared: add formats-util.h
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index d612816..3e398b5 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -41,6 +41,7 @@
#include "capability.h"
#include "bus-xml-policy.h"
#include "proxy.h"
+#include "formats-util.h"
static char *arg_address = NULL;
static char **arg_configuration = NULL;
diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c
index 497bce7..675d244 100644
--- a/src/bus-proxyd/bus-xml-policy.c
+++ b/src/bus-proxyd/bus-xml-policy.c
@@ -27,6 +27,7 @@
#include "bus-internal.h"
#include "bus-xml-policy.h"
#include "sd-login.h"
+#include "formats-util.h"
static void policy_item_free(PolicyItem *i) {
assert(i);
diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c
index c689618..aa5010c 100644
--- a/src/bus-proxyd/proxy.c
+++ b/src/bus-proxyd/proxy.c
@@ -42,6 +42,7 @@
#include "driver.h"
#include "proxy.h"
#include "synthesize.h"
+#include "formats-util.h"
static int proxy_create_destination(Proxy *p, const char *destination, const char *local_sec, bool negotiate_fds) {
_cleanup_bus_close_unref_ sd_bus *b = NULL;
diff --git a/src/bus-proxyd/stdio-bridge.c b/src/bus-proxyd/stdio-bridge.c
index 35e69a5..61bc08a 100644
--- a/src/bus-proxyd/stdio-bridge.c
+++ b/src/bus-proxyd/stdio-bridge.c
@@ -37,6 +37,7 @@
#include "strv.h"
#include "def.h"
#include "proxy.h"
+#include "formats-util.h"
static char *arg_address = NULL;
static char *arg_command_line_buffer = NULL;
diff --git a/src/core/automount.c b/src/core/automount.c
index f6a6ad5..e1ca2a4 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -40,6 +40,7 @@
#include "dbus-automount.h"
#include "bus-util.h"
#include "bus-error.h"
+#include "formats-util.h"
static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
[AUTOMOUNT_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/busname.c b/src/core/busname.c
index 0ca9678..b1b953a 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -30,6 +30,7 @@
#include "bus-policy.h"
#include "dbus-busname.h"
#include "busname.h"
+#include "formats-util.h"
static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
[BUSNAME_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 1b26e55..8821cc7 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -40,6 +40,7 @@
#include "dbus-snapshot.h"
#include "dbus-execute.h"
#include "bus-common-errors.h"
+#include "formats-util.h"
static int property_get_version(
sd_bus *bus,
diff --git a/src/core/execute.c b/src/core/execute.c
index 768a32b..c87e900 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -76,6 +76,7 @@
#include "smack-util.h"
#include "bus-endpoint.h"
#include "cap-list.h"
+#include "formats-util.h"
#ifdef HAVE_APPARMOR
#include "apparmor-util.h"
diff --git a/src/core/killall.c b/src/core/killall.c
index c6f1ddf..5040514 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -27,6 +27,7 @@
#include "util.h"
#include "killall.h"
#include "set.h"
+#include "formats-util.h"
#define TIMEOUT_USEC (10 * USEC_PER_SEC)
diff --git a/src/core/main.c b/src/core/main.c
index dd8b650..5d1aed8 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -72,6 +72,7 @@
#include "ima-setup.h"
#include "smack-setup.h"
#include "kmod-setup.h"
+#include "formats-util.h"
static enum {
ACTION_RUN,
diff --git a/src/core/mount.c b/src/core/mount.c
index c4aa810..8bfbbed 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -40,6 +40,7 @@
#include "special.h"
#include "exit-status.h"
#include "fstab-util.h"
+#include "formats-util.h"
#define RETRY_UMOUNT_MAX 32
diff --git a/src/core/service.c b/src/core/service.c
index d938550..c6ea655 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -45,6 +45,7 @@
#include "bus-error.h"
#include "bus-util.h"
#include "bus-kernel.h"
+#include "formats-util.h"
static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/socket.c b/src/core/socket.c
index c81fd66..dd805d5 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -48,6 +48,7 @@
#include "dbus-socket.h"
#include "unit.h"
#include "socket.h"
+#include "formats-util.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/swap.c b/src/core/swap.c
index 53f1274..76660cc 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -35,6 +35,7 @@
#include "virt.h"
#include "udev-util.h"
#include "fstab-util.h"
+#include "formats-util.h"
static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
[SWAP_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index 90cb504..bb4aa21 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -26,6 +26,7 @@
#include "unit-printf.h"
#include "macro.h"
#include "cgroup-util.h"
+#include "formats-util.h"
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
Unit *u = userdata;
diff --git a/src/core/unit.c b/src/core/unit.c
index 7660d6b..4b9c406 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -46,6 +46,7 @@
#include "dbus.h"
#include "execute.h"
#include "dropin.h"
+#include "formats-util.h"
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index ecec7a1..19d6468 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -36,6 +36,7 @@
#include "bus-util.h"
#include "bus-error.h"
#include "def.h"
+#include "formats-util.h"
#define SERVER_FD_MAX 16
#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index 75bb434..ddbb873 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -34,6 +34,7 @@
#include "conf-parser.h"
#include "sigbus.h"
#include "journal-upload.h"
+#include "formats-util.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
#define CERT_FILE CERTIFICATE_ROOT "/certs/journal-upload.pem"
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index f7ea779..4ccacd7 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -26,6 +26,7 @@
#include "fileio.h"
#include "journald-server.h"
#include "journald-console.h"
+#include "formats-util.h"
static bool prefix_timestamp(void) {
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index 80bd9cd..cb4bc38 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -31,6 +31,7 @@
#include "journald-server.h"
#include "journald-kmsg.h"
#include "journald-syslog.h"
+#include "formats-util.h"
void server_forward_kmsg(
Server *s,
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 78d5b22..7e20b96 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -50,6 +50,7 @@
#include "journald-audit.h"
#include "journald-server.h"
#include "acl-util.h"
+#include "formats-util.h"
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 7d545ca..6c46a30 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -31,6 +31,7 @@
#include "journald-kmsg.h"
#include "journald-console.h"
#include "journald-wall.h"
+#include "formats-util.h"
/* Warn once every 30s if we missed syslog message */
#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
index e320167..b4e0717 100644
--- a/src/journal/journald-wall.c
+++ b/src/journal/journald-wall.c
@@ -22,6 +22,7 @@
#include "utmp-wtmp.h"
#include "journald-server.h"
#include "journald-wall.h"
+#include "formats-util.h"
void server_forward_wall(
Server *s,
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 28a4233..b2624c6 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -30,6 +30,7 @@
#include "journald-syslog.h"
#include "sigbus.h"
+#include "formats-util.h"
int main(int argc, char *argv[]) {
Server server;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 9b9e8ac..9f0f71a 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -42,6 +42,7 @@
#include "catalog.h"
#include "replace-var.h"
#include "fileio.h"
+#include "formats-util.h"
#define JOURNAL_FILES_MAX 7168
diff --git a/src/journal/stacktrace.c b/src/journal/stacktrace.c
index 6b9d272..706c08e 100644
--- a/src/journal/stacktrace.c
+++ b/src/journal/stacktrace.c
@@ -25,6 +25,7 @@
#include "util.h"
#include "macro.h"
#include "stacktrace.h"
+#include "formats-util.h"
#define FRAMES_MAX 64
#define THREADS_MAX 64
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index cd1c5e2..4141cc3 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -23,6 +23,7 @@
#include <linux/capability.h>
#include "util.h"
+#include "formats-util.h"
#include "capability.h"
#include "cgroup-util.h"
#include "fileio.h"
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 4bc8965..d722680 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -24,6 +24,7 @@
#include "strv.h"
#include "macro.h"
#include "cap-list.h"
+#include "formats-util.h"
#include "bus-message.h"
#include "bus-internal.h"
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 35c2aa6..0062e66 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -39,6 +39,7 @@
#include "memfd-util.h"
#include "capability.h"
#include "fileio.h"
+#include "formats-util.h"
#include "bus-internal.h"
#include "bus-message.h"
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 873aede..f97e15d 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -29,6 +29,7 @@
#include "missing.h"
#include "utf8.h"
#include "sd-daemon.h"
+#include "formats-util.h"
#include "sd-bus.h"
#include "bus-socket.h"
diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c
index 7f49fe9..ab2ec27 100644
--- a/src/libsystemd/sd-bus/test-bus-chat.c
+++ b/src/libsystemd/sd-bus/test-bus-chat.c
@@ -27,6 +27,7 @@
#include "log.h"
#include "util.h"
#include "macro.h"
+#include "formats-util.h"
#include "sd-bus.h"
#include "bus-error.h"
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 072191e..7b8f063 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -31,6 +31,7 @@
#include "strv.h"
#include "fileio.h"
#include "login-shared.h"
+#include "formats-util.h"
#include "sd-login.h"
_public_ int sd_pid_get_session(pid_t pid, char **session) {
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 2802e82..05affa4 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -26,6 +26,7 @@
#include "util.h"
#include "strv.h"
+#include "formats-util.h"
static void test_login(void) {
_cleanup_close_pair_ int pair[2] = { -1, -1 };
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index c938471..4f994a1 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include "util.h"
+#include "formats-util.h"
#include "refcnt.h"
#include "missing.h"
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index c48ac78..e9d403c 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -32,6 +32,7 @@
#include "libudev-private.h"
#include "socket-util.h"
#include "missing.h"
+#include "formats-util.h"
/**
* SECTION:libudev-monitor
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index 9f349b7..1f78e4b 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -31,6 +31,7 @@
#include "util.h"
#include "build.h"
#include "strv.h"
+#include "formats-util.h"
static const char* arg_what = "idle:sleep:shutdown";
static const char* arg_who = NULL;
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
index d2b3337..466225d 100644
--- a/src/login/logind-acl.c
+++ b/src/login/logind-acl.c
@@ -23,6 +23,7 @@
#include <string.h>
#include "util.h"
+#include "formats-util.h"
#include "acl-util.h"
#include "set.h"
#include "logind-acl.h"
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index 281e3c7..d7ae175 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -27,6 +27,7 @@
#include "bus-util.h"
#include "bus-error.h"
#include "logind-action.h"
+#include "formats-util.h"
int manager_handle_action(
Manager *m,
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 9ba85d8..45aedad 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -40,6 +40,7 @@
#include "selinux-util.h"
#include "efivars.h"
#include "logind.h"
+#include "formats-util.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 5eb1a2e..68304a1 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -28,6 +28,7 @@
#include "mkdir.h"
#include "logind-inhibit.h"
#include "fileio.h"
+#include "formats-util.h"
Inhibitor* inhibitor_new(Manager *m, const char* id) {
Inhibitor *i;
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 49808c9..4c0bebd 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -29,6 +29,7 @@
#include "logind-acl.h"
#include "util.h"
#include "mkdir.h"
+#include "formats-util.h"
Seat *seat_new(Manager *m, const char *id) {
Seat *s;
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 59f7657..cebc90c 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -37,6 +37,7 @@
#include "bus-util.h"
#include "bus-error.h"
#include "logind-session.h"
+#include "formats-util.h"
#define RELEASE_USEC (20*USEC_PER_SEC)
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index f7af8ff..03c3370 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -26,6 +26,7 @@
#include "bus-util.h"
#include "logind.h"
#include "logind-user.h"
+#include "formats-util.h"
static int property_get_display(
sd_bus *bus,
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index cba9cb6..b00e9b1 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -38,6 +38,7 @@
#include "clean-ipc.h"
#include "logind-user.h"
#include "smack-util.h"
+#include "formats-util.h"
User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
User *u;
diff --git a/src/login/logind.c b/src/login/logind.c
index e788074..707d528 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -32,6 +32,7 @@
#include "bus-error.h"
#include "logind.h"
#include "udev-util.h"
+#include "formats-util.h"
Manager *manager_new(void) {
Manager *m;
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index d7a708f..a0fabfe 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -40,6 +40,7 @@
#include "socket-util.h"
#include "fileio.h"
#include "bus-error.h"
+#include "formats-util.h"
static int parse_argv(
pam_handle_t *handle,
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index d6b8c90..6cc46af 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -42,6 +42,7 @@
#include "bus-internal.h"
#include "machine.h"
#include "machine-dbus.h"
+#include "formats-util.h"
static int property_get_id(
sd_bus *bus,
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 048607f..dd073ad 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -35,6 +35,7 @@
#include "bus-error.h"
#include "machine.h"
#include "machine-dbus.h"
+#include "formats-util.h"
Machine* machine_new(Manager *manager, const char *name) {
Machine *m;
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 4d74093..066a8da 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -35,6 +35,7 @@
#include "image-dbus.h"
#include "machined.h"
#include "machine-dbus.h"
+#include "formats-util.h"
static int property_get_pool_path(
sd_bus *bus,
diff --git a/src/machine/machined.c b/src/machine/machined.c
index f91f067..7980293 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -30,6 +30,7 @@
#include "label.h"
#include "machine-image.h"
#include "machined.h"
+#include "formats-util.h"
Manager *manager_new(void) {
Manager *m;
diff --git a/src/notify/notify.c b/src/notify/notify.c
index 00db753..c920b29 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -32,6 +32,7 @@
#include "log.h"
#include "build.h"
#include "env-util.h"
+#include "formats-util.h"
static bool arg_ready = false;
static pid_t arg_pid = 0;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 6789281..8ec6743 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -91,6 +91,7 @@
#include "in-addr-util.h"
#include "fw-util.h"
#include "local-addresses.h"
+#include "formats-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
diff --git a/src/run/run.c b/src/run/run.c
index 3ded2c7..156824e 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -34,6 +34,7 @@
#include "bus-error.h"
#include "calendarspec.h"
#include "ptyfwd.h"
+#include "formats-util.h"
static bool arg_scope = false;
static bool arg_remain_after_exit = false;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index 44ebc58..dfc89d2 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -32,6 +32,7 @@
#include <sys/signalfd.h>
#include "util.h"
+#include "formats-util.h"
#include "mkdir.h"
#include "strv.h"
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index cbd94e8..fed72ac 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -25,6 +25,7 @@
#include <errno.h>
#include "util.h"
+#include "formats-util.h"
#include "macro.h"
#include "path-util.h"
#include "cgroup-util.h"
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index b6fa386..481708f 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -33,6 +33,7 @@
#include "set.h"
#include "macro.h"
#include "util.h"
+#include "formats-util.h"
#include "path-util.h"
#include "unit-name.h"
#include "fileio.h"
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
index ea781f5..48b1086 100644
--- a/src/shared/clean-ipc.c
+++ b/src/shared/clean-ipc.c
@@ -29,6 +29,7 @@
#include <mqueue.h>
#include "util.h"
+#include "formats-util.h"
#include "strv.h"
#include "clean-ipc.h"
diff --git a/src/shared/formats-util.h b/src/shared/formats-util.h
new file mode 100644
index 0000000..ce516b1
--- /dev/null
+++ b/src/shared/formats-util.h
@@ -0,0 +1,63 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Ronny Chevalier
+
+ 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 <inttypes.h>
+
+#if SIZEOF_PID_T == 4
+# define PID_PRI PRIi32
+#elif SIZEOF_PID_T == 2
+# define PID_PRI PRIi16
+#else
+# error Unknown pid_t size
+#endif
+#define PID_FMT "%" PID_PRI
+
+#if SIZEOF_UID_T == 4
+# define UID_FMT "%" PRIu32
+#elif SIZEOF_UID_T == 2
+# define UID_FMT "%" PRIu16
+#else
+# error Unknown uid_t size
+#endif
+
+#if SIZEOF_GID_T == 4
+# define GID_FMT "%" PRIu32
+#elif SIZEOF_GID_T == 2
+# define GID_FMT "%" PRIu16
+#else
+# error Unknown gid_t size
+#endif
+
+#if SIZEOF_TIME_T == 8
+# define PRI_TIME PRIi64
+#elif SIZEOF_TIME_T == 4
+# define PRI_TIME PRIu32
+#else
+# error Unknown time_t size
+#endif
+
+#if SIZEOF_RLIM_T == 8
+# define RLIM_FMT "%" PRIu64
+#elif SIZEOF_RLIM_T == 4
+# define RLIM_FMT "%" PRIu32
+#else
+# error Unknown rlim_t size
+#endif
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
index f62a032..9996649 100644
--- a/src/shared/install-printf.c
+++ b/src/shared/install-printf.c
@@ -25,6 +25,7 @@
#include "unit-name.h"
#include "util.h"
#include "install-printf.h"
+#include "formats-util.h"
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
InstallInfo *i = userdata;
diff --git a/src/shared/log.c b/src/shared/log.c
index 646a1d6..32ec581 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -34,6 +34,7 @@
#include "missing.h"
#include "macro.h"
#include "socket-util.h"
+#include "formats-util.h"
#define SNDBUF_SIZE (8*1024*1024)
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 4e1b878..e179b8a 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -31,6 +31,7 @@
#include "utf8.h"
#include "hashmap.h"
#include "journal-internal.h"
+#include "formats-util.h"
/* up to three lines (each up to 100 characters),
or 300 characters, whichever is less */
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
index 4a6bf50..94a0663 100644
--- a/src/shared/socket-util.c
+++ b/src/shared/socket-util.c
@@ -35,6 +35,7 @@
#include "socket-util.h"
#include "missing.h"
#include "fileio.h"
+#include "formats-util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
diff --git a/src/shared/util.c b/src/shared/util.c
index df5f8d1..7321f1b 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -92,6 +92,7 @@
#include "virt.h"
#include "def.h"
#include "sparse-endian.h"
+#include "formats-util.h"
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
diff --git a/src/shared/util.h b/src/shared/util.h
index 56e11c7..d17b987 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -43,50 +43,10 @@
#include <sys/inotify.h>
#include <sys/statfs.h>
-#if SIZEOF_PID_T == 4
-# define PID_PRI PRIi32
-#elif SIZEOF_PID_T == 2
-# define PID_PRI PRIi16
-#else
-# error Unknown pid_t size
-#endif
-#define PID_FMT "%" PID_PRI
-
-#if SIZEOF_UID_T == 4
-# define UID_FMT "%" PRIu32
-#elif SIZEOF_UID_T == 2
-# define UID_FMT "%" PRIu16
-#else
-# error Unknown uid_t size
-#endif
-
-#if SIZEOF_GID_T == 4
-# define GID_FMT "%" PRIu32
-#elif SIZEOF_GID_T == 2
-# define GID_FMT "%" PRIu16
-#else
-# error Unknown gid_t size
-#endif
-
-#if SIZEOF_TIME_T == 8
-# define PRI_TIME PRIi64
-#elif SIZEOF_TIME_T == 4
-# define PRI_TIME PRIu32
-#else
-# error Unknown time_t size
-#endif
-
-#if SIZEOF_RLIM_T == 8
-# define RLIM_FMT "%" PRIu64
-#elif SIZEOF_RLIM_T == 4
-# define RLIM_FMT "%" PRIu32
-#else
-# error Unknown rlim_t size
-#endif
-
#include "macro.h"
#include "missing.h"
#include "time-util.h"
+#include "formats-util.h"
/* What is interpreted as whitespace? */
#define WHITESPACE " \t\n\r"
diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c
index 6e4511e..a05cddc 100644
--- a/src/shutdownd/shutdownd.c
+++ b/src/shutdownd/shutdownd.c
@@ -35,6 +35,7 @@
#include "utmp-wtmp.h"
#include "mkdir.h"
#include "fileio.h"
+#include "formats-util.h"
union shutdown_buffer {
struct sd_shutdown_command command;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 9cb351d..915482f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -69,6 +69,7 @@
#include "mkdir.h"
#include "dropin.h"
#include "efivars.h"
+#include "formats-util.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index e549df6..cc4c7ef 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -38,6 +38,7 @@
#include "fileio-label.h"
#include "uid-range.h"
#include "selinux-util.h"
+#include "formats-util.h"
typedef enum ItemType {
ADD_USER = 'u',
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 9834a6a..c0f4abe 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -23,6 +23,7 @@
#include "util.h"
#include "cgroup-util.h"
#include "test-helper.h"
+#include "formats-util.h"
static void check_p_d_u(const char *path, int code, const char *result) {
_cleanup_free_ char *unit = NULL;
diff --git a/src/test/test-log.c b/src/test/test-log.c
index ca64004..9dcfa2f 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -24,6 +24,7 @@
#include "log.h"
#include "util.h"
+#include "formats-util.h"
int main(int argc, char* argv[]) {
diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c
index 90e49d4..221dd67 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include "util.h"
+#include "formats-util.h"
int main(int argc, char** argv) {
const char *p = argv[1] ?: "/tmp";
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index ad5f3f6..ef13dcb 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -56,6 +56,7 @@
#include "selinux-util.h"
#include "btrfs-util.h"
#include "acl-util.h"
+#include "formats-util.h"
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
* them in the file system. This is intended to be used to create
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 61d3c5b..0f357ba 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -19,6 +19,7 @@
#include <sys/un.h>
#include "socket-util.h"
+#include "formats-util.h"
#include "udev.h"
/* wire protocol magic must match */
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 3a165b0..bda0638 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -32,6 +32,7 @@
#include "udev.h"
#include "rtnl-util.h"
+#include "formats-util.h"
struct udev_event *udev_event_new(struct udev_device *dev) {
struct udev *udev = udev_device_get_udev(dev);
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index debf9ea..d824172 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -28,6 +28,7 @@
#include "udev.h"
#include "smack-util.h"
#include "selinux-util.h"
+#include "formats-util.h"
static int node_symlink(struct udev_device *dev, const char *node, const char *slink) {
struct stat stats;
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index 7ef2e68..5e93955 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -27,6 +27,7 @@
#include "udev.h"
#include "udev-util.h"
+#include "formats-util.h"
static bool udev_exit;
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 830aedd..a3f17c4 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -48,6 +48,7 @@
#include "selinux-util.h"
#include "udev.h"
#include "udev-util.h"
+#include "formats-util.h"
static struct udev_rules *rules;
static struct udev_ctrl *udev_ctrl;
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index 33535eb..ea9b0c9 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -37,6 +37,7 @@
#include "bus-util.h"
#include "bus-error.h"
#include "unit-name.h"
+#include "formats-util.h"
typedef struct Context {
sd_bus *bus;
More information about the systemd-commits
mailing list