Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}