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 16 /* 17 * return the name of the slave 18 */ 19 char* 20 ptsname(int fd) 21 { 22 Dir *d; 23 static char buf[32]; 24 25 if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){ 26 free(d); 27 _syserrno(); 28 return 0; 29 } 30 snprintf(buf, sizeof buf, "/dev/ptty%d", atoi(d->name+4)); 31 free(d); 32 return buf; 33 } 34 35 /* 36 * return the name of the master 37 */ 38 char* 39 ptmname(int fd) 40 { 41 Dir *d; 42 static char buf[32]; 43 44 if((d = _dirfstat(fd)) == nil || strlen(d->name) < 4){ 45 free(d); 46 _syserrno(); 47 return 0; 48 } 49 50 snprintf(buf, sizeof buf, "/dev/ttym%d", atoi(d->name+4)); 51 return buf; 52 } 53 54 static char ptycl[] = "/dev/ptyclone"; 55 static char fssrv[] = "/srv/ptyfs"; 56 57 static void 58 mkserver(void) 59 { 60 int fd, i; 61 char *argv[3]; 62 63 fd = _OPEN(fssrv, O_RDWR); 64 if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0) { 65 /* 66 * remove fssrv here, if it exists, to avoid a race 67 * between the loop in the default case below and the 68 * new ptyfs removing fssrv when it starts. 69 * we otherwise might be unlucky enough to open the old 70 * (hung channel) fssrv before ptyfs removes it and break 71 * out of the loop with an open fd to a hung channel? 72 */ 73 _CLOSE(fd); 74 _REMOVE(fssrv); 75 switch(_RFORK(RFPROC|RFFDG)) { 76 case -1: 77 return; 78 case 0: 79 argv[0] = "ptyfs"; 80 argv[1] = 0; 81 _EXEC("/bin/ape/ptyfs", argv); 82 _EXITS(0); 83 default: 84 for(i = 0; i < 3; i++) { 85 fd = _OPEN(fssrv, O_RDWR); 86 if(fd >= 0) 87 break; 88 _SLEEP(1000); 89 } 90 } 91 if(fd < 0) 92 return; 93 if(_MOUNT(fd, -1, "/dev", MAFTER, "") < 0) 94 _CLOSE(fd); 95 } 96 /* successful _MOUNT closes fd */ 97 } 98 99 /* 100 * allocate a new pty 101 */ 102 int 103 _getpty(void) 104 { 105 struct stat sb; 106 107 if(stat(ptycl, &sb) < 0) 108 mkserver(); 109 110 return open(ptycl, O_RDWR); 111 } 112