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