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* 20219b2ee8SDavid du Colombier ptsname(int fd) 21219b2ee8SDavid du Colombier { 22*9a747e4fSDavid du Colombier Dir *d; 23219b2ee8SDavid du Colombier static char buf[32]; 24219b2ee8SDavid du Colombier 25*9a747e4fSDavid du Colombier if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){ 26*9a747e4fSDavid du Colombier free(d); 27219b2ee8SDavid du Colombier _syserrno(); 28219b2ee8SDavid du Colombier return 0; 29219b2ee8SDavid du Colombier } 30*9a747e4fSDavid du Colombier sprintf(buf, "/dev/ptty%d", atoi(d->name+4)); 31*9a747e4fSDavid 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* 39219b2ee8SDavid du Colombier ptmname(int fd) 40219b2ee8SDavid du Colombier { 41*9a747e4fSDavid du Colombier Dir *d; 42219b2ee8SDavid du Colombier static char buf[32]; 43219b2ee8SDavid du Colombier 44*9a747e4fSDavid du Colombier if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){ 45*9a747e4fSDavid du Colombier free(d); 46219b2ee8SDavid du Colombier _syserrno(); 47219b2ee8SDavid du Colombier return 0; 48219b2ee8SDavid du Colombier } 49219b2ee8SDavid du Colombier 50*9a747e4fSDavid du Colombier sprintf(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 58219b2ee8SDavid du Colombier mkserver(void) 59219b2ee8SDavid du Colombier { 60219b2ee8SDavid du Colombier int fd, i; 61*9a747e4fSDavid du Colombier char *argv[3]; 62219b2ee8SDavid du Colombier 63*9a747e4fSDavid du Colombier fd = _OPEN(fssrv, O_RDWR); 64*9a747e4fSDavid du Colombier if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0) { 65*9a747e4fSDavid du Colombier /* 66*9a747e4fSDavid du Colombier * remove fssrv here, if it exists, to avoid a race 67*9a747e4fSDavid du Colombier * between the loop in the default case below and the 68*9a747e4fSDavid du Colombier * new ptyfs removing fssrv when it starts. 69*9a747e4fSDavid du Colombier * we otherwise might be unlucky enough to open the old 70*9a747e4fSDavid du Colombier * (hung channel) fssrv before ptyfs removes it and break 71*9a747e4fSDavid du Colombier * out of the loop with an open fd to a hung channel? 72*9a747e4fSDavid du Colombier */ 73*9a747e4fSDavid du Colombier _CLOSE(fd); 74*9a747e4fSDavid 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++) { 85*9a747e4fSDavid du Colombier fd = _OPEN(fssrv, O_RDWR); 86219b2ee8SDavid du Colombier if(fd >= 0) 87219b2ee8SDavid du Colombier break; 88*9a747e4fSDavid du Colombier _SLEEP(1000); 89219b2ee8SDavid du Colombier } 90219b2ee8SDavid du Colombier } 91219b2ee8SDavid du Colombier if(fd < 0) 92219b2ee8SDavid du Colombier return; 93*9a747e4fSDavid du Colombier if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0) 94*9a747e4fSDavid du Colombier _CLOSE(fd); 95219b2ee8SDavid du Colombier } 96*9a747e4fSDavid 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 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