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