forked from pool/util-linux
sulogin: Try to autoconfigure broken serial lines
OBS-URL: https://build.opensuse.org/package/show/Base:System/util-linux?expand=0&rev=436
This commit is contained in:
parent
fd21f8d012
commit
d4cb846fae
@ -6,14 +6,162 @@ and also not functional console devices. Redirect the error
|
|||||||
messages to the appropiate console device.
|
messages to the appropiate console device.
|
||||||
|
|
||||||
---
|
---
|
||||||
sulogin.c | 11 ++++++++---
|
login-utils/sulogin-consoles.h | 1 +
|
||||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
login-utils/sulogin.c | 97 +++++++++++++++++++++++++++++++++++-------
|
||||||
|
2 files changed, 82 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h
|
||||||
|
index 0bfbc3871..12032c997 100644
|
||||||
|
--- a/login-utils/sulogin-consoles.h
|
||||||
|
+++ b/login-utils/sulogin-consoles.h
|
||||||
|
@@ -40,6 +40,7 @@ struct console {
|
||||||
|
int fd, id;
|
||||||
|
#define CON_SERIAL 0x0001
|
||||||
|
#define CON_NOTTY 0x0002
|
||||||
|
+#define CON_EIO 0x0004
|
||||||
|
pid_t pid;
|
||||||
|
struct chardata cp;
|
||||||
|
struct termios tio;
|
||||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
|
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
|
||||||
index 9091caf14..7ee8f2dc7 100644
|
index 9091caf14..c833796e7 100644
|
||||||
--- a/login-utils/sulogin.c
|
--- a/login-utils/sulogin.c
|
||||||
+++ b/login-utils/sulogin.c
|
+++ b/login-utils/sulogin.c
|
||||||
@@ -608,7 +608,7 @@ static const char *getpasswd(struct console *con)
|
@@ -52,6 +52,7 @@
|
||||||
|
#ifdef __linux__
|
||||||
|
# include <sys/kd.h>
|
||||||
|
# include <sys/param.h>
|
||||||
|
+# include <linux/serial.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "c.h"
|
||||||
|
@@ -104,6 +105,9 @@ static void tcinit(struct console *con)
|
||||||
|
int flags = 0, mode = 0;
|
||||||
|
struct termios *tio = &con->tio;
|
||||||
|
const int fd = con->fd;
|
||||||
|
+#if defined(TIOCGSERIAL)
|
||||||
|
+ struct serial_struct serinfo;
|
||||||
|
+#endif
|
||||||
|
#ifdef USE_PLYMOUTH_SUPPORT
|
||||||
|
struct termios lock;
|
||||||
|
int i = (plymouth_command(MAGIC_PING)) ? PLYMOUTH_TERMIOS_FLAGS_DELAY : 0;
|
||||||
|
@@ -123,27 +127,72 @@ static void tcinit(struct console *con)
|
||||||
|
}
|
||||||
|
memset(&lock, 0, sizeof(struct termios));
|
||||||
|
ioctl(fd, TIOCSLCKTRMIOS, &lock);
|
||||||
|
+ errno = 0;
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+#if defined(TIOCGSERIAL)
|
||||||
|
+ if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0)
|
||||||
|
+ con->flags |= CON_SERIAL;
|
||||||
|
+ errno = 0;
|
||||||
|
+#else
|
||||||
|
+# if defined(KDGKBMODE)
|
||||||
|
+ if (ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||||
|
+ con->flags |= CON_SERIAL;
|
||||||
|
errno = 0;
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (tcgetattr(fd, tio) < 0) {
|
||||||
|
- warn(_("tcgetattr failed"));
|
||||||
|
- con->flags |= CON_NOTTY;
|
||||||
|
- return;
|
||||||
|
+ int saveno = errno;
|
||||||
|
+#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
|
||||||
|
+ if (con->flags & CON_SERIAL) { /* Try to recover this */
|
||||||
|
+
|
||||||
|
+# if defined(TIOCGSERIAL)
|
||||||
|
+ serinfo.flags |= ASYNC_SKIP_TEST; /* Skip test of UART */
|
||||||
|
+
|
||||||
|
+ if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0)
|
||||||
|
+ goto tcgeterr;
|
||||||
|
+ if (ioctl(fd, TIOCSERCONFIG) < 0) /* Try to autoconfigure */
|
||||||
|
+ goto tcgeterr;
|
||||||
|
+ if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
|
||||||
|
+ goto tcgeterr; /* Ouch */
|
||||||
|
+# endif
|
||||||
|
+ if (tcgetattr(fd, tio) < 0) /* Retry to get tty attributes */
|
||||||
|
+ saveno = errno;
|
||||||
|
+ }
|
||||||
|
+# if defined(TIOCGSERIAL)
|
||||||
|
+ tcgeterr:
|
||||||
|
+# endif
|
||||||
|
+ if (saveno)
|
||||||
|
+#endif
|
||||||
|
+ {
|
||||||
|
+ FILE *fcerr = fdopen(fd, "w");
|
||||||
|
+ if (fcerr) {
|
||||||
|
+ fprintf(fcerr, _("tcgetattr failed"));
|
||||||
|
+ fclose(fcerr);
|
||||||
|
+ }
|
||||||
|
+ warn(_("tcgetattr failed"));
|
||||||
|
+
|
||||||
|
+ con->flags &= ~CON_SERIAL;
|
||||||
|
+ if (saveno != EIO)
|
||||||
|
+ con->flags |= CON_NOTTY;
|
||||||
|
+ else
|
||||||
|
+ con->flags |= CON_EIO;
|
||||||
|
+
|
||||||
|
+ errno = 0;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle lines other than virtual consoles here */
|
||||||
|
-#if defined(KDGKBMODE)
|
||||||
|
- if (ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||||
|
+#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
|
||||||
|
+ if (con->flags & CON_SERIAL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
speed_t ispeed, ospeed;
|
||||||
|
struct winsize ws;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
- /* this is a modem line */
|
||||||
|
- con->flags |= CON_SERIAL;
|
||||||
|
-
|
||||||
|
/* Flush input and output queues on modem lines */
|
||||||
|
tcflush(fd, TCIOFLUSH);
|
||||||
|
|
||||||
|
@@ -220,6 +269,8 @@ static void tcfinal(struct console *con)
|
||||||
|
struct termios *tio = &con->tio;
|
||||||
|
const int fd = con->fd;
|
||||||
|
|
||||||
|
+ if (con->flags & CON_EIO)
|
||||||
|
+ return;
|
||||||
|
if ((con->flags & CON_SERIAL) == 0) {
|
||||||
|
xsetenv("TERM", "linux", 1);
|
||||||
|
return;
|
||||||
|
@@ -557,12 +608,16 @@ err:
|
||||||
|
static void setup(struct console *con)
|
||||||
|
{
|
||||||
|
int fd = con->fd;
|
||||||
|
- const pid_t pid = getpid(), pgrp = getpgid(0), ppgrp =
|
||||||
|
- getpgid(getppid()), ttypgrp = tcgetpgrp(fd);
|
||||||
|
+ const pid_t pid = getpid(), pgrp = getpgid(0), ppgrp = getpgid(getppid());
|
||||||
|
+ pid_t ttypgrp;
|
||||||
|
|
||||||
|
if (con->flags & CON_NOTTY)
|
||||||
|
+ goto notty;
|
||||||
|
+ if (con->flags & CON_EIO)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ ttypgrp = tcgetpgrp(fd);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Only go through this trouble if the new
|
||||||
|
* tty doesn't fall in this process group.
|
||||||
|
@@ -585,6 +640,7 @@ static void setup(struct console *con)
|
||||||
|
ioctl(fd, TIOCSCTTY, (char *)1);
|
||||||
|
tcsetpgrp(fd, ppgrp);
|
||||||
|
}
|
||||||
|
+notty:
|
||||||
|
dup2(fd, STDIN_FILENO);
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
dup2(fd, STDERR_FILENO);
|
||||||
|
@@ -608,20 +664,25 @@ static const char *getpasswd(struct console *con)
|
||||||
struct termios tty;
|
struct termios tty;
|
||||||
static char pass[128], *ptr;
|
static char pass[128], *ptr;
|
||||||
struct chardata *cp;
|
struct chardata *cp;
|
||||||
@ -22,21 +170,33 @@ index 9091caf14..7ee8f2dc7 100644
|
|||||||
unsigned char tc;
|
unsigned char tc;
|
||||||
char c, ascval;
|
char c, ascval;
|
||||||
int eightbit;
|
int eightbit;
|
||||||
@@ -618,6 +618,7 @@ static const char *getpasswd(struct console *con)
|
const int fd = con->fd;
|
||||||
|
|
||||||
|
- if (con->flags & CON_NOTTY)
|
||||||
|
+ if (con->flags & CON_EIO)
|
||||||
goto out;
|
goto out;
|
||||||
|
+
|
||||||
cp = &con->cp;
|
cp = &con->cp;
|
||||||
tty = con->tio;
|
tty = con->tio;
|
||||||
|
+ tc = 0;
|
||||||
+ ret = pass;
|
+ ret = pass;
|
||||||
|
|
||||||
tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
|
tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
|
||||||
tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ISIG);
|
tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ISIG);
|
||||||
@@ -647,11 +648,12 @@ static const char *getpasswd(struct console *con)
|
- tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0);
|
||||||
|
+
|
||||||
|
+ if ((con->flags & CON_NOTTY) == 0)
|
||||||
|
+ tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0);
|
||||||
|
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler = alrm_handler;
|
||||||
|
@@ -647,11 +708,12 @@ static const char *getpasswd(struct console *con)
|
||||||
}
|
}
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
- case 0:
|
- case 0:
|
||||||
case EIO:
|
case EIO:
|
||||||
+ con->flags |= CON_NOTTY;
|
+ con->flags |= CON_EIO;
|
||||||
case ESRCH:
|
case ESRCH:
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
@ -44,11 +204,20 @@ index 9091caf14..7ee8f2dc7 100644
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn(_("cannot read %s"), con->tty);
|
warn(_("cannot read %s"), con->tty);
|
||||||
@@ -968,10 +970,13 @@ int main(int argc, char **argv)
|
@@ -775,7 +837,7 @@ static void sushell(struct passwd *pwd)
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBSELINUX
|
||||||
|
if (is_selinux_enabled() > 0) {
|
||||||
|
- security_context_t scon=NULL;
|
||||||
|
+ char *scon=NULL;
|
||||||
|
char *seuser=NULL;
|
||||||
|
char *level=NULL;
|
||||||
|
if (getseuserbyname("root", &seuser, &level) == 0) {
|
||||||
|
@@ -968,10 +1030,13 @@ int main(int argc, char **argv)
|
||||||
con = list_entry(ptr, struct console, entry);
|
con = list_entry(ptr, struct console, entry);
|
||||||
if (con->id >= CONMAX)
|
if (con->id >= CONMAX)
|
||||||
break;
|
break;
|
||||||
+ if (con->flags & CON_NOTTY)
|
+ if (con->flags & CON_EIO)
|
||||||
+ goto next;
|
+ goto next;
|
||||||
|
|
||||||
switch ((con->pid = fork())) {
|
switch ((con->pid = fork())) {
|
||||||
@ -58,7 +227,7 @@ index 9091caf14..7ee8f2dc7 100644
|
|||||||
nofork:
|
nofork:
|
||||||
setup(con);
|
setup(con);
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -1026,7 +1031,7 @@ int main(int argc, char **argv)
|
@@ -1026,7 +1091,7 @@ int main(int argc, char **argv)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Nov 4 11:07:03 UTC 2020 - Dr. Werner Fink <werner@suse.de>
|
||||||
|
|
||||||
|
- Modernize patch util-linux-sulogin4bsc1175514.patch
|
||||||
|
* Try to autoconfigure broken serial lines
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Oct 30 14:03:47 UTC 2020 - Dr. Werner Fink <werner@suse.de>
|
Fri Oct 30 14:03:47 UTC 2020 - Dr. Werner Fink <werner@suse.de>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user