1219b2ee8SDavid du Colombier /* posix */
2219b2ee8SDavid du Colombier #include <sys/types.h>
3219b2ee8SDavid du Colombier #include <unistd.h>
4219b2ee8SDavid du Colombier #include <stdlib.h>
5219b2ee8SDavid du Colombier #include <stdio.h>
6219b2ee8SDavid du Colombier #include <errno.h>
7219b2ee8SDavid du Colombier #include <string.h>
8219b2ee8SDavid du Colombier #include <fcntl.h>
9219b2ee8SDavid du Colombier #include <sys/stat.h>
10219b2ee8SDavid du Colombier
11219b2ee8SDavid du Colombier #include <sys/pty.h>
12219b2ee8SDavid du Colombier #include "lib.h"
13219b2ee8SDavid du Colombier #include "sys9.h"
14219b2ee8SDavid du Colombier #include "dir.h"
15219b2ee8SDavid du Colombier
16219b2ee8SDavid du Colombier /*
17219b2ee8SDavid du Colombier * return the name of the slave
18219b2ee8SDavid du Colombier */
19219b2ee8SDavid du Colombier char*
ptsname(int fd)20219b2ee8SDavid du Colombier ptsname(int fd)
21219b2ee8SDavid du Colombier {
229a747e4fSDavid du Colombier Dir *d;
23219b2ee8SDavid du Colombier static char buf[32];
24219b2ee8SDavid du Colombier
259a747e4fSDavid du Colombier if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){
269a747e4fSDavid du Colombier free(d);
27219b2ee8SDavid du Colombier _syserrno();
28219b2ee8SDavid du Colombier return 0;
29219b2ee8SDavid du Colombier }
30*7e125112SDavid du Colombier snprintf(buf, sizeof buf, "/dev/ptty%d", atoi(d->name+4));
319a747e4fSDavid du Colombier free(d);
32219b2ee8SDavid du Colombier return buf;
33219b2ee8SDavid du Colombier }
34219b2ee8SDavid du Colombier
35219b2ee8SDavid du Colombier /*
36219b2ee8SDavid du Colombier * return the name of the master
37219b2ee8SDavid du Colombier */
38219b2ee8SDavid du Colombier char*
ptmname(int fd)39219b2ee8SDavid du Colombier ptmname(int fd)
40219b2ee8SDavid du Colombier {
419a747e4fSDavid du Colombier Dir *d;
42219b2ee8SDavid du Colombier static char buf[32];
43219b2ee8SDavid du Colombier
449a747e4fSDavid du Colombier if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){
459a747e4fSDavid du Colombier free(d);
46219b2ee8SDavid du Colombier _syserrno();
47219b2ee8SDavid du Colombier return 0;
48219b2ee8SDavid du Colombier }
49219b2ee8SDavid du Colombier
50*7e125112SDavid du Colombier snprintf(buf, sizeof buf, "/dev/ttym%d", atoi(d->name+4));
51219b2ee8SDavid du Colombier return buf;
52219b2ee8SDavid du Colombier }
53219b2ee8SDavid du Colombier
54219b2ee8SDavid du Colombier static char ptycl[] = "/dev/ptyclone";
55219b2ee8SDavid du Colombier static char fssrv[] = "/srv/ptyfs";
56219b2ee8SDavid du Colombier
57219b2ee8SDavid du Colombier static void
mkserver(void)58219b2ee8SDavid du Colombier mkserver(void)
59219b2ee8SDavid du Colombier {
60219b2ee8SDavid du Colombier int fd, i;
619a747e4fSDavid du Colombier char *argv[3];
62219b2ee8SDavid du Colombier
639a747e4fSDavid du Colombier fd = _OPEN(fssrv, O_RDWR);
649a747e4fSDavid du Colombier if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0) {
659a747e4fSDavid du Colombier /*
669a747e4fSDavid du Colombier * remove fssrv here, if it exists, to avoid a race
679a747e4fSDavid du Colombier * between the loop in the default case below and the
689a747e4fSDavid du Colombier * new ptyfs removing fssrv when it starts.
699a747e4fSDavid du Colombier * we otherwise might be unlucky enough to open the old
709a747e4fSDavid du Colombier * (hung channel) fssrv before ptyfs removes it and break
719a747e4fSDavid du Colombier * out of the loop with an open fd to a hung channel?
729a747e4fSDavid du Colombier */
739a747e4fSDavid du Colombier _CLOSE(fd);
749a747e4fSDavid du Colombier _REMOVE(fssrv);
75219b2ee8SDavid du Colombier switch(_RFORK(RFPROC|RFFDG)) {
76219b2ee8SDavid du Colombier case -1:
77219b2ee8SDavid du Colombier return;
78219b2ee8SDavid du Colombier case 0:
79219b2ee8SDavid du Colombier argv[0] = "ptyfs";
80219b2ee8SDavid du Colombier argv[1] = 0;
81219b2ee8SDavid du Colombier _EXEC("/bin/ape/ptyfs", argv);
82219b2ee8SDavid du Colombier _EXITS(0);
83219b2ee8SDavid du Colombier default:
84219b2ee8SDavid du Colombier for(i = 0; i < 3; i++) {
859a747e4fSDavid du Colombier fd = _OPEN(fssrv, O_RDWR);
86219b2ee8SDavid du Colombier if(fd >= 0)
87219b2ee8SDavid du Colombier break;
889a747e4fSDavid du Colombier _SLEEP(1000);
89219b2ee8SDavid du Colombier }
90219b2ee8SDavid du Colombier }
91219b2ee8SDavid du Colombier if(fd < 0)
92219b2ee8SDavid du Colombier return;
939a747e4fSDavid du Colombier if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0)
949a747e4fSDavid du Colombier _CLOSE(fd);
95219b2ee8SDavid du Colombier }
969a747e4fSDavid du Colombier /* successful _MOUNT closes fd */
97219b2ee8SDavid du Colombier }
98219b2ee8SDavid du Colombier
99219b2ee8SDavid du Colombier /*
100219b2ee8SDavid du Colombier * allocate a new pty
101219b2ee8SDavid du Colombier */
102219b2ee8SDavid du Colombier int
_getpty(void)103219b2ee8SDavid du Colombier _getpty(void)
104219b2ee8SDavid du Colombier {
105219b2ee8SDavid du Colombier struct stat sb;
106219b2ee8SDavid du Colombier
107219b2ee8SDavid du Colombier if(stat(ptycl, &sb) < 0)
108219b2ee8SDavid du Colombier mkserver();
109219b2ee8SDavid du Colombier
110219b2ee8SDavid du Colombier return open(ptycl, O_RDWR);
111219b2ee8SDavid du Colombier }
112