abduco

Fork of abduco for persistent terminal sessions
git clone git://git.laack.co/abduco.git
Log | Files | Refs | README | LICENSE

forkpty-sunos.c (2109B)


      1 /*
      2  * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     14  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <sys/types.h>
     18 #include <sys/ioctl.h>
     19 #include <fcntl.h>
     20 #include <stdlib.h>
     21 #include <strings.h>
     22 #include <stropts.h>
     23 #include <unistd.h>
     24 
     25 #ifndef TTY_NAME_MAX
     26 #define TTY_NAME_MAX TTYNAME_MAX
     27 #endif
     28 
     29 pid_t forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
     30 {
     31 	int	slave;
     32 	char   *path;
     33 	pid_t	pid;
     34 
     35 	if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1)
     36 		return -1;
     37 	if (grantpt(*master) != 0)
     38 		goto out;
     39 	if (unlockpt(*master) != 0)
     40 		goto out;
     41 
     42 	if ((path = ptsname(*master)) == NULL)
     43 		goto out;
     44 	if (name != NULL)
     45 		strlcpy(name, path, TTY_NAME_MAX);
     46 	if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
     47 		goto out;
     48 
     49 	switch (pid = fork()) {
     50 	case -1:
     51 		goto out;
     52 	case 0:
     53 		close(*master);
     54 
     55 		setsid();
     56 #ifdef TIOCSCTTY
     57 		if (ioctl(slave, TIOCSCTTY, NULL) == -1)
     58 			return -1;
     59 #endif
     60 
     61 		if (ioctl(slave, I_PUSH, "ptem") == -1)
     62 			return -1;
     63 		if (ioctl(slave, I_PUSH, "ldterm") == -1)
     64 			return -1;
     65 
     66 		if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
     67 			return -1;
     68 		if (ioctl(slave, TIOCSWINSZ, ws) == -1)
     69 			return -1;
     70 
     71 		dup2(slave, 0);
     72 		dup2(slave, 1);
     73 		dup2(slave, 2);
     74 		if (slave > 2)
     75 			close(slave);
     76 		return 0;
     77 	}
     78 
     79 	close(slave);
     80 	return pid;
     81 
     82 out:
     83 	if (*master != -1)
     84 		close(*master);
     85 	if (slave != -1)
     86 		close(slave);
     87 	return -1;
     88 }