1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <hurd.h>
21: #include <hurd/fd.h>
22: #include <sys/ioctl.h>
23: #include <hurd/ioctl.h>
24: #include <string.h>
25:
26:
27:
28:
29:
30: symbol_set_define (_hurd_ioctl_handler_lists)
31:
32:
33: ioctl_handler_t
34: _hurd_lookup_ioctl_handler (int request)
35: {
36: void *const *ptr;
37: const struct ioctl_handler *h;
38:
39:
40:
41: request = _IOC_NOTYPE (request);
42:
43: for (ptr = symbol_set_first_element (_hurd_ioctl_handler_lists);
44: !symbol_set_end_p (_hurd_ioctl_handler_lists, ptr);
45: ++ptr)
46: for (h = *ptr; h != NULL; h = h->next)
47: if (request >= h->first_request && request <= h->last_request)
48: return h->handler;
49:
50: return NULL;
51: }
52: ^L
53: #include <fcntl.h>
54:
55:
56:
57: static int
58: fioctl (int fd,
59: int request,
60: int *arg)
61: {
62: error_t err;
63:
64: *(volatile int *) arg = *arg;
65:
66: switch (request)
67: {
68: default:
69: err = ENOTTY;
70: break;
71:
72: case FIONREAD:
73: {
74: mach_msg_type_number_t navail;
75: err = HURD_DPORT_USE (fd, __io_readable (port, &navail));
76: if (!err)
77: *arg = (int) navail;
78: }
79: break;
80:
81: case FIONBIO:
82: err = HURD_DPORT_USE (fd, (*arg ?
83: __io_set_some_openmodes :
84: __io_clear_some_openmodes)
85: (port, O_NONBLOCK));
86: break;
87:
88: case FIOASYNC:
89: err = HURD_DPORT_USE (fd, (*arg ?
90: __io_set_some_openmodes :
91: __io_clear_some_openmodes)
92: (port, O_ASYNC));
93: break;
94:
95: case FIOSETOWN:
96: err = HURD_DPORT_USE (fd, __io_mod_owner (port, *arg));
97: break;
98:
99: case FIOGETOWN:
100: err = HURD_DPORT_USE (fd, __io_get_owner (port, arg));
101: break;
102: }
103:
104: return err ? __hurd_dfail (fd, err) : 0;
105: }
106:
107: _HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD);
108:
109:
110: static int
111: fioclex (int fd,
112: int request)
113: {
114: int flag;
115:
116: switch (request)
117: {
118: default:
119: return __hurd_fail (ENOTTY);
120: case FIOCLEX:
121: flag = FD_CLOEXEC;
122: break;
123: case FIONCLEX:
124: flag = 0;
125: break;
126: }
127:
128: return __fcntl (fd, F_SETFD, flag);
129: }
130: _HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX);
131: ^L
132: #include <hurd/term.h>
133: #include <hurd/tioctl.h>
134:
135:
136:
137:
138: void
139: _hurd_locked_install_cttyid (mach_port_t cttyid)
140: {
141: mach_port_t old;
142: struct hurd_port *const port = &_hurd_ports[INIT_PORT_CTTYID];
143: struct hurd_userlink ulink;
144: int i;
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164: __spin_lock (&port->lock);
165: old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL;
166: port->port = cttyid;
167: cttyid = _hurd_port_locked_get (port, &ulink);
168:
169: for (i = 0; i < _hurd_dtablesize; ++i)
170: {
171: struct hurd_fd *const d = _hurd_dtable[i];
172: mach_port_t newctty;
173:
174: if (d == NULL)
175:
176: continue;
177:
178: if (cttyid == MACH_PORT_NULL)
179:
180: newctty = MACH_PORT_NULL;
181: else
182: HURD_PORT_USE (&d->port,
183: ({ mach_port_t id;
184:
185: if (! __term_getctty (port, &id))
186: {
187: if (id == cttyid &&
188:
189: __term_open_ctty (port,
190: _hurd_pid, _hurd_pgrp,
191: &newctty))
192:
193: newctty = MACH_PORT_NULL;
194: __mach_port_deallocate
195: (__mach_task_self (), (mach_port_t) id);
196: }
197: else
198: newctty = MACH_PORT_NULL;
199: 0;
200: }));
201:
202:
203: _hurd_port_set (&d->ctty, newctty);
204: }
205:
206: __mutex_unlock (&_hurd_dtable_lock);
207:
208: if (old != MACH_PORT_NULL)
209: __mach_port_deallocate (__mach_task_self (), old);
210: _hurd_port_free (port, &ulink, cttyid);
211: }
212:
213: static void
214: install_ctty (mach_port_t cttyid)
215: {
216: HURD_CRITICAL_BEGIN;
217: __mutex_lock (&_hurd_dtable_lock);
218: _hurd_locked_install_cttyid (cttyid);
219: HURD_CRITICAL_END;
220: }
221:
222:
223:
224:
225: error_t
226: _hurd_setcttyid (mach_port_t cttyid)
227: {
228: error_t err;
229:
230: if (cttyid != MACH_PORT_NULL)
231: {
232:
233:
234: if (err = __mach_port_mod_refs (__mach_task_self (), cttyid,
235: MACH_PORT_RIGHT_SEND, 1))
236: return err;
237: }
238:
239:
240: install_ctty (cttyid);
241:
242: return 0;
243: }
244:
245:
246:
247:
248:
249: static int
250: tiocsctty (int fd,
251: int request)
252: {
253: mach_port_t cttyid;
254: error_t err;
255:
256:
257: err = HURD_DPORT_USE (fd, ctty != MACH_PORT_NULL ? EADDRINUSE :
258: __term_getctty (port, &cttyid));
259: if (err == EADDRINUSE)
260:
261: return 0;
262: else if (err)
263: return __hurd_fail (err);
264:
265:
266: err = HURD_DPORT_USE (fd, __tioctl_tiocspgrp (port, _hurd_pgrp));
267: if (err)
268: return __hurd_fail (err);
269:
270:
271: install_ctty (cttyid);
272:
273: return 0;
274: }
275: _HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY);
276:
277:
278:
279: static int
280: tiocnotty (int fd,
281: int request)
282: {
283: mach_port_t fd_cttyid;
284: error_t err;
285:
286: if (err = HURD_DPORT_USE (fd, __term_getctty (port, &fd_cttyid)))
287: return __hurd_fail (err);
288:
289: if (__USEPORT (CTTYID, port != fd_cttyid))
290: err = EINVAL;
291:
292: __mach_port_deallocate (__mach_task_self (), fd_cttyid);
293:
294: if (err)
295: return __hurd_fail (err);
296:
297:
298: install_ctty (MACH_PORT_NULL);
299:
300: return 0;
301: }
302: _HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY);
303: ^L
304: #include <hurd/pfinet.h>
305: #include <net/if.h>
306: #include <netinet/in.h>
307:
308:
309:
310: static int
311: siocgifconf (int fd, int request, struct ifconf *ifc)
312: {
313: error_t err;
314: size_t data_len = ifc->ifc_len;
315: char *data = ifc->ifc_buf;
316:
317: if (data_len <= 0)
318: return 0;
319:
320: err = HURD_DPORT_USE (fd, __pfinet_siocgifconf (port, ifc->ifc_len,
321: &data, &data_len));
322: if (data_len < ifc->ifc_len)
323: ifc->ifc_len = data_len;
324: if (data != ifc->ifc_buf)
325: {
326: memcpy (ifc->ifc_buf, data, ifc->ifc_len);
327: __vm_deallocate (__mach_task_self (), (vm_address_t) data, data_len);
328: }
329: return err ? __hurd_dfail (fd, err) : 0;
330: }
331: _HURD_HANDLE_IOCTL (siocgifconf, SIOCGIFCONF);