Index: head/include/ttyent.h =================================================================== --- head/include/ttyent.h +++ head/include/ttyent.h @@ -57,6 +57,8 @@ #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 */ Index: head/lib/libc/gen/getttyent.3 =================================================================== --- head/lib/libc/gen/getttyent.3 +++ head/lib/libc/gen/getttyent.3 @@ -75,6 +75,8 @@ #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 @@ 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. Index: head/lib/libc/gen/getttyent.c =================================================================== --- head/lib/libc/gen/getttyent.c +++ head/lib/libc/gen/getttyent.c @@ -75,11 +75,14 @@ { 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 @@ 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 @@ 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); } Index: head/sbin/init/init.c =================================================================== --- head/sbin/init/init.c +++ head/sbin/init/init.c @@ -156,6 +156,8 @@ 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 @@ 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 @@ 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 @@ } /* + * 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 @@ 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 @@ -1610,6 +1630,8 @@ 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 */