xref: /minix3/minix/drivers/tty/pty/ptyfs.c (revision da21d850255e4f11bb2023f69a0b3aad4eab62e2)
1*da21d850SDavid van Moolenbroek /* ptyfs.c - communication to PTYFS */
2*da21d850SDavid van Moolenbroek 
3*da21d850SDavid van Moolenbroek #include <minix/driver.h>
4*da21d850SDavid van Moolenbroek #include <minix/ds.h>
5*da21d850SDavid van Moolenbroek 
6*da21d850SDavid van Moolenbroek #include "ptyfs.h"
7*da21d850SDavid van Moolenbroek 
8*da21d850SDavid van Moolenbroek /*
9*da21d850SDavid van Moolenbroek  * Perform synchronous communication with PTYFS, if PTYFS is actually running.
10*da21d850SDavid van Moolenbroek  * This function is expected to return only once PTYFS has acknowledged
11*da21d850SDavid van Moolenbroek  * processing the request, in order to avoid race conditions between PTYFS and
12*da21d850SDavid van Moolenbroek  * userland.  The function must always fail when PTYFS is not available for any
13*da21d850SDavid van Moolenbroek  * reason.  Return OK on success, or an IPC-level error on failure.
14*da21d850SDavid van Moolenbroek  */
15*da21d850SDavid van Moolenbroek static int
ptyfs_sendrec(message * m_ptr)16*da21d850SDavid van Moolenbroek ptyfs_sendrec(message * m_ptr)
17*da21d850SDavid van Moolenbroek {
18*da21d850SDavid van Moolenbroek 	endpoint_t endpt;
19*da21d850SDavid van Moolenbroek 
20*da21d850SDavid van Moolenbroek 	/*
21*da21d850SDavid van Moolenbroek 	 * New pseudoterminals are created sufficiently rarely that we need not
22*da21d850SDavid van Moolenbroek 	 * optimize this by for example caching the PTYFS endpoint,  especially
23*da21d850SDavid van Moolenbroek 	 * since caching brings along new issues, such as having to reissue the
24*da21d850SDavid van Moolenbroek 	 * request if the cached endpoint turns out to be outdated (e.g., when
25*da21d850SDavid van Moolenbroek 	 * ptyfs is unmounted and remounted for whatever reason).
26*da21d850SDavid van Moolenbroek 	 */
27*da21d850SDavid van Moolenbroek 	if (ds_retrieve_label_endpt("ptyfs", &endpt) != OK)
28*da21d850SDavid van Moolenbroek 		return EDEADSRCDST; /* ptyfs is not available */
29*da21d850SDavid van Moolenbroek 
30*da21d850SDavid van Moolenbroek 	return ipc_sendrec(endpt, m_ptr);
31*da21d850SDavid van Moolenbroek }
32*da21d850SDavid van Moolenbroek 
33*da21d850SDavid van Moolenbroek /*
34*da21d850SDavid van Moolenbroek  * Add or update a node on PTYFS, with the given node index and attributes.
35*da21d850SDavid van Moolenbroek  * Return OK on success, or an error code on failure.  Errors may include
36*da21d850SDavid van Moolenbroek  * communication failures and out-of-memory conditions.
37*da21d850SDavid van Moolenbroek  */
38*da21d850SDavid van Moolenbroek int
ptyfs_set(unsigned int index,mode_t mode,uid_t uid,gid_t gid,dev_t dev)39*da21d850SDavid van Moolenbroek ptyfs_set(unsigned int index, mode_t mode, uid_t uid, gid_t gid, dev_t dev)
40*da21d850SDavid van Moolenbroek {
41*da21d850SDavid van Moolenbroek 	message m;
42*da21d850SDavid van Moolenbroek 	int r;
43*da21d850SDavid van Moolenbroek 
44*da21d850SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
45*da21d850SDavid van Moolenbroek 
46*da21d850SDavid van Moolenbroek 	m.m_type = PTYFS_SET;
47*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.index = index;
48*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.mode = mode;
49*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.uid = uid;
50*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.gid = gid;
51*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.dev = dev;
52*da21d850SDavid van Moolenbroek 
53*da21d850SDavid van Moolenbroek 	if ((r = ptyfs_sendrec(&m)) != OK)
54*da21d850SDavid van Moolenbroek 		return r;
55*da21d850SDavid van Moolenbroek 
56*da21d850SDavid van Moolenbroek 	return m.m_type;
57*da21d850SDavid van Moolenbroek }
58*da21d850SDavid van Moolenbroek 
59*da21d850SDavid van Moolenbroek /*
60*da21d850SDavid van Moolenbroek  * Remove a node from PTYFS.  Return OK on success, or an error code on
61*da21d850SDavid van Moolenbroek  * failure.  The function succeeds even if no node existed for the given index.
62*da21d850SDavid van Moolenbroek  */
63*da21d850SDavid van Moolenbroek int
ptyfs_clear(unsigned int index)64*da21d850SDavid van Moolenbroek ptyfs_clear(unsigned int index)
65*da21d850SDavid van Moolenbroek {
66*da21d850SDavid van Moolenbroek 	message m;
67*da21d850SDavid van Moolenbroek 	int r;
68*da21d850SDavid van Moolenbroek 
69*da21d850SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
70*da21d850SDavid van Moolenbroek 
71*da21d850SDavid van Moolenbroek 	m.m_type = PTYFS_CLEAR;
72*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.index = index;
73*da21d850SDavid van Moolenbroek 
74*da21d850SDavid van Moolenbroek 	if ((r = ptyfs_sendrec(&m)) != OK)
75*da21d850SDavid van Moolenbroek 		return r;
76*da21d850SDavid van Moolenbroek 
77*da21d850SDavid van Moolenbroek 	return m.m_type;
78*da21d850SDavid van Moolenbroek }
79*da21d850SDavid van Moolenbroek 
80*da21d850SDavid van Moolenbroek /*
81*da21d850SDavid van Moolenbroek  * Obtain the file name for the PTYFS node with the given index, and store it
82*da21d850SDavid van Moolenbroek  * in the given 'name' buffer which consists of 'size' bytes.  On success,
83*da21d850SDavid van Moolenbroek  * return OK, with the file name stored as a null-terminated string.  The
84*da21d850SDavid van Moolenbroek  * returned name does not include the PTYFS mount path.  On failure, return an
85*da21d850SDavid van Moolenbroek  * error code.  Among other reasons, the function fails if no node is allocated
86*da21d850SDavid van Moolenbroek  * for the given index, and if the name does not fit in the given buffer.
87*da21d850SDavid van Moolenbroek  */
88*da21d850SDavid van Moolenbroek int
ptyfs_name(unsigned int index,char * name,size_t size)89*da21d850SDavid van Moolenbroek ptyfs_name(unsigned int index, char * name, size_t size)
90*da21d850SDavid van Moolenbroek {
91*da21d850SDavid van Moolenbroek 	message m;
92*da21d850SDavid van Moolenbroek 	int r;
93*da21d850SDavid van Moolenbroek 
94*da21d850SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
95*da21d850SDavid van Moolenbroek 
96*da21d850SDavid van Moolenbroek 	m.m_type = PTYFS_NAME;
97*da21d850SDavid van Moolenbroek 	m.m_pty_ptyfs_req.index = index;
98*da21d850SDavid van Moolenbroek 
99*da21d850SDavid van Moolenbroek 	if ((r = ptyfs_sendrec(&m)) != OK)
100*da21d850SDavid van Moolenbroek 		return r;
101*da21d850SDavid van Moolenbroek 
102*da21d850SDavid van Moolenbroek 	if (m.m_type != OK)
103*da21d850SDavid van Moolenbroek 		return m.m_type;
104*da21d850SDavid van Moolenbroek 
105*da21d850SDavid van Moolenbroek 	/* Ensure null termination, and make sure the string fits. */
106*da21d850SDavid van Moolenbroek 	m.m_ptyfs_pty_name.name[sizeof(m.m_ptyfs_pty_name.name) - 1] = 0;
107*da21d850SDavid van Moolenbroek 	if (strlen(m.m_ptyfs_pty_name.name) >= size)
108*da21d850SDavid van Moolenbroek 		return ENAMETOOLONG;
109*da21d850SDavid van Moolenbroek 
110*da21d850SDavid van Moolenbroek 	strlcpy(name, m.m_ptyfs_pty_name.name, size);
111*da21d850SDavid van Moolenbroek 	return OK;
112*da21d850SDavid van Moolenbroek }
113