- Undo Obsoletes/Provides (from Aug 11), creates too big a cycle.

- Provide systemd-sysv-install program/link [bnc#948353]

OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=907
This commit is contained in:
Dr. Werner Fink 2015-10-06 15:11:15 +00:00 committed by Git OBS Bridge
parent 87536ff7bd
commit 2e0055b023
6 changed files with 186 additions and 273 deletions

View File

@ -1,8 +1,8 @@
-------------------------------------------------------------------
Tue Oct 6 15:09:56 UTC 2015 - werner@suse.de
Thu Oct 1 15:58:32 UTC 2015 - jengelh@inai.de
- Modifiy patch tty-ask-password-agent-on-console.patch to reflect
latest status of pull request 1432
- Undo Obsoletes/Provides (from Aug 11), creates too big a cycle.
- Provide systemd-sysv-install program/link [bnc#948353]
-------------------------------------------------------------------
Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de

View File

@ -83,10 +83,12 @@ BuildRequires: pkgconfig(libseccomp)
BuildRequires: pkgconfig(libselinux) >= 2.1.9
BuildRequires: pkgconfig(libsepol)
Conflicts: sysvinit
Conflicts: otherproviders(systemd)
%if 0%{?bootstrap}
#!BuildIgnore: dbus-1
Requires: this-is-only-for-build-envs
Provides: systemd = %version-%release
Conflicts: otherproviders(systemd)
Conflicts: kiwi
%else
BuildRequires: docbook-xsl-stylesheets
BuildRequires: libgcrypt-devel
@ -143,6 +145,7 @@ Source7: libgcrypt.m4
Source9: nss-myhostname-config
Source10: macros.systemd.upstream
Source11: after-local.service
Source12: systemd-sysv-install
Source1065: systemd-remount-tmpfs
@ -324,11 +327,8 @@ Requires: libsystemd0%{?mini} = %version
Requires: systemd-rpm-macros
%if 0%{?bootstrap}
Provides: systemd-devel = %version-%release
Conflicts: otherproviders(systemd-devel)
%else
Obsoletes: systemd-mini-devel
Provides: systemd-mini-devel
%endif
Conflicts: otherproviders(systemd-devel)
%description devel
Development headers and auxiliary files for developing applications for systemd.
@ -351,9 +351,7 @@ License: LGPL-2.1+
Group: System/Libraries
%if 0%{?bootstrap}
Conflicts: libsystemd0
%else
Obsoletes: libsystemd0-mini
Provides: libsystemd0-mini
Requires: this-is-only-for-build-envs
%endif
%description -n libsystemd0%{?mini}
@ -411,11 +409,9 @@ Conflicts: ConsoleKit < 0.4.1
Requires: filesystem
%if 0%{?bootstrap}
Provides: udev = %version-%release
Conflicts: otherproviders(udev)
%else
Obsoletes: udev-mini
Provides: udev-mini
Conflicts: kiwi
%endif
Conflicts: otherproviders(udev)
%description -n udev%{?mini}
Udev creates and removes device nodes in /dev for devices discovered or
@ -449,11 +445,8 @@ Group: Development/Libraries/C and C++
Requires: libudev%{?mini}1 = %version-%release
%if 0%{?bootstrap}
Provides: libudev-devel = %version-%release
Conflicts: otherproviders(libudev-devel)
%else
Obsoletes: libudev-mini-devel
Provides: libudev-mini-devel
%endif
Conflicts: otherproviders(libudev-devel)
%description -n libudev%{?mini}-devel
This package contains the development files for the library libudev, a
@ -726,6 +719,7 @@ make %{?_smp_mflags} update-man-list man
%install
make install DESTDIR="%buildroot"
install -pm0755 "%_sourcedir/systemd-sysv-install" "%buildroot/%_prefix/lib/systemd/"
# move to %{_lib}
%if ! 0%{?bootstrap}
@ -1187,6 +1181,7 @@ exit 0
%dir %{_prefix}/lib/systemd
%dir %{_prefix}/lib/systemd/user
%dir %{_prefix}/lib/systemd/system
%exclude %{_prefix}/lib/systemd/systemd-sysv*
%exclude %{_prefix}/lib/systemd/system/systemd-udev*.*
%exclude %{_prefix}/lib/systemd/system/udev.service
%exclude %{_prefix}/lib/systemd/system/initrd-udevadm-cleanup-db.service
@ -1443,6 +1438,8 @@ exit 0
%{_mandir}/man8/telinit.8*
%{_mandir}/man8/runlevel.8*
%endif
%dir %_prefix/lib/systemd
%_prefix/lib/systemd/systemd-sysv-install
%files -n udev%{?mini}
%defattr(-,root,root)

26
systemd-sysv-install Normal file
View File

@ -0,0 +1,26 @@
#!/bin/sh
set -e
usage() {
echo "Usage: $0 [--root=path] enable|disable|is-enabled <sysv script name>" >&2
exit 1
}
eval set -- "$(getopt -o r: --long root: -- "$@")"
while true; do
case "$1" in
-r|--root)
ROOT="$2"
shift 2 ;;
--) shift ; break ;;
*) usage ;;
esac
done
NAME="$2"
ROOT="${ROOT:+--root=$ROOT}"
[ -n "$NAME" ] || usage
case "$1" in
enable) chkconfig $ROOT -a "$NAME" ;;
disable) chkconfig $ROOT -r "$NAME" ;;
is-enabled) chkconfig $ROOT -t "$NAME" ;;
*) usage ;;
esac

View File

@ -1,8 +1,8 @@
-------------------------------------------------------------------
Tue Oct 6 15:09:56 UTC 2015 - werner@suse.de
Thu Oct 1 15:58:32 UTC 2015 - jengelh@inai.de
- Modifiy patch tty-ask-password-agent-on-console.patch to reflect
latest status of pull request 1432
- Undo Obsoletes/Provides (from Aug 11), creates too big a cycle.
- Provide systemd-sysv-install program/link [bnc#948353]
-------------------------------------------------------------------
Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de

View File

@ -78,10 +78,12 @@ BuildRequires: pkgconfig(libseccomp)
BuildRequires: pkgconfig(libselinux) >= 2.1.9
BuildRequires: pkgconfig(libsepol)
Conflicts: sysvinit
Conflicts: otherproviders(systemd)
%if 0%{?bootstrap}
#!BuildIgnore: dbus-1
Requires: this-is-only-for-build-envs
Provides: systemd = %version-%release
Conflicts: otherproviders(systemd)
Conflicts: kiwi
%else
BuildRequires: docbook-xsl-stylesheets
BuildRequires: libgcrypt-devel
@ -138,6 +140,7 @@ Source7: libgcrypt.m4
Source9: nss-myhostname-config
Source10: macros.systemd.upstream
Source11: after-local.service
Source12: systemd-sysv-install
Source1065: systemd-remount-tmpfs
@ -319,11 +322,8 @@ Requires: libsystemd0%{?mini} = %version
Requires: systemd-rpm-macros
%if 0%{?bootstrap}
Provides: systemd-devel = %version-%release
Conflicts: otherproviders(systemd-devel)
%else
Obsoletes: systemd-mini-devel
Provides: systemd-mini-devel
%endif
Conflicts: otherproviders(systemd-devel)
%description devel
Development headers and auxiliary files for developing applications for systemd.
@ -346,9 +346,7 @@ License: LGPL-2.1+
Group: System/Libraries
%if 0%{?bootstrap}
Conflicts: libsystemd0
%else
Obsoletes: libsystemd0-mini
Provides: libsystemd0-mini
Requires: this-is-only-for-build-envs
%endif
%description -n libsystemd0%{?mini}
@ -406,11 +404,9 @@ Conflicts: ConsoleKit < 0.4.1
Requires: filesystem
%if 0%{?bootstrap}
Provides: udev = %version-%release
Conflicts: otherproviders(udev)
%else
Obsoletes: udev-mini
Provides: udev-mini
Conflicts: kiwi
%endif
Conflicts: otherproviders(udev)
%description -n udev%{?mini}
Udev creates and removes device nodes in /dev for devices discovered or
@ -444,11 +440,8 @@ Group: Development/Libraries/C and C++
Requires: libudev%{?mini}1 = %version-%release
%if 0%{?bootstrap}
Provides: libudev-devel = %version-%release
Conflicts: otherproviders(libudev-devel)
%else
Obsoletes: libudev-mini-devel
Provides: libudev-mini-devel
%endif
Conflicts: otherproviders(libudev-devel)
%description -n libudev%{?mini}-devel
This package contains the development files for the library libudev, a
@ -721,6 +714,7 @@ make %{?_smp_mflags} update-man-list man
%install
make install DESTDIR="%buildroot"
install -pm0755 "%_sourcedir/systemd-sysv-install" "%buildroot/%_prefix/lib/systemd/"
# move to %{_lib}
%if ! 0%{?bootstrap}
@ -1182,6 +1176,7 @@ exit 0
%dir %{_prefix}/lib/systemd
%dir %{_prefix}/lib/systemd/user
%dir %{_prefix}/lib/systemd/system
%exclude %{_prefix}/lib/systemd/systemd-sysv*
%exclude %{_prefix}/lib/systemd/system/systemd-udev*.*
%exclude %{_prefix}/lib/systemd/system/udev.service
%exclude %{_prefix}/lib/systemd/system/initrd-udevadm-cleanup-db.service
@ -1438,6 +1433,8 @@ exit 0
%{_mandir}/man8/telinit.8*
%{_mandir}/man8/runlevel.8*
%endif
%dir %_prefix/lib/systemd
%_prefix/lib/systemd/systemd-sysv-install
%files -n udev%{?mini}
%defattr(-,root,root)

View File

@ -1,6 +1,6 @@
From 907bc2aa36f58c6050cd4b7b290e0992a4373e49 Mon Sep 17 00:00:00 2001
From 633a5904c1c4e363a7147f47e2d9fdb1925f7b9f Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de>
Date: Wed, 30 Sep 2015 15:00:41 +0200
Date: Fri, 25 Sep 2015 14:28:58 +0200
Subject: [PATCH] Ask for passphrases not only on the first console of
/dev/console
@ -9,45 +9,22 @@ where often a serial console together with other consoles are
used. Even rack based servers attachted to both a serial console
as well as having a virtual console do sometimes miss a connected
monitor.
To be able to ask on all terminal devices of /dev/console the devices
are collected. If more than one device are found, then on each of the
terminals a inquiring task for passphrase is forked and do not return
to the caller.
Every task has its own session and its own controlling terminal.
If one of the tasks does handle a password, the remaining tasks
will be terminated.
Also let contradictory options on the command of
systemd-tty-ask-password-agent fail.
Spwan for each device of the system console /dev/console a own process.
Replace the system call wait() with with system call waitid().
---
src/tty-ask-password-agent.c | 264 ++++++++++++++++++++-
1 file changed, 255 insertions(+), 9 deletions(-)
src/tty-ask-password-agent/tty-ask-password-agent.c | 191 ++++++++++++++++++++-
1 file changed, 186 insertions(+), 5 deletions(-)
diff --git src/tty-ask-password-agent/tty-ask-password-agent.c src/tty-ask-password-agent/tty-ask-password-agent.c
index 4630eb9..df4bada 100644
index 82cbf95..928a5e8 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -4,6 +4,7 @@
This file is part of systemd.
Copyright 2010 Lennart Poettering
+ Copyright 2015 Werner Fink
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
@@ -31,6 +32,9 @@
@@ -31,6 +31,10 @@
#include <getopt.h>
#include <sys/signalfd.h>
#include <fcntl.h>
+#include <sys/prctl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
#include "util.h"
#include "mkdir.h"
@ -60,7 +37,7 @@ index 4630eb9..df4bada 100644
static enum {
ACTION_LIST,
@@ -53,8 +59,21 @@ static enum {
@@ -53,6 +59,19 @@ static enum {
ACTION_WALL
} arg_action = ACTION_QUERY;
@ -69,101 +46,88 @@ index 4630eb9..df4bada 100644
+ char *tty;
+};
+
+static volatile unsigned long *usemask;
+static volatile sig_atomic_t sigchild;
+
+static void chld_handler(int sig) {
+static void chld_handler(int sig)
+{
+ (void)sig;
+ ++sigchild;
+}
+
static bool arg_plymouth = false;
static bool arg_console = false;
+static bool arg_device = false;
+static const char *current_dev = "/dev/console";
static int ask_password_plymouth(
const char *message,
@@ -211,6 +230,80 @@ static int ask_password_plymouth(
@@ -210,6 +229,69 @@ static int ask_password_plymouth(
return 0;
}
+static void free_consoles(struct console *con, unsigned int num) {
+static void free_consoles(struct console *con, const unsigned int num) {
+ unsigned int n;
+
+ if (!con || num == 0)
+ if (!con || !num)
+ return;
+
+ for (n = 0; n < num; n++)
+ free(con[n].tty);
+
+ free(con);
+}
+
+static int collect_consoles(struct console **consoles, unsigned int *num) {
+static const char *current_dev = "/dev/console";
+static struct console* collect_consoles(unsigned int * num) {
+ _cleanup_free_ char *active = NULL;
+ const char *word, *state;
+ struct console *con = NULL;
+ size_t con_len = 0, len;
+ unsigned int count = 0;
+ int ret;
+
+ assert(num);
+ assert(consoles);
+ assert(*num == 0);
+
+ ret = read_one_line_file("/sys/class/tty/console/active", &active);
+ if (ret < 0)
+ return log_error_errno(ret, "Failed to read /sys/class/tty/console/active: %m");
+
+ return con;
+ FOREACH_WORD(word, len, active, state) {
+ _cleanup_free_ char *tty = NULL;
+
+ if (len == 4 && strneq(word, "tty0", 4)) {
+
+ ret = read_one_line_file("/sys/class/tty/tty0/active", &tty);
+ if (ret < 0)
+ return log_error_errno(ret, "Failed to read /sys/class/tty/tty0/active: %m");
+
+ if (strneq(word, "tty0", len) &&
+ read_one_line_file("/sys/class/tty/tty0/active", &tty) >= 0) {
+ word = tty;
+ len = strlen(tty);
+ }
+
+ con = GREEDY_REALLOC(con, con_len, 1+count);
+ if (!con)
+ return log_oom();
+
+ if (asprintf(&con[count].tty, "/dev/%.*s", (int)len, word) < 0) {
+ free_consoles(con, count);
+ return log_oom();
+ con = greedy_realloc((void**)&con, &con_len, 1+(*num), sizeof(struct console));
+ if (con == NULL) {
+ log_oom();
+ return NULL;
+ }
+
+ con[count].pid = 0;
+ count++;
+ if (asprintf(&con[*num].tty, "/dev/%.*s", (int)len, word) < 0) {
+ free_consoles(con, *num);
+ log_oom();
+ *num = 0;
+ return NULL;
+ }
+ con[*num].pid = 0;
+ (*num)++;
+ }
+
+ if (!con) {
+ con = GREEDY_REALLOC(con, con_len, 1);
+ if (!con)
+ return log_oom();
+
+ if (con == NULL) {
+ con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console));
+ if (con == NULL) {
+ log_oom();
+ return NULL;
+ }
+ con[0].tty = strdup(current_dev);
+ if (!con[0].tty) {
+ if (con[0].tty == NULL) {
+ free_consoles(con, 1);
+ return log_oom();
+ log_oom();
+ return NULL;
+ }
+
+ con[0].pid = 0;
+ count++;
+ (*num)++;
+ }
+
+ *num = count;
+ *consoles = con;
+
+ return 0;
+ return con;
+}
+
static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
uint64_t not_after = 0;
@@ -311,7 +404,7 @@ static int parse_password(const char *fi
@@ -310,7 +392,7 @@ static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *password = NULL;
if (arg_console) {
@ -172,208 +136,137 @@ index 4630eb9..df4bada 100644
if (tty_fd < 0)
return tty_fd;
}
@@ -554,7 +647,7 @@ static int parse_argv(int argc, char *ar
{ "watch", no_argument, NULL, ARG_WATCH },
{ "wall", no_argument, NULL, ARG_WALL },
{ "plymouth", no_argument, NULL, ARG_PLYMOUTH },
- { "console", no_argument, NULL, ARG_CONSOLE },
+ { "console", optional_argument, NULL, ARG_CONSOLE },
{}
};
@@ -598,6 +691,10 @@ static int parse_argv(int argc, char *ar
case ARG_CONSOLE:
arg_console = true;
+ if (optarg && *optarg) {
+ current_dev = optarg;
+ arg_device = true;
+ }
break;
case '?':
@@ -612,9 +709,143 @@ static int parse_argv(int argc, char *ar
return -EINVAL;
}
+ if (arg_plymouth || arg_console) {
+
+ if (!IN_SET(arg_action, ACTION_QUERY, ACTION_WATCH)) {
+ log_error("%s conflicting options --query and --watch.", program_invocation_short_name);
+ return -EINVAL;
+ }
+
+ if (arg_plymouth && arg_console) {
+ log_error("%s conflicting options --plymouth and --console.", program_invocation_short_name);
+ return -EINVAL;
+ }
+ }
+
@@ -614,8 +696,90 @@ static int parse_argv(int argc, char *argv[]) {
return 1;
}
+/*
+ * To be able to ask on all terminal devices of /dev/console
+ * the devices are collected. If more than one device are found,
+ * then on each of the terminals a inquiring task is forked.
+ * Every task has its own session and its own controlling terminal.
+ * If one of the tasks does handle a password, the remaining tasks
+ * will be terminated.
+ */
+static int ask_on_consoles(int argc, char *argv[]) {
+ struct console *consoles = NULL;
+static unsigned int wfa_child(const struct console * con, const unsigned int id)
+{
+ setsid();
+ release_terminal();
+ *usemask |= 1 << id; /* shared memory area */
+ current_dev = con[id].tty;
+ return id;
+}
+
+static unsigned int wait_for_answer(void)
+{
+ struct console *consoles;
+ struct sigaction sig = {
+ .sa_handler = chld_handler,
+ .sa_flags = SA_NOCLDSTOP | SA_RESTART,
+ };
+ struct sigaction oldsig;
+ sigset_t oldset;
+ sigset_t set, oldset;
+ unsigned int num = 0, id;
+ siginfo_t status = {};
+ int ret;
+ int status = 0, ret;
+ pid_t job;
+
+ ret = collect_consoles(&consoles, &num);
+ if (ret < 0)
+ return log_error_errno(ret, "Failed to query password: %m");
+
+ assert_se(sigprocmask_many(SIG_UNBLOCK, &oldset, SIGHUP, SIGCHLD, -1) >= 0);
+
+ assert_se(sigemptyset(&sig.sa_mask) >= 0);
+ assert_se(sigaction(SIGCHLD, &sig, &oldsig) >= 0);
+ consoles = collect_consoles(&num);
+ if (!consoles) {
+ log_error("Failed to query password: %m");
+ exit(EXIT_FAILURE);
+ }
+ if (num < 2)
+ return wfa_child(consoles, 0);
+
+ assert_se(sigemptyset(&set) == 0);
+ assert_se(sigaddset(&set, SIGHUP) == 0);
+ assert_se(sigaddset(&set, SIGCHLD) == 0);
+ assert_se(sigemptyset(&sig.sa_mask) == 0);
+ assert_se(sigprocmask(SIG_UNBLOCK, &set, &oldset) == 0);
+ assert_se(sigaction(SIGCHLD, &sig, &oldsig) == 0);
+ sig.sa_handler = SIG_DFL;
+ assert_se(sigaction(SIGHUP, &sig, NULL) >= 0);
+ assert_se(sigaction(SIGHUP, &sig, NULL) == 0);
+
+ for (id = 0; id < num; id++) {
+ consoles[id].pid = fork();
+
+ if (consoles[id].pid < 0)
+ return log_error_errno(errno, "Failed to query password: %m");
+ if (consoles[id].pid < 0) {
+ log_error("Failed to query password: %m");
+ exit(EXIT_FAILURE);
+ }
+
+ if (consoles[id].pid == 0) {
+ char *conarg;
+ int ac;
+
+ conarg = strjoina("--console=", consoles[id].tty);
+ if (!conarg)
+ return log_oom();
+
+ free_consoles(consoles, num); /* not used anymore */
+
+ assert_se(prctl(PR_SET_PDEATHSIG, SIGHUP) >= 0);
+
+ if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0)
+ _exit(EXIT_FAILURE);
+ zero(sig);
+ assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) >= 0);
+ assert_se(sigaction(SIGCHLD, &oldsig, NULL) >= 0);
+
+ for (ac = 0; ac < argc; ac++) {
+ if (streq(argv[ac], "--console")) {
+ argv[ac] = conarg;
+ break;
+ }
+ }
+
+ execv(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, argv);
+
+ return log_error_errno(errno, "Failed to execute %s: %m", program_invocation_name);
+ assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) == 0);
+ assert_se(sigaction(SIGCHLD, &oldsig, NULL) == 0);
+ return wfa_child(consoles, id);
+ }
+ }
+
+ ret = 0;
+ while (true) {
+
+ if ((ret = waitid(P_ALL, 0, &status, WEXITED)) < 0) {
+
+ if (errno != EINTR) {
+ ret = -errno;
+ if (errno == ECHILD)
+ ret = EXIT_SUCCESS;
+ while ((job = wait(&status)) != 0) {
+ if (job < 0) {
+ if (errno != EINTR)
+ break;
+ }
+ continue;
+ }
+
+ for (id = 0; id < num; id++) {
+ struct timespec timeout;
+ sigset_t set;
+ int signum;
+
+ if (consoles[id].pid == status.si_pid || kill(consoles[id].pid, 0) < 0)
+ consoles[id].pid = -1;
+
+ if (consoles[id].pid < 0)
+ if (consoles[id].pid == job || kill(consoles[id].pid, 0) < 0) {
+ *usemask &= ~(1 << id); /* shared memory area */
+ continue;
+
+ kill(consoles[id].pid, SIGHUP);
+
+ assert_se(sigemptyset(&set) >= 0);
+ assert_se(sigaddset(&set, SIGCHLD) >= 0);
+
+ timespec_store(&timeout, 50 * USEC_PER_MSEC);
+ signum = sigtimedwait(&set, NULL, &timeout);
+
+ if (signum != SIGCHLD) {
+
+ if (signum < 0 && errno != EAGAIN)
+ return log_error_errno(errno, "sigtimedwait() failed: %m");
+
+ if (signum >= 0)
+ log_warning("sigtimedwait() returned unexpected signal.");
+ }
+
+ if (*usemask & (1 << id)) /* shared memory area */
+ continue;
+ kill(consoles[id].pid, SIGHUP);
+ usleep(50000);
+ kill(consoles[id].pid, SIGKILL);
+ }
+
+ if (WIFEXITED(status.si_status) && ret == 0)
+ ret = WEXITSTATUS(status.si_status);
+ if (WIFEXITED(status) && ret == 0)
+ ret = WEXITSTATUS(status);
+ }
+
+ free_consoles(consoles, num);
+
+ return ret;
+ exit(ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS); /* parent */
+}
+
int main(int argc, char *argv[]) {
int r;
- int r;
+ int r, id = 0;
@@ -628,15 +859,28 @@ int main(int argc, char *argv[]) {
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -627,11 +791,27 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- if (arg_console) {
+ /*
+ * Use this shared memory area to be able to synchronize the
+ * workers asking for password with the main process.
+ * This allows to continue if one of the consoles had been
+ * used as afterwards the remaining asking processes will
+ * be terminated. The wait_for_terminate() does not help
+ * for this use case.
+ */
+ usemask = mmap(NULL, sizeof(*usemask), PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+ assert_se(usemask != NULL);
+
if (arg_console) {
- setsid();
- release_terminal();
+ if (arg_console && !arg_device)
+ /*
+ * Spwan for each console device a own process
+ */
+ r = ask_on_consoles(argc, argv);
+ else {
+
+ if (arg_device) {
+ /*
+ * Later on a controlling terminal will be will be acquired,
+ * therefore the current process has to become a session
+ * leader and should not have a controlling terminal already.
+ */
+ (void) setsid();
+ (void) release_terminal();
+ if (!arg_plymouth &&
+ !IN_SET(arg_action, ACTION_WALL, ACTION_LIST)) {
+ id = wait_for_answer();
+ } else {
+ setsid();
+ release_terminal();
+ }
+
+ if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
+ r = watch_passwords();
+ else
+ r = show_passwords();
}
-
- if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
- r = watch_passwords();
- else
- r = show_passwords();
if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
r = watch_passwords();
else
@@ -640,6 +820,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error_errno(r, "Error: %m");
+ *usemask &= ~(1 << id); /* shared memory area */
finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
2.2.0