Home | History | Annotate | Line # | Download | only in compat
forkpty-haiku.c revision 1.1
      1 /*
      2  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      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 
     20 #include <fcntl.h>
     21 #include <stdlib.h>
     22 #include <unistd.h>
     23 
     24 #include "compat.h"
     25 
     26 void fatal(const char *, ...);
     27 void fatalx(const char *, ...);
     28 
     29 pid_t
     30 forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
     31 {
     32 	int	slave = -1;
     33 	char   *path;
     34 	pid_t	pid;
     35 
     36 	if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1)
     37 		return (-1);
     38 	if (grantpt(*master) != 0)
     39 		goto out;
     40 	if (unlockpt(*master) != 0)
     41 		goto out;
     42 
     43 	if ((path = ptsname(*master)) == NULL)
     44 		goto out;
     45 	if (name != NULL)
     46 		strlcpy(name, path, TTY_NAME_MAX);
     47 	if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
     48 		goto out;
     49 
     50 	switch (pid = fork()) {
     51 	case -1:
     52 		goto out;
     53 	case 0:
     54 		close(*master);
     55 
     56 		setsid();
     57 		if (ioctl(slave, TIOCSCTTY, NULL) == -1)
     58 			fatal("ioctl failed");
     59 
     60 		if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
     61 			fatal("tcsetattr failed");
     62 		if (ioctl(slave, TIOCSWINSZ, ws) == -1)
     63 			fatal("ioctl failed");
     64 
     65 		dup2(slave, 0);
     66 		dup2(slave, 1);
     67 		dup2(slave, 2);
     68 		if (slave > 2)
     69 			close(slave);
     70 		return (0);
     71 	}
     72 
     73 	close(slave);
     74 	return (pid);
     75 
     76 out:
     77 	if (*master != -1)
     78 		close(*master);
     79 	if (slave != -1)
     80 		close(slave);
     81 	return (-1);
     82 }
     83