xref: /plan9/sys/src/ape/lib/bsd/pty.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier /* posix */
2*219b2ee8SDavid du Colombier #include <sys/types.h>
3*219b2ee8SDavid du Colombier #include <unistd.h>
4*219b2ee8SDavid du Colombier #include <stdlib.h>
5*219b2ee8SDavid du Colombier #include <stdio.h>
6*219b2ee8SDavid du Colombier #include <errno.h>
7*219b2ee8SDavid du Colombier #include <string.h>
8*219b2ee8SDavid du Colombier #include <fcntl.h>
9*219b2ee8SDavid du Colombier #include <sys/stat.h>
10*219b2ee8SDavid du Colombier 
11*219b2ee8SDavid du Colombier #include <sys/pty.h>
12*219b2ee8SDavid du Colombier #include "lib.h"
13*219b2ee8SDavid du Colombier #include "sys9.h"
14*219b2ee8SDavid du Colombier #include "dir.h"
15*219b2ee8SDavid du Colombier #include "fcall.h"
16*219b2ee8SDavid du Colombier 
17*219b2ee8SDavid du Colombier /*
18*219b2ee8SDavid du Colombier  * return the name of the slave
19*219b2ee8SDavid du Colombier  */
20*219b2ee8SDavid du Colombier char*
21*219b2ee8SDavid du Colombier ptsname(int fd)
22*219b2ee8SDavid du Colombier {
23*219b2ee8SDavid du Colombier 	Dir d;
24*219b2ee8SDavid du Colombier 	char cd[DIRLEN];
25*219b2ee8SDavid du Colombier 	static char buf[32];
26*219b2ee8SDavid du Colombier 
27*219b2ee8SDavid du Colombier 	if(_FSTAT(fd, cd) < 0) {
28*219b2ee8SDavid du Colombier 		_syserrno();
29*219b2ee8SDavid du Colombier 		return 0;
30*219b2ee8SDavid du Colombier 	}
31*219b2ee8SDavid du Colombier 	convM2D(cd, &d);
32*219b2ee8SDavid du Colombier 
33*219b2ee8SDavid du Colombier 	sprintf(buf, "/dev/ptty%d", atoi(d.name+4));
34*219b2ee8SDavid du Colombier 	return buf;
35*219b2ee8SDavid du Colombier }
36*219b2ee8SDavid du Colombier 
37*219b2ee8SDavid du Colombier /*
38*219b2ee8SDavid du Colombier  * return the name of the master
39*219b2ee8SDavid du Colombier  */
40*219b2ee8SDavid du Colombier char*
41*219b2ee8SDavid du Colombier ptmname(int fd)
42*219b2ee8SDavid du Colombier {
43*219b2ee8SDavid du Colombier 	Dir d;
44*219b2ee8SDavid du Colombier 	char cd[DIRLEN];
45*219b2ee8SDavid du Colombier 	static char buf[32];
46*219b2ee8SDavid du Colombier 
47*219b2ee8SDavid du Colombier 	if(_FSTAT(fd, cd) < 0) {
48*219b2ee8SDavid du Colombier 		_syserrno();
49*219b2ee8SDavid du Colombier 		return 0;
50*219b2ee8SDavid du Colombier 	}
51*219b2ee8SDavid du Colombier 	convM2D(cd, &d);
52*219b2ee8SDavid du Colombier 
53*219b2ee8SDavid du Colombier 	sprintf(buf, "/dev/ttym%d", atoi(d.name+4));
54*219b2ee8SDavid du Colombier 	return buf;
55*219b2ee8SDavid du Colombier }
56*219b2ee8SDavid du Colombier 
57*219b2ee8SDavid du Colombier static char ptycl[] = "/dev/ptyclone";
58*219b2ee8SDavid du Colombier static char fssrv[] = "/srv/ptyfs";
59*219b2ee8SDavid du Colombier 
60*219b2ee8SDavid du Colombier static void
61*219b2ee8SDavid du Colombier mkserver(void)
62*219b2ee8SDavid du Colombier {
63*219b2ee8SDavid du Colombier 	int fd, i;
64*219b2ee8SDavid du Colombier 	char *argv[3], tbuf[2*TICKETLEN];
65*219b2ee8SDavid du Colombier 
66*219b2ee8SDavid du Colombier 	fd = _OPEN(fssrv, 3);
67*219b2ee8SDavid du Colombier 	if(_MOUNT(fd, "/dev", MAFTER, "") < 0) {
68*219b2ee8SDavid du Colombier 		switch(_RFORK(RFPROC|RFFDG)) {
69*219b2ee8SDavid du Colombier 		case -1:
70*219b2ee8SDavid du Colombier 			return;
71*219b2ee8SDavid du Colombier 		case 0:
72*219b2ee8SDavid du Colombier 			argv[0] = "ptyfs";
73*219b2ee8SDavid du Colombier 			argv[1] = 0;
74*219b2ee8SDavid du Colombier 			_EXEC("/bin/ape/ptyfs", argv);
75*219b2ee8SDavid du Colombier 			_EXITS(0);
76*219b2ee8SDavid du Colombier 		default:
77*219b2ee8SDavid du Colombier 			for(i = 0; i < 3; i++) {
78*219b2ee8SDavid du Colombier 				fd = _OPEN(fssrv, 3);
79*219b2ee8SDavid du Colombier 				if(fd >= 0)
80*219b2ee8SDavid du Colombier 					break;
81*219b2ee8SDavid du Colombier 				sleep(1);
82*219b2ee8SDavid du Colombier 			}
83*219b2ee8SDavid du Colombier 		}
84*219b2ee8SDavid du Colombier 		if(fd < 0)
85*219b2ee8SDavid du Colombier 			return;
86*219b2ee8SDavid du Colombier 		memset(tbuf, 0, sizeof(tbuf));
87*219b2ee8SDavid du Colombier 		_FSESSION(fd, tbuf);
88*219b2ee8SDavid du Colombier 		_MOUNT(fd, "/dev", MAFTER, "");
89*219b2ee8SDavid du Colombier 	}
90*219b2ee8SDavid du Colombier }
91*219b2ee8SDavid du Colombier 
92*219b2ee8SDavid du Colombier /*
93*219b2ee8SDavid du Colombier  * allocate a new pty
94*219b2ee8SDavid du Colombier  */
95*219b2ee8SDavid du Colombier int
96*219b2ee8SDavid du Colombier _getpty(void)
97*219b2ee8SDavid du Colombier {
98*219b2ee8SDavid du Colombier 	struct stat sb;
99*219b2ee8SDavid du Colombier 
100*219b2ee8SDavid du Colombier 	if(stat(ptycl, &sb) < 0)
101*219b2ee8SDavid du Colombier 		mkserver();
102*219b2ee8SDavid du Colombier 
103*219b2ee8SDavid du Colombier 	return open(ptycl, O_RDWR);
104*219b2ee8SDavid du Colombier }
105