mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 13:33:09 +07:00
Refactor built-in getty into a standalone getty in /libexec
This patch moves the built-in getty out of Finit into /libexec/finit/, reducing the size of the Finit binary and simplifying the code. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
.deps/*
|
||||
finit
|
||||
getty
|
||||
initctl
|
||||
keventd
|
||||
logit
|
||||
|
||||
+7
-2
@@ -8,7 +8,7 @@ AM_LDFLAGS = -export-dynamic
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = finit initctl
|
||||
pkglibexec_PROGRAMS = logit sulogin
|
||||
pkglibexec_PROGRAMS = getty logit sulogin
|
||||
if KEVENTD
|
||||
pkglibexec_PROGRAMS += keventd
|
||||
endif
|
||||
@@ -19,6 +19,11 @@ endif
|
||||
finit_pkglibdir = $(pkglibdir)
|
||||
finit_pkglib_SCRIPTS = rescue.conf sample.conf
|
||||
|
||||
getty_SOURCES = getty.c helpers.h logrotate.c stty.c utmp-api.c utmp-api.h
|
||||
getty_CFLAGS = -W -Wall -Wextra -std=gnu99
|
||||
getty_CFLAGS += $(lite_CFLAGS)
|
||||
getty_LDADD = $(lite_LIBS)
|
||||
|
||||
keventd_SOURCES = keventd.c iwatch.c iwatch.h util.c util.h
|
||||
keventd_CFLAGS = -W -Wall -Wextra -std=gnu99
|
||||
keventd_CFLAGS += $(lite_CFLAGS)
|
||||
@@ -37,7 +42,7 @@ finit_SOURCES = api.c cgroup.c cgroup.h \
|
||||
cond.c cond-w.c cond.h \
|
||||
conf.c conf.h \
|
||||
exec.c finit.c finit.h \
|
||||
getty.c stty.c \
|
||||
stty.c \
|
||||
helpers.c helpers.h \
|
||||
iwatch.c iwatch.h \
|
||||
log.c log.h \
|
||||
|
||||
+39
-2
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <ctype.h> /* isdigit() */
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/prctl.h>
|
||||
@@ -388,9 +389,19 @@ pid_t run_getty(char *tty, char *baud, char *term, int noclear, int nowait, stru
|
||||
speed = stty_parse_speed(baud);
|
||||
prepare_tty(tty, speed, "tty", rlimit);
|
||||
if (activate_console(noclear, nowait)) {
|
||||
logit(LOG_INFO, "Starting built-in getty on %s, speed %u", tty, speed);
|
||||
rc = getty(tty, speed, term, NULL);
|
||||
char spd[15];
|
||||
char *args[5] = {
|
||||
"getty",
|
||||
tty,
|
||||
spd,
|
||||
term,
|
||||
NULL
|
||||
};
|
||||
snprintf(spd, sizeof(spd), "%d", speed);
|
||||
logit(LOG_ERR, "Starting built-in getty on %s, speed %u", tty, speed);
|
||||
rc = execv("/libexec/finit/getty", args);
|
||||
}
|
||||
logit(LOG_ERR, "Failed starting built-in getty on %s, speed %u", tty, speed);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -414,6 +425,32 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait, st
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sh(char *tty)
|
||||
{
|
||||
char *args[2] = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char *arg0;
|
||||
size_t len;
|
||||
|
||||
/* The getty process is usually responsible for the UTMP login record */
|
||||
utmp_set_login(tty, NULL);
|
||||
|
||||
/* Start /bin/sh as a login shell, i.e. with a prefix '-' */
|
||||
len = strlen(_PATH_BSHELL) + 2;
|
||||
arg0 = malloc(len);
|
||||
if (!arg0)
|
||||
err(1, "Failed allocating memory");
|
||||
snprintf(arg0, len, "-%s", _PATH_BSHELL);
|
||||
args[0] = arg0;
|
||||
|
||||
/* Unblock signals inherited from parent */
|
||||
sig_unblock();
|
||||
|
||||
return execv(_PATH_BSHELL, args);
|
||||
}
|
||||
|
||||
pid_t run_sh(char *tty, int noclear, int nowait, struct rlimit rlimit[])
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
+30
-65
@@ -26,15 +26,13 @@
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
||||
#include <termios.h>
|
||||
|
||||
#include "finit.h"
|
||||
#include "cgroup.h"
|
||||
#include "helpers.h"
|
||||
#include "sig.h"
|
||||
#include "utmp-api.h"
|
||||
|
||||
#ifndef _PATH_LOGIN
|
||||
@@ -44,19 +42,14 @@
|
||||
/*
|
||||
* Read one character from stdin.
|
||||
*/
|
||||
static int readch(char *tty)
|
||||
static int readch(void)
|
||||
{
|
||||
int st;
|
||||
char ch1;
|
||||
int st;
|
||||
|
||||
st = read(STDIN_FILENO, &ch1, 1);
|
||||
if (st == 0) {
|
||||
dprint(STDOUT_FILENO, "\n", 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (st < 0)
|
||||
errx(1, "getty: %s: read error", tty);
|
||||
if (st <= 0)
|
||||
return -1;
|
||||
|
||||
return ch1 & 0xFF;
|
||||
}
|
||||
@@ -141,10 +134,10 @@ static void do_issue(char *tty)
|
||||
/*
|
||||
* Handle the process of a GETTY.
|
||||
*/
|
||||
static void do_getty(char *tty, char *name, size_t len)
|
||||
static int get_logname(char *tty, char *name, size_t len)
|
||||
{
|
||||
int ch;
|
||||
char *np;
|
||||
int ch;
|
||||
|
||||
/*
|
||||
* Display prompt.
|
||||
@@ -155,14 +148,9 @@ static void do_getty(char *tty, char *name, size_t len)
|
||||
do_issue(tty);
|
||||
|
||||
np = name;
|
||||
while ((ch = readch(tty)) != '\n') {
|
||||
if (ch == CTRL('U')) {
|
||||
while (np > name) {
|
||||
dprint(STDOUT_FILENO, "\b \b", 3);
|
||||
np--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
while ((ch = readch()) != '\n') {
|
||||
if (ch < 0)
|
||||
return 1;
|
||||
|
||||
if (np < name + len)
|
||||
*np++ = ch;
|
||||
@@ -174,6 +162,7 @@ static void do_getty(char *tty, char *name, size_t len)
|
||||
}
|
||||
|
||||
name[len - 1] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -185,7 +174,6 @@ static int do_login(char *name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
cgroup_user(name, 0);
|
||||
execl(_PATH_LOGIN, _PATH_LOGIN, name, NULL);
|
||||
|
||||
/*
|
||||
@@ -196,12 +184,12 @@ static int do_login(char *name)
|
||||
*/
|
||||
warnx("Failed exec %s, attempting fallback to %s ...", _PATH_LOGIN, _PATH_BSHELL);
|
||||
if (fstat(0, &st) == 0 && S_ISCHR(st.st_mode))
|
||||
execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
|
||||
execl(_PATH_BSHELL, _PATH_BSHELL, NULL); /* XXX: run sulogin instead! */
|
||||
|
||||
return 1; /* We shouldn't get here ... */
|
||||
}
|
||||
|
||||
int getty(char *tty, speed_t speed, char *term, char *user)
|
||||
static int getty(char *tty, speed_t speed, char *term, char *user)
|
||||
{
|
||||
const char cln[] = "\r\e[2K\n";
|
||||
char name[33]; /* useradd(1) limit at 32 chars */
|
||||
@@ -212,15 +200,20 @@ int getty(char *tty, speed_t speed, char *term, char *user)
|
||||
if (!strncmp(tty, _PATH_DEV, strlen(_PATH_DEV)))
|
||||
tty += 5;
|
||||
|
||||
/* Set up TTY, re-enabling ISIG et al. */
|
||||
stty(STDIN_FILENO, speed);
|
||||
dprint(STDERR_FILENO, cln, strlen(cln));
|
||||
|
||||
/* The getty process is responsible for the UTMP login record */
|
||||
utmp_set_login(tty, NULL);
|
||||
if (!user)
|
||||
do_getty(tty, name, sizeof(name));
|
||||
else
|
||||
|
||||
/* Replace "Please press enter ..." with login: */
|
||||
dprint(STDERR_FILENO, cln, strlen(cln));
|
||||
|
||||
restart:
|
||||
stty(STDIN_FILENO, speed);
|
||||
if (!user) {
|
||||
if (get_logname(tty, name, sizeof(name))) {
|
||||
sleep(5);
|
||||
goto restart;
|
||||
}
|
||||
} else
|
||||
strlcpy(name, user, sizeof(name));
|
||||
|
||||
if (term && term[0])
|
||||
@@ -229,42 +222,14 @@ int getty(char *tty, speed_t speed, char *term, char *user)
|
||||
return do_login(name);
|
||||
}
|
||||
|
||||
int sh(char *tty)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct termios term;
|
||||
char *args[2] = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char *arg0;
|
||||
size_t len;
|
||||
|
||||
/* The getty process is usually responsible for the UTMP login record */
|
||||
utmp_set_login(tty, NULL);
|
||||
|
||||
/* Set up TTY, re-enabling ISIG et al. */
|
||||
stty(STDIN_FILENO, B0);
|
||||
|
||||
/* Start /bin/sh as a login shell, i.e. with a prefix '-' */
|
||||
len = strlen(_PATH_BSHELL) + 2;
|
||||
arg0 = malloc(len);
|
||||
if (!arg0)
|
||||
err(1, "Failed allocating memory");
|
||||
snprintf(arg0, len, "-%s", _PATH_BSHELL);
|
||||
args[0] = arg0;
|
||||
|
||||
/* Reenable Ctrl-D and Ctrl-C, and ... */
|
||||
if (!tcgetattr(STDIN_FILENO, &term)) {
|
||||
term.c_lflag |= ISIG;
|
||||
term.c_cc[VEOF] = CEOF;
|
||||
term.c_cc[VINTR] = CINTR;
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term);
|
||||
if (argc < 4) {
|
||||
warnx("usage: getty tty speed term");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ... unblock signals in general */
|
||||
sig_unblock();
|
||||
|
||||
return execv(_PATH_BSHELL, args);
|
||||
return getty(argv[1], atoi(argv[2]), argv[3], NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-4
@@ -68,11 +68,8 @@ char *strip_line (char *line);
|
||||
void enable_progress (int onoff);
|
||||
void show_progress (pstyle_t style);
|
||||
|
||||
int getty (char *tty, speed_t speed, char *term, char *user);
|
||||
int sh (char *tty);
|
||||
|
||||
void stty (int fd, speed_t speed);
|
||||
speed_t stty_parse_speed(char *baud);
|
||||
void stty (int fd, speed_t speed);
|
||||
|
||||
void print_banner (const char *heading);
|
||||
void printv (const char *fmt, va_list ap);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "service.h"
|
||||
#include "cgutil.h"
|
||||
#include "util.h"
|
||||
#include "utmp-api.h"
|
||||
|
||||
struct cmd {
|
||||
char *cmd;
|
||||
|
||||
-10
@@ -229,16 +229,6 @@ int fngetint(char *path, int *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* musl libc default to /dev/null/utmp and /dev/null/wtmp, respectively.
|
||||
* See https://www.openwall.com/lists/musl/2012/03/04/4 for reasoning.
|
||||
* Also, there's no __MUSL__, so we cannot make a libc-specific #ifdef
|
||||
*/
|
||||
int has_utmp(void)
|
||||
{
|
||||
return strncmp(_PATH_UTMP, "/dev/null", 9);
|
||||
}
|
||||
|
||||
int strtobytes(char *arg)
|
||||
{
|
||||
int mod = 0, bytes;
|
||||
|
||||
@@ -54,7 +54,6 @@ int fnread (char *buf, size_t len, char *fmt, ...);
|
||||
int fnwrite (char *value, char *fmt, ...);
|
||||
int fngetint (char *path, int *val);
|
||||
|
||||
int has_utmp (void);
|
||||
int strtobytes (char *arg);
|
||||
char *sig2str (int sig);
|
||||
char *code2str (int code);
|
||||
|
||||
@@ -42,6 +42,16 @@ int utmp_show (char *file);
|
||||
|
||||
void runlevel_set (int pre, int now);
|
||||
|
||||
/*
|
||||
* musl libc default to /dev/null/utmp and /dev/null/wtmp, respectively.
|
||||
* See https://www.openwall.com/lists/musl/2012/03/04/4 for reasoning.
|
||||
* Also, there's no __MUSL__, so we cannot make a libc-specific #ifdef
|
||||
*/
|
||||
static inline int has_utmp(void)
|
||||
{
|
||||
return strncmp(_PATH_UTMP, "/dev/null", 9);
|
||||
}
|
||||
|
||||
#endif /* FINIT_UTMP_API_H_ */
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user