Description: add libutil with openpty(), forkpty() and login_tty() Taken from FreeBSD, adopted for illumos. We should not push modules unconditionally: open() will do it for us if __xpg4 != 0, see usr/src/lib/libc/port/sys/open.c. If we do push modules too, termninal settings are reset, so we have 24x80 when login via ssh :-) Index: b/usr/src/head/pty.h =================================================================== --- /dev/null +++ b/usr/src/head/pty.h @@ -0,0 +1,39 @@ +/* +Copyright: 2013, Igor Pashev +License: WTFPL-2 + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + + */ + +#ifndef _PTY_H +#define _PTY_H 1 + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +int openpty (int *, int *, char *, const struct termios *, const struct winsize *); +int forkpty (int *, char *, const struct termios *, const struct winsize *); + +#ifdef __cplusplus +} +#endif + +#endif /* pty.h */ + Index: b/usr/src/head/utmp.h =================================================================== --- a/usr/src/head/utmp.h +++ b/usr/src/head/utmp.h @@ -161,6 +161,10 @@ extern int utmpname(const char *); #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ +#if defined(__EXTENSIONS__) || defined(_BSD_SOURCE) +int login_tty (int); +#endif + #ifdef __cplusplus } #endif Index: b/usr/src/lib/libutil/Makefile =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/Makefile @@ -0,0 +1,23 @@ +include ../Makefile.lib + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ Index: b/usr/src/head/Makefile =================================================================== --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -149,6 +149,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) prof.h \ project.h \ pthread.h \ + pty.h \ pw.h \ pwd.h \ rctl.h \ Index: b/usr/src/lib/libutil/Makefile.com =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/Makefile.com @@ -0,0 +1,21 @@ +LIBRARY = libutil.a +VERS = .1 +OBJECTS = pty.o login_tty.o + +include ../../Makefile.lib + +LIBS = $(DYNLIB) $(LINTLIB) + +SRCDIR = ../common + +LDLIBS += -lc + +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ Index: b/usr/src/lib/libutil/amd64/Makefile =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/amd64/Makefile @@ -0,0 +1,5 @@ +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) + Index: b/usr/src/lib/libutil/i386/Makefile =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/i386/Makefile @@ -0,0 +1,4 @@ +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) + Index: b/usr/src/lib/libutil/common/login_tty.c =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/common/login_tty.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include + +int +login_tty(int fd) +{ + pid_t s; + + s = setsid(); + if (s == -1) + s = getsid(0); + if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1) + return (-1); + (void) dup2(fd, 0); + (void) dup2(fd, 1); + (void) dup2(fd, 2); + if (fd > 2) + (void) close(fd); + return (0); +} Index: b/usr/src/lib/libutil/common/pty.c =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/common/pty.c @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#include + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + +int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, + struct winsize *winp) +{ + const char *slavename; + int master = -1, slave = -1; + int rc; + sighandler_t sigchld_handler; + + master = posix_openpt(O_RDWR|O_NOCTTY); + if (master == -1) + goto bad; + + /* The behavior of the grantpt() function is unspecified + * if the application has installed a signal handler + * to catch SIGCHLD signals. + */ + sigchld_handler = signal(SIGCHLD, SIG_DFL); + rc = grantpt(master); + (void) signal(SIGCHLD, sigchld_handler); + + if (-1 == rc) + goto bad; + + if (unlockpt(master) == -1) + goto bad; + + slavename = ptsname(master); + if (slavename == NULL) + goto bad; + + slave = open(slavename, O_RDWR|O_NOCTTY); + if (slave == -1) + goto bad; + + rc = ioctl(slave, I_FIND, "ldterm"); + if (rc < 0) + goto bad; + + if (0 == rc) { + ioctl(slave, I_PUSH, "ptem"); + ioctl(slave, I_PUSH, "ldterm"); + ioctl(slave, I_PUSH, "ttcompat"); + } + + if (name) + strcpy(name, slavename); + if (termp) + tcsetattr(slave, TCSAFLUSH, termp); + if (winp) + ioctl(slave, TIOCSWINSZ, (char *)winp); + + *amaster = master; + *aslave = slave; + + return (0); + +bad: + if (-1 != slave) + (void) close(slave); + if (-1 != master) + (void) close(master); + return (-1); +} + +int +forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) +{ + int master, slave, pid; + + if (openpty(&master, &slave, name, termp, winp) == -1) + return (-1); + switch (pid = fork()) { + case -1: + return (-1); + case 0: + /* + * child + */ + (void) close(master); + login_tty(slave); + return (0); + } + /* + * parent + */ + *amaster = master; + (void) close(slave); + return (pid); +} Index: b/usr/src/lib/libutil/common/mapfile-vers =================================================================== --- /dev/null +++ b/usr/src/lib/libutil/common/mapfile-vers @@ -0,0 +1,11 @@ +$mapfile_version 2 + +SYMBOL_VERSION LIBUTIL_1.0 { + global: + openpty; + forkpty; + login_tty; + local: + *; +}; +