xref: /haiku/src/libs/bsd/pty.cpp (revision de0b831289e3279eb3de0356b81ce98030893afc)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
3  * Copyright 2010, Jérôme Duval, korli@users.berlios.de. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include <pty.h>
8 
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 
15 int
openpty(int * _master,int * _slave,char * name,struct termios * termAttrs,struct winsize * windowSize)16 openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
17 	struct winsize* windowSize)
18 {
19 	int master = posix_openpt(O_RDWR);
20 	if (master < 0)
21     	return -1;
22 
23 	int slave;
24 	const char *ttyName;
25 	if (grantpt(master) != 0 || unlockpt(master) != 0
26 		|| (ttyName = ptsname(master)) == NULL
27 		|| (slave = open(ttyName, O_RDWR | O_NOCTTY)) < 0) {
28 		close(master);
29 		return -1;
30 	}
31 
32 	if ((termAttrs != NULL && tcsetattr(master, TCSANOW, termAttrs) != 0)
33 		|| (windowSize != NULL
34 			&& ioctl(master, TIOCSWINSZ, windowSize, sizeof(winsize)) != 0)) {
35 		close(slave);
36 		close(master);
37 		return -1;
38 	}
39 
40 	*_master = master;
41 	*_slave = slave;
42 
43 	if (name != NULL)
44 		strcpy(name, ttyName);
45 
46 	return 0;
47 }
48 
49 
50 int
login_tty(int fd)51 login_tty(int fd)
52 {
53 	setsid();
54 
55 	if (ioctl(fd, TIOCSCTTY, NULL) != 0)
56 		return -1;
57 
58 	dup2(fd, 0);
59 	dup2(fd, 1);
60 	dup2(fd, 2);
61 
62 	close(fd);
63 	return 0;
64 }
65 
66 
67 pid_t
forkpty(int * _master,char * name,struct termios * termAttrs,struct winsize * windowSize)68 forkpty(int* _master, char* name, struct termios* termAttrs,
69 	struct winsize* windowSize)
70 {
71 	int master, slave;
72 	if (openpty(&master, &slave, name, termAttrs, windowSize) != 0)
73 		return -1;
74 
75 	int pid = fork();
76 	if (pid < 0) {
77 		close(master);
78 		close(slave);
79 		return -1;
80 	}
81 	// child
82 	if (pid == 0) {
83 		close(master);
84 		return login_tty(slave);
85 	}
86 
87 	// parent
88 	close (slave);
89 	*_master = master;
90 	return pid;
91 }
92