mirror of
https://github.com/troglobit/finit.git
synced 2026-10-06 07:43:43 +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/*
|
.deps/*
|
||||||
finit
|
finit
|
||||||
|
getty
|
||||||
initctl
|
initctl
|
||||||
keventd
|
keventd
|
||||||
logit
|
logit
|
||||||
|
|||||||
+7
-2
@@ -8,7 +8,7 @@ AM_LDFLAGS = -export-dynamic
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
sbin_PROGRAMS = finit initctl
|
sbin_PROGRAMS = finit initctl
|
||||||
pkglibexec_PROGRAMS = logit sulogin
|
pkglibexec_PROGRAMS = getty logit sulogin
|
||||||
if KEVENTD
|
if KEVENTD
|
||||||
pkglibexec_PROGRAMS += keventd
|
pkglibexec_PROGRAMS += keventd
|
||||||
endif
|
endif
|
||||||
@@ -19,6 +19,11 @@ endif
|
|||||||
finit_pkglibdir = $(pkglibdir)
|
finit_pkglibdir = $(pkglibdir)
|
||||||
finit_pkglib_SCRIPTS = rescue.conf sample.conf
|
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_SOURCES = keventd.c iwatch.c iwatch.h util.c util.h
|
||||||
keventd_CFLAGS = -W -Wall -Wextra -std=gnu99
|
keventd_CFLAGS = -W -Wall -Wextra -std=gnu99
|
||||||
keventd_CFLAGS += $(lite_CFLAGS)
|
keventd_CFLAGS += $(lite_CFLAGS)
|
||||||
@@ -37,7 +42,7 @@ finit_SOURCES = api.c cgroup.c cgroup.h \
|
|||||||
cond.c cond-w.c cond.h \
|
cond.c cond-w.c cond.h \
|
||||||
conf.c conf.h \
|
conf.c conf.h \
|
||||||
exec.c finit.c finit.h \
|
exec.c finit.c finit.h \
|
||||||
getty.c stty.c \
|
stty.c \
|
||||||
helpers.c helpers.h \
|
helpers.c helpers.h \
|
||||||
iwatch.c iwatch.h \
|
iwatch.c iwatch.h \
|
||||||
log.c log.h \
|
log.c log.h \
|
||||||
|
|||||||
+39
-2
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <ctype.h> /* isdigit() */
|
#include <ctype.h> /* isdigit() */
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/prctl.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);
|
speed = stty_parse_speed(baud);
|
||||||
prepare_tty(tty, speed, "tty", rlimit);
|
prepare_tty(tty, speed, "tty", rlimit);
|
||||||
if (activate_console(noclear, nowait)) {
|
if (activate_console(noclear, nowait)) {
|
||||||
logit(LOG_INFO, "Starting built-in getty on %s, speed %u", tty, speed);
|
char spd[15];
|
||||||
rc = getty(tty, speed, term, NULL);
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -414,6 +425,32 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait, st
|
|||||||
return rc;
|
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[])
|
pid_t run_sh(char *tty, int noclear, int nowait, struct rlimit rlimit[])
|
||||||
{
|
{
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
|
|||||||
+30
-65
@@ -26,15 +26,13 @@
|
|||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#include "finit.h"
|
|
||||||
#include "cgroup.h"
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "sig.h"
|
|
||||||
#include "utmp-api.h"
|
#include "utmp-api.h"
|
||||||
|
|
||||||
#ifndef _PATH_LOGIN
|
#ifndef _PATH_LOGIN
|
||||||
@@ -44,19 +42,14 @@
|
|||||||
/*
|
/*
|
||||||
* Read one character from stdin.
|
* Read one character from stdin.
|
||||||
*/
|
*/
|
||||||
static int readch(char *tty)
|
static int readch(void)
|
||||||
{
|
{
|
||||||
int st;
|
|
||||||
char ch1;
|
char ch1;
|
||||||
|
int st;
|
||||||
|
|
||||||
st = read(STDIN_FILENO, &ch1, 1);
|
st = read(STDIN_FILENO, &ch1, 1);
|
||||||
if (st == 0) {
|
if (st <= 0)
|
||||||
dprint(STDOUT_FILENO, "\n", 0);
|
return -1;
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st < 0)
|
|
||||||
errx(1, "getty: %s: read error", tty);
|
|
||||||
|
|
||||||
return ch1 & 0xFF;
|
return ch1 & 0xFF;
|
||||||
}
|
}
|
||||||
@@ -141,10 +134,10 @@ static void do_issue(char *tty)
|
|||||||
/*
|
/*
|
||||||
* Handle the process of a GETTY.
|
* 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;
|
char *np;
|
||||||
|
int ch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display prompt.
|
* Display prompt.
|
||||||
@@ -155,14 +148,9 @@ static void do_getty(char *tty, char *name, size_t len)
|
|||||||
do_issue(tty);
|
do_issue(tty);
|
||||||
|
|
||||||
np = name;
|
np = name;
|
||||||
while ((ch = readch(tty)) != '\n') {
|
while ((ch = readch()) != '\n') {
|
||||||
if (ch == CTRL('U')) {
|
if (ch < 0)
|
||||||
while (np > name) {
|
return 1;
|
||||||
dprint(STDOUT_FILENO, "\b \b", 3);
|
|
||||||
np--;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (np < name + len)
|
if (np < name + len)
|
||||||
*np++ = ch;
|
*np++ = ch;
|
||||||
@@ -174,6 +162,7 @@ static void do_getty(char *tty, char *name, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
name[len - 1] = 0;
|
name[len - 1] = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -185,7 +174,6 @@ static int do_login(char *name)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
cgroup_user(name, 0);
|
|
||||||
execl(_PATH_LOGIN, _PATH_LOGIN, name, NULL);
|
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);
|
warnx("Failed exec %s, attempting fallback to %s ...", _PATH_LOGIN, _PATH_BSHELL);
|
||||||
if (fstat(0, &st) == 0 && S_ISCHR(st.st_mode))
|
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 ... */
|
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";
|
const char cln[] = "\r\e[2K\n";
|
||||||
char name[33]; /* useradd(1) limit at 32 chars */
|
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)))
|
if (!strncmp(tty, _PATH_DEV, strlen(_PATH_DEV)))
|
||||||
tty += 5;
|
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 */
|
/* The getty process is responsible for the UTMP login record */
|
||||||
utmp_set_login(tty, NULL);
|
utmp_set_login(tty, NULL);
|
||||||
if (!user)
|
|
||||||
do_getty(tty, name, sizeof(name));
|
/* Replace "Please press enter ..." with login: */
|
||||||
else
|
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));
|
strlcpy(name, user, sizeof(name));
|
||||||
|
|
||||||
if (term && term[0])
|
if (term && term[0])
|
||||||
@@ -229,42 +222,14 @@ int getty(char *tty, speed_t speed, char *term, char *user)
|
|||||||
return do_login(name);
|
return do_login(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sh(char *tty)
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct termios term;
|
if (argc < 4) {
|
||||||
char *args[2] = {
|
warnx("usage: getty tty speed term");
|
||||||
NULL,
|
return 1;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... unblock signals in general */
|
return getty(argv[1], atoi(argv[2]), argv[3], NULL);
|
||||||
sig_unblock();
|
|
||||||
|
|
||||||
return execv(_PATH_BSHELL, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-4
@@ -68,11 +68,8 @@ char *strip_line (char *line);
|
|||||||
void enable_progress (int onoff);
|
void enable_progress (int onoff);
|
||||||
void show_progress (pstyle_t style);
|
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);
|
speed_t stty_parse_speed(char *baud);
|
||||||
|
void stty (int fd, speed_t speed);
|
||||||
|
|
||||||
void print_banner (const char *heading);
|
void print_banner (const char *heading);
|
||||||
void printv (const char *fmt, va_list ap);
|
void printv (const char *fmt, va_list ap);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "cgutil.h"
|
#include "cgutil.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "utmp-api.h"
|
||||||
|
|
||||||
struct cmd {
|
struct cmd {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
|||||||
-10
@@ -229,16 +229,6 @@ int fngetint(char *path, int *val)
|
|||||||
return 0;
|
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 strtobytes(char *arg)
|
||||||
{
|
{
|
||||||
int mod = 0, bytes;
|
int mod = 0, bytes;
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ int fnread (char *buf, size_t len, char *fmt, ...);
|
|||||||
int fnwrite (char *value, char *fmt, ...);
|
int fnwrite (char *value, char *fmt, ...);
|
||||||
int fngetint (char *path, int *val);
|
int fngetint (char *path, int *val);
|
||||||
|
|
||||||
int has_utmp (void);
|
|
||||||
int strtobytes (char *arg);
|
int strtobytes (char *arg);
|
||||||
char *sig2str (int sig);
|
char *sig2str (int sig);
|
||||||
char *code2str (int code);
|
char *code2str (int code);
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ int utmp_show (char *file);
|
|||||||
|
|
||||||
void runlevel_set (int pre, int now);
|
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_ */
|
#endif /* FINIT_UTMP_API_H_ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user