aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ttyent.h2
-rw-r--r--lib/libc/gen/getttyent.36
-rw-r--r--lib/libc/gen/getttyent.c15
-rw-r--r--sbin/init/init.c50
4 files changed, 53 insertions, 20 deletions
diff --git a/include/ttyent.h b/include/ttyent.h
index cbefc87c62ca..a98fbdffb86f 100644
--- a/include/ttyent.h
+++ b/include/ttyent.h
@@ -57,6 +57,8 @@ struct ttyent {
#define TTY_SECURE 0x02 /* allow uid of 0 to login */
#define TTY_DIALUP 0x04 /* is a dialup tty */
#define TTY_NETWORK 0x08 /* is a network tty */
+#define TTY_IFEXISTS 0x10 /* configured as "onifexists" */
+#define TTY_IFCONSOLE 0x20 /* configured as "onifconsole" */
int ty_status; /* status flags */
char *ty_window; /* command to start up window manager */
char *ty_comment; /* comment field */
diff --git a/lib/libc/gen/getttyent.3 b/lib/libc/gen/getttyent.3
index 1b1590d8ae59..a5e9156c7e61 100644
--- a/lib/libc/gen/getttyent.3
+++ b/lib/libc/gen/getttyent.3
@@ -75,6 +75,8 @@ struct ttyent {
#define TTY_SECURE 0x02 /* allow uid of 0 to login */
#define TTY_DIALUP 0x04 /* is a dialup tty */
#define TTY_NETWORK 0x08 /* is a network tty */
+#define TTY_IFEXISTS 0x10 /* configured as "onifexists" */
+#define TTY_IFCONSOLE 0x20 /* configured as "onifconsole" */
int ty_status; /* status flags */
char *ty_window; /* command to start up window manager */
char *ty_comment; /* comment field */
@@ -115,6 +117,10 @@ Identifies a tty used for network connections.
If this flag is set, then
.Fn isnettty
will return a non-zero value.
+.It Dv TTY_IFEXISTS
+Identifies a tty that does not neccessarily exist.
+.It Dv TTY_IFCONSOLE
+Identifies a tty that might be a system console.
.El
.It Fa ty_window
The command to execute for a window system associated with the line.
diff --git a/lib/libc/gen/getttyent.c b/lib/libc/gen/getttyent.c
index 633a5f212372..cc36201a2d20 100644
--- a/lib/libc/gen/getttyent.c
+++ b/lib/libc/gen/getttyent.c
@@ -75,11 +75,14 @@ auto_tty_status(const char *ty_name)
{
size_t len;
char *buf, *cons, *nextcons;
+ int rv;
+
+ rv = TTY_IFCONSOLE;
/* Check if this is an enabled kernel console line */
buf = NULL;
if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1)
- return (0); /* Errors mean don't enable */
+ return (rv); /* Errors mean don't enable */
buf = malloc(len);
if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1)
goto done;
@@ -90,14 +93,14 @@ auto_tty_status(const char *ty_name)
nextcons = buf;
while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) {
if (strcmp(cons, ty_name) == 0) {
- free(buf);
- return (TTY_ON);
+ rv |= TTY_ON;
+ break;
}
}
done:
free(buf);
- return (0);
+ return (rv);
}
static int
@@ -107,13 +110,13 @@ auto_exists_status(const char *ty_name)
char *dev;
int rv;
- rv = 0;
+ rv = TTY_IFEXISTS;
if (*ty_name == '/')
asprintf(&dev, "%s", ty_name);
else
asprintf(&dev, "/dev/%s", ty_name);
if (dev != NULL && stat(dev, &sb) == 0)
- rv = TTY_ON;
+ rv |= TTY_ON;
free(dev);
return (rv);
}
diff --git a/sbin/init/init.c b/sbin/init/init.c
index e0ec7cd891ea..235c3f13ffd3 100644
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -156,6 +156,8 @@ typedef struct init_session {
int se_flags; /* status of session */
#define SE_SHUTDOWN 0x1 /* session won't be restarted */
#define SE_PRESENT 0x2 /* session is in /etc/ttys */
+#define SE_IFEXISTS 0x4 /* session defined as "onifexists" */
+#define SE_IFCONSOLE 0x8 /* session defined as "onifconsole" */
int se_nspace; /* spacing count */
char *se_device; /* filename of port */
char *se_getty; /* what to run on that port */
@@ -1262,7 +1264,6 @@ static session_t *
new_session(session_t *sprev, struct ttyent *typ)
{
session_t *sp;
- int fd;
if ((typ->ty_status & TTY_ON) == 0 ||
typ->ty_name == 0 ||
@@ -1273,21 +1274,15 @@ new_session(session_t *sprev, struct ttyent *typ)
sp->se_flags |= SE_PRESENT;
+ if ((typ->ty_status & TTY_IFEXISTS) != 0)
+ sp->se_flags |= SE_IFEXISTS;
+
+ if ((typ->ty_status & TTY_IFCONSOLE) != 0)
+ sp->se_flags |= SE_IFCONSOLE;
+
if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0)
err(1, "asprintf");
- /*
- * Attempt to open the device, if we get "device not configured"
- * then don't add the device to the session list.
- */
- if ((fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0)) < 0) {
- if (errno == ENXIO) {
- free_session(sp);
- return (0);
- }
- } else
- close(fd);
-
if (setupargv(sp, typ) == 0) {
free_session(sp);
return (0);
@@ -1507,6 +1502,30 @@ start_getty(session_t *sp)
}
/*
+ * Return 1 if the session is defined as "onifexists"
+ * or "onifconsole" and the device node does not exist.
+ */
+static int
+session_has_no_tty(session_t *sp)
+{
+ int fd;
+
+ if ((sp->se_flags & SE_IFEXISTS) == 0 &&
+ (sp->se_flags & SE_IFCONSOLE) == 0)
+ return (0);
+
+ fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ return (1);
+ return (0);
+ }
+
+ close(fd);
+ return (0);
+}
+
+/*
* Collect exit status for a child.
* If an exiting login, start a new login running.
*/
@@ -1524,7 +1543,8 @@ collect_child(pid_t pid)
del_session(sp);
sp->se_process = 0;
- if (sp->se_flags & SE_SHUTDOWN) {
+ if (sp->se_flags & SE_SHUTDOWN ||
+ session_has_no_tty(sp)) {
if ((sprev = sp->se_prev) != NULL)
sprev->se_next = sp->se_next;
else
@@ -1611,6 +1631,8 @@ multi_user(void)
for (sp = sessions; sp; sp = sp->se_next) {
if (sp->se_process)
continue;
+ if (session_has_no_tty(sp))
+ continue;
if ((pid = start_getty(sp)) == -1) {
/* serious trouble */
requested_transition = clean_ttys;