summaryrefslogtreecommitdiffstats
path: root/login-utils/sulogin.c
diff options
context:
space:
mode:
authorWerner Fink2014-05-08 12:09:22 +0200
committerKarel Zak2014-05-13 10:36:49 +0200
commitbb280f79f188f910c41e97fd5fa8889ae8b76d62 (patch)
tree9dafc3acb6655834b49c17cfa1e4e2e884854cd0 /login-utils/sulogin.c
parentcfdisk: fix compiler warning [-Wsign-compare] (diff)
downloadkernel-qcow2-util-linux-bb280f79f188f910c41e97fd5fa8889ae8b76d62.tar.gz
kernel-qcow2-util-linux-bb280f79f188f910c41e97fd5fa8889ae8b76d62.tar.xz
kernel-qcow2-util-linux-bb280f79f188f910c41e97fd5fa8889ae8b76d62.zip
agetty: avoid that agetty nor sulogin are fooled by a running plymouth
The nowadays used plymouth locks the devices used for the system console which causes that agetty as well as sulogin can not modify the termios settings of e.g. the serial devices of the systenm console. Signed-off-by: Werner Fink <werner@suse.de>
Diffstat (limited to 'login-utils/sulogin.c')
-rw-r--r--login-utils/sulogin.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
index 37d006dde..1e227a863 100644
--- a/login-utils/sulogin.c
+++ b/login-utils/sulogin.c
@@ -77,13 +77,62 @@ static volatile sig_atomic_t sigchild;
#endif
/*
+ * For the case plymouth is found on this system
+ */
+static int plymouth_command(const char* arg)
+{
+ const char *cmd = "/usr/bin/plymouth";
+ static int has_plymouth = 1;
+ pid_t pid;
+
+ if (!has_plymouth)
+ return 127;
+
+ pid = fork();
+ if (!pid) {
+ int fd = open("/dev/null", O_RDWR);
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
+ execl(cmd, cmd, arg, (char *) NULL);
+ exit(127);
+ } else if (pid > 0) {
+ int status;
+ waitpid(pid, &status, 0);
+ if (status == 127)
+ has_plymouth = 0;
+ return status;
+ }
+ return 1;
+}
+
+/*
* Fix the tty modes and set reasonable defaults.
*/
static void tcinit(struct console *con)
{
int mode = 0, flags = 0;
struct termios *tio = &con->tio;
- int fd = con->fd;
+ struct termios lock;
+ int fd = con->fd, i = (plymouth_command("--ping")) ? 20 : 0;
+
+ while (i-- > 0) {
+ /*
+ * With plymouth the termios flags become changed after this
+ * function had changed the termios.
+ */
+ memset(&lock, 0, sizeof(struct termios));
+ if (ioctl(fd, TIOCGLCKTRMIOS, &lock) < 0)
+ break;
+ if (!lock.c_iflag && !lock.c_oflag && !lock.c_cflag && !lock.c_lflag)
+ break;
+ if (i == 15 && plymouth_command("quit") != 0)
+ break;
+ sleep(1);
+ }
+ memset(&lock, 0, sizeof(struct termios));
+ ioctl(fd, TIOCSLCKTRMIOS, &lock);
errno = 0;