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