[PATCH] Use the plymouth local protocol instead the plymouth binary

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



for stopping plymouthd.  That do not depend on the existence of
the plymouth binary if it e.g. becomes uninstalled or an other
service is providing plymouthd facilities.

Signed-off-by: Werner Fink <werner@xxxxxxx>
---
 include/plymouth-ctrl.h |  64 ++++++++++++++++++++++
 lib/Makemodule.am       |   1 +
 lib/plymouth-ctrl.c     | 140 ++++++++++++++++++++++++++++++++++++++++++++++++
 login-utils/sulogin.c   |  44 ++-------------
 term-utils/agetty.c     |  48 +++--------------
 5 files changed, 215 insertions(+), 82 deletions(-)
 create mode 100644 include/plymouth-ctrl.h
 create mode 100644 lib/plymouth-ctrl.c

diff --git include/plymouth-ctrl.h include/plymouth-ctrl.h
new file mode 100644
index 0000000..27c5ebc
--- /dev/null
+++ include/plymouth-ctrl.h
@@ -0,0 +1,64 @@
+/*
+ * plymouth-ctrl.h	Header file for communcations with plymouthd
+ *
+ * Copyright (c) 2016 SUSE Linux GmbH, All rights reserved.
+ * Copyright (c) 2016 Werner Fink <werner@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *  
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: Werner Fink <werner@xxxxxxx>
+ */
+
+/*
+ * Taken from plymouth 0.9.0 src/ply-boot-protocol.h
+ */
+
+#ifndef UTIL_LINUX_PLYMOUTH_CTRL_H
+#define UTIL_LINUX_PLYMOUTH_CTRL_H
+
+#define PLYMOUTH_SOCKET_PATH	"\0/org/freedesktop/plymouthd"
+#define ANSWER_TYP		'\x2'
+#define ANSWER_ENQ		'\x5'
+#define ANSWER_ACK		'\x6'
+#define ANSWER_MLT		'\t'
+#define ANSWER_NCK		'\x15'
+
+#define MAGIC_PRG_STOP		'A'
+#define MAGIC_PRG_CONT		'a'
+#define MAGIC_UPDATE		'U'
+#define MAGIC_SYS_UPDATE	'u'
+#define MAGIC_SYS_INIT		'S'
+#define MAGIC_DEACTIVATE	'D'
+#define MAGIC_REACTIVATE	'r'
+#define MAGIC_SHOW_SPLASH	'$'
+#define MAGIC_HIDE_SPLASH	'H'
+#define MAGIC_CHMOD		'C'
+#define MAGIC_CHROOT		'R'
+#define MAGIC_ACTIVE_VT		'V'
+#define MAGIC_QUESTION		'W'
+#define MAGIC_SHOW_MSG		'M'
+#define MAGIC_HIDE_MSG		'm'
+#define MAGIC_KEYSTROKE		'K'
+#define MAGIC_KEYSTROKE_RM	'L'
+#define MAGIC_PING		'P'
+#define MAGIC_QUIT		'Q'
+#define MAGIC_CACHED_PWD	'c'
+#define MAGIC_ASK_PWD		'*'
+#define MAGIC_DETAILS		'!'
+
+extern int plymouth_command(int cmd, ...);
+
+#endif /* UTIL_LINUX_PLYMOUTH_CTRL_H */
diff --git lib/Makemodule.am lib/Makemodule.am
index 054b816..cbf5cee 100644
--- lib/Makemodule.am
+++ lib/Makemodule.am
@@ -16,6 +16,7 @@ libcommon_la_SOURCES = \
 	lib/md5.c \
 	lib/pager.c \
 	lib/path.c \
+	lib/plymouth-ctrl.c \
 	lib/randutils.c \
 	lib/setproctitle.c \
 	lib/strutils.c \
diff --git lib/plymouth-ctrl.c lib/plymouth-ctrl.c
new file mode 100644
index 0000000..3a038c8
--- /dev/null
+++ lib/plymouth-ctrl.c
@@ -0,0 +1,140 @@
+/*
+ * plymouth-ctrl.c	Simply communcations with plymouthd
+ *			to avoid forked sub processes and/or
+ *			misssed plymouth send commands tool
+ *			due a plymouthd replacment.
+ *
+ * Copyright (c) 2016 SUSE Linux GmbH, All rights reserved.
+ * Copyright (c) 2016 Werner Fink <werner@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: Werner Fink <werner@xxxxxxx>
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "all-io.h"
+#include "c.h"
+#include "nls.h"
+#include "plymouth-ctrl.h"
+
+static int can_read(int fd, const long timeout)
+{
+	struct pollfd fds = {
+		.fd = fd,
+		.events = POLLIN|POLLPRI,
+		.revents = 0,
+	};
+	int ret;
+
+	do {
+		ret = poll(&fds, 1, timeout);
+	} while ((ret < 0) && (errno == EINTR));
+
+	return (ret == 1) && (fds.revents & (POLLIN|POLLPRI));
+}
+
+static int open_un_socket_and_connect(void)
+{
+	struct sockaddr_un su = {		/* The abstract UNIX socket of plymouth */
+		.sun_family = AF_UNIX,
+		.sun_path = PLYMOUTH_SOCKET_PATH,
+	};
+	const int one = 1;
+	int fd, ret;
+
+	fd = socket(PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+	if (fd < 0) {
+		warnx(_("can not open UNIX socket"));
+		goto err;
+	}
+
+	ret = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, (socklen_t)sizeof(one));
+	if (ret < 0) {
+		warnx(_("can not set option for UNIX socket"));
+		close(fd);
+		fd = -1;
+		goto err;
+	}
+
+	ret = connect(fd, &su, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(su.sun_path+1));
+	if (ret < 0) {
+		if (errno != ECONNREFUSED)
+			warnx(_("can not connect on UNIX socket"));
+		close(fd);
+		fd = -1;
+		goto err;
+	}
+err:
+	return fd;
+}
+
+int plymouth_command(int cmd, ...)
+{
+	char answer[2], command[2];
+	struct sigaction sp, op;
+	int fdsock = -1, ret = 0;
+
+	sigemptyset (&sp.sa_mask);
+	sp.sa_handler = SIG_IGN;
+	sp.sa_flags = SA_RESTART;
+	sigaction(SIGPIPE, &sp, &op);
+
+	command[1] = '\0';
+	switch (cmd) {
+	case MAGIC_PING:
+		fdsock = open_un_socket_and_connect();
+		if (fdsock >= 0) {
+			command[0] = cmd;
+			write_all(fdsock, command, strlen(command)+1);
+		}
+		break;
+	case MAGIC_QUIT:
+		fdsock = open_un_socket_and_connect();
+		if (fdsock >= 0) {
+			command[0] = cmd;
+			write_all(fdsock, command, strlen(command)+1);
+		}
+		break;
+	default:
+		warnx(_("the plymouth request %c is not implemented"), cmd);
+	case '?':
+		goto err;
+	}
+
+	answer[0] = '\0';
+	if (fdsock >= 0) {
+		if (can_read(fdsock, 1000))
+			read_all(fdsock, &answer[0], sizeof(answer));
+		close(fdsock);
+	}
+	sigaction(SIGPIPE, &op, NULL);
+	ret = (answer[0] == ANSWER_ACK) ? 1 : 0;
+err:
+	return ret;
+}
+
diff --git login-utils/sulogin.c login-utils/sulogin.c
index 601d38c..9d941e1 100644
--- login-utils/sulogin.c
+++ login-utils/sulogin.c
@@ -58,6 +58,7 @@
 #include "closestream.h"
 #include "nls.h"
 #include "pathnames.h"
+#include "plymouth-ctrl.h"
 #include "strutils.h"
 #include "ttyutils.h"
 #include "sulogin-consoles.h"
@@ -92,42 +93,6 @@ static int locked_account_password(const char *passwd)
 	return 0;
 }
 
-#ifdef TIOCGLCKTRMIOS
-/*
- * 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);
-		if (fd < 0)
-			exit(127);
-		dup2(fd, 0);
-		dup2(fd, 1);
-		dup2(fd, 2);
-		if (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;
-}
-#endif
-
 /*
  * Fix the tty modes and set reasonable defaults.
  */
@@ -138,8 +103,9 @@ static void tcinit(struct console *con)
 	struct termios lock;
 	int fd = con->fd;
 #ifdef TIOCGLCKTRMIOS
-	int i = (plymouth_command("--ping")) ? 20 : 0;
-
+	int i = (plymouth_command(MAGIC_PING)) ? 20 : 0;
+	if (i)
+		plymouth_command(MAGIC_QUIT);
 	while (i-- > 0) {
 		/*
 		 * With plymouth the termios flags become changed after this
@@ -150,8 +116,6 @@ static void tcinit(struct console *con)
 			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));
diff --git term-utils/agetty.c term-utils/agetty.c
index 6d610c6..a00ae3d 100644
--- term-utils/agetty.c
+++ term-utils/agetty.c
@@ -41,6 +41,7 @@
 #include "all-io.h"
 #include "nls.h"
 #include "pathnames.h"
+#include "plymouth-ctrl.h"
 #include "c.h"
 #include "widechar.h"
 #include "ttyutils.h"
@@ -138,9 +139,6 @@ static int inotify_fd = AGETTY_RELOAD_FDNONE;
 static int netlink_fd = AGETTY_RELOAD_FDNONE;
 #endif
 
-#define AGETTY_PLYMOUTH		"/usr/bin/plymouth"
-#define AGETTY_PLYMOUTH_FDFILE	"/dev/null"
-
 /*
  * When multiple baud rates are specified on the command line, the first one
  * we will try is the first one specified.
@@ -309,7 +307,6 @@ static void log_warn (const char *, ...)
 static ssize_t append(char *dest, size_t len, const char  *sep, const char *src);
 static void check_username (const char* nm);
 static void login_options_to_argv(char *argv[], int *argc, char *str, char *username);
-static int plymouth_command(const char* arg);
 static void reload_agettys(void);
 
 /* Fake hostname for ut_host specified on command line. */
@@ -1180,8 +1177,9 @@ static void termio_init(struct options *op, struct termios *tp)
 	struct winsize ws;
 	struct termios lock;
 #ifdef TIOCGLCKTRMIOS
-	int i =  (plymouth_command("--ping") == 0) ? 30 : 0;
-
+	int i =  (plymouth_command(MAGIC_PING) == 0) ? 30 : 0;
+	if (i)
+		plymouth_command(MAGIC_QUIT);
 	while (i-- > 0) {
 		/*
 		 * Even with TTYReset=no it seems with systemd or plymouth
@@ -1194,8 +1192,6 @@ static void termio_init(struct options *op, struct termios *tp)
 		if (!lock.c_iflag && !lock.c_oflag && !lock.c_cflag && !lock.c_lflag)
 			break;
 		debug("termios locked\n");
-		if (i == 15 && plymouth_command("quit") != 0)
-			break;
 		sleep(1);
 	}
 	memset(&lock, 0, sizeof(struct termios));
@@ -1725,7 +1721,9 @@ static void print_issue_file(struct options *op, struct termios *tp)
 /* Show login prompt, optionally preceded by /etc/issue contents. */
 static void do_prompt(struct options *op, struct termios *tp)
 {
+#ifdef AGETTY_RELOAD
 again:
+#endif
 	print_issue_file(op, tp);
 
 	if (op->flags & F_LOGINPAUSE) {
@@ -2596,40 +2594,6 @@ err:
 	log_err(_("checkname failed: %m"));
 }
 
-/*
- * For the case plymouth is found on this system
- */
-static int plymouth_command(const char* arg)
-{
-	static int has_plymouth = 1;
-	pid_t pid;
-
-	if (!has_plymouth)
-		return 127;
-
-	pid = fork();
-	if (!pid) {
-		int fd = open(AGETTY_PLYMOUTH_FDFILE, O_RDWR);
-
-		if (fd < 0)
-			err(EXIT_FAILURE,_("cannot open %s"),
-					AGETTY_PLYMOUTH_FDFILE);
-		dup2(fd, 0);
-		dup2(fd, 1);
-		dup2(fd, 2);
-		close(fd);
-		execl(AGETTY_PLYMOUTH, AGETTY_PLYMOUTH, 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;
-}
-
 static void reload_agettys(void)
 {
 #ifdef AGETTY_RELOAD
-- 
2.6.6

--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux