mirror of
https://github.com/AuxXxilium/eudev.git
synced 2025-01-27 01:20:00 +07:00
systemctl: shutdown agent explicitly so that it can reset the tty properly
This commit is contained in:
parent
6d55002a69
commit
c0f9c7da07
5
TODO
5
TODO
@ -6,9 +6,6 @@ F15:
|
||||
|
||||
* isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target
|
||||
|
||||
* increase password timeout
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=677962
|
||||
|
||||
* finish syslog socket stuff
|
||||
|
||||
* load EnvironmentFile= when starting services, not when reloading configuration
|
||||
@ -19,8 +16,6 @@ F15:
|
||||
|
||||
* NFS, networkmanager ordering issue
|
||||
|
||||
* Make systemd-cryptsetup cancellable
|
||||
|
||||
* add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target
|
||||
|
||||
* hook emergency.target into local-fs.target in some way as OnFailure with isolate
|
||||
|
@ -180,7 +180,6 @@ int ask_password_tty(
|
||||
}
|
||||
|
||||
if (ttyfd >= 0)
|
||||
loop_write(ttyfd, "\n", 1, false);
|
||||
|
||||
passphrase[p] = 0;
|
||||
|
||||
@ -196,8 +195,11 @@ finish:
|
||||
close_nointr_nofail(notify);
|
||||
|
||||
if (ttyfd >= 0) {
|
||||
if (reset_tty)
|
||||
|
||||
if (reset_tty) {
|
||||
loop_write(ttyfd, "\n", 1, false);
|
||||
tcsetattr(ttyfd, TCSADRAIN, &old_termios);
|
||||
}
|
||||
|
||||
close_nointr_nofail(ttyfd);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ static int open_dev_autofs(Manager *m) {
|
||||
if (m->dev_autofs_fd >= 0)
|
||||
return m->dev_autofs_fd;
|
||||
|
||||
label_fix("/dev/autofs", false);
|
||||
label_fix("/dev/autofs", false);
|
||||
|
||||
if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) {
|
||||
log_error("Failed to open /dev/autofs: %s", strerror(errno));
|
||||
|
@ -112,6 +112,7 @@ static enum dot {
|
||||
static bool private_bus = false;
|
||||
|
||||
static pid_t pager_pid = 0;
|
||||
static pid_t agent_pid = 0;
|
||||
|
||||
static int daemon_reload(DBusConnection *bus, char **args, unsigned n);
|
||||
static void pager_open(void);
|
||||
@ -132,7 +133,10 @@ static bool on_tty(void) {
|
||||
}
|
||||
|
||||
static void spawn_ask_password_agent(void) {
|
||||
pid_t parent, child;
|
||||
pid_t parent;
|
||||
|
||||
if (agent_pid > 0)
|
||||
return;
|
||||
|
||||
/* We check STDIN here, not STDOUT, since this is about input,
|
||||
* not output */
|
||||
@ -150,16 +154,11 @@ static void spawn_ask_password_agent(void) {
|
||||
/* Spawns a temporary TTY agent, making sure it goes away when
|
||||
* we go away */
|
||||
|
||||
if ((child = fork()) < 0)
|
||||
if ((agent_pid = fork()) < 0)
|
||||
return;
|
||||
|
||||
if (child == 0) {
|
||||
if (agent_pid == 0) {
|
||||
/* In the child */
|
||||
const char * const args[] = {
|
||||
SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
|
||||
"--watch",
|
||||
NULL
|
||||
};
|
||||
|
||||
int fd;
|
||||
bool stdout_is_tty, stderr_is_tty;
|
||||
@ -202,7 +201,9 @@ static void spawn_ask_password_agent(void) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
execv(args[0], (char **) args);
|
||||
execl(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL);
|
||||
|
||||
log_error("Unable to execute agent: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -5447,6 +5448,7 @@ static int runlevel_main(void) {
|
||||
static void pager_open(void) {
|
||||
int fd[2];
|
||||
const char *pager;
|
||||
pid_t parent_pid;
|
||||
|
||||
if (pager_pid > 0)
|
||||
return;
|
||||
@ -5467,6 +5469,8 @@ static void pager_open(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent_pid = getpid();
|
||||
|
||||
pager_pid = fork();
|
||||
if (pager_pid < 0) {
|
||||
log_error("Failed to fork pager: %m");
|
||||
@ -5482,7 +5486,14 @@ static void pager_open(void) {
|
||||
|
||||
setenv("LESS", "FRSX", 0);
|
||||
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
/* Make sure the pager goes away when the parent dies */
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
/* Check whether our parent died before we were able
|
||||
* to set the death signal */
|
||||
if (getppid() != parent_pid)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
if (pager) {
|
||||
execlp(pager, pager, NULL);
|
||||
@ -5523,6 +5534,18 @@ static void pager_close(void) {
|
||||
pager_pid = 0;
|
||||
}
|
||||
|
||||
static void agent_close(void) {
|
||||
siginfo_t dummy;
|
||||
|
||||
if (agent_pid <= 0)
|
||||
return;
|
||||
|
||||
/* Inform agent that we are done */
|
||||
kill(agent_pid, SIGTERM);
|
||||
wait_for_terminate(agent_pid, &dummy);
|
||||
agent_pid = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[]) {
|
||||
int r, retval = EXIT_FAILURE;
|
||||
DBusConnection *bus = NULL;
|
||||
@ -5605,6 +5628,7 @@ finish:
|
||||
strv_free(arg_property);
|
||||
|
||||
pager_close();
|
||||
agent_close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ static int ask_password_plymouth(
|
||||
sa.sa.sa_family = AF_UNIX;
|
||||
strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
|
||||
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
|
||||
log_error("FAILED TO CONNECT: %m");
|
||||
log_error("Failed to connect to Plymouth: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user