AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
unix.c
Go to the documentation of this file.
1
13
14#include <core/system.h>
15#include <aquila/ioctl.h>
16#include <sys/sched.h>
17#include <fs/vfs.h>
18#include <ds/ringbuf.h>
19#include <net/socket.h>
20#include <sys/uaccess.h>
21#include <unix.h>
22
23#include <aquila/fcntl.h>
24
25/* How much a connection holds each way. X servers send replies of
26 * hundreds of KB (font metrics), and every time the ring fills, the
27 * processes have to switch, so the rings are big. */
28#define SOCKBUF 65536
29
30MALLOC_DEFINE(M_SOCKET, "socket", "socket struct");
31MALLOC_DEFINE(M_UN_SOCKET, "unix socket", "unix socket struct");
32MALLOC_DEFINE(M_UN_CONN, "unix conn", "unix connection struct");
33
35
36static struct queue *sockets = QUEUE_NEW(); /* the bound sockets */
37
41static int unix_addr_check(const struct sockaddr *addr)
42{
43 struct sockaddr_un *addr_un = (struct sockaddr_un *) addr;
44
45 return strnlen(addr_un->sun_path, sizeof(addr_un->sun_path)) < sizeof(addr_un->sun_path) ? 0 : -EINVAL;
46}
47
50static void unix_conn_wakeup(struct un_conn *conn)
51{
56}
57
68int socket_unix_create(struct file *file, int domain, int type, int protocol)
69{
70 /* streams only: refusing other types is better than making a stream
71 * socket where a datagram socket was asked for */
72 if (type != SOCK_STREAM)
73 return -EPROTONOSUPPORT;
74
75 if (protocol)
76 return -EPROTONOSUPPORT;
77
78 struct socket *socket = kmalloc(sizeof(struct socket), &M_SOCKET, M_ZERO);
79 if (!socket) return -ENOMEM;
80
82 socket->type = type;
85 socket->p = NULL;
86
88 file->socket = socket;
89 return 0;
90}
91
95static int socket_unix_accept(struct file *file, struct file *conn, const struct sockaddr *addr, socklen_t *len)
96{
97 if (!file || !file->socket)
98 return -EINVAL;
99
100 struct un_socket *socket = file->socket->p;
101
102 if (file->socket->domain != AF_UNIX || !socket || !socket->listening)
103 return -EINVAL;
104
105 /* sleep until a connection request comes */
106 while (!socket->requests.count) {
107 if (file->flags & O_NONBLOCK)
108 return -EAGAIN;
109
110 int err = waitq_sleep(&socket->accept);
111
112 if (err)
113 return err;
114 }
115
116 /* allocate everything before taking the request off the queue, so
117 * that running out of memory leaves it there */
118 struct socket *conn_socket = kmalloc(sizeof(struct socket), &M_SOCKET, 0);
119 struct ringbuf *soci = ringbuf_new(SOCKBUF);
120 struct ringbuf *sico = ringbuf_new(SOCKBUF);
121
122 if (!conn_socket || !soci || !sico) {
123 kfree(conn_socket);
124 if (soci) ringbuf_free(soci);
125 if (sico) ringbuf_free(sico);
126 return -ENOMEM;
127 }
128
129 struct un_conn *request = dequeue(&socket->requests);
130
131 memcpy(conn_socket, file->socket, sizeof(struct socket));
132
133 conn_socket->domain = AF_UNIX_CONN;
134 conn_socket->p = request;
135
136 /* the connection's server side: offset 0 marks it */
137 conn->socket = conn_socket;
138 conn->flags = FILE_SOCKET;
139 conn->offset = 0;
140
141 /* the rings, one each way */
142 request->soci = soci;
143 request->sico = sico;
144
145 request->connected = 1;
146
147 /* wake up the client, which waits in connect() */
148 waitq_wakeup(&request->connect);
149
150 return 0;
151}
152
155static int socket_unix_bind(struct file *file, const struct sockaddr *addr, socklen_t len)
156{
157 struct sockaddr_un *addr_un = (struct sockaddr_un *) addr;
158
159 int err = 0;
160 struct uio uio = PROC_UIO(curproc);
161
162 if ((err = unix_addr_check(addr)))
163 return err;
164
165 /* it is bound or connected already */
166 if (file->socket->domain != AF_UNIX || file->socket->p)
167 return -EINVAL;
168
169 struct vnode *vnode = NULL;
170 err = vfs_lookup(addr_un->sun_path, &uio, &vnode);
171
172 if (err && err != -ENOENT)
173 return err;
174
175 if (!err) {
176 if (vnode)
178
179 /* the path is taken: POSIX says bind() fails then */
180 return -EADDRINUSE;
181 }
182
183 /* make the socket node, as Linux does: 0777 less the umask */
184 if ((err = vfs_mknod(addr_un->sun_path, S_IFSOCK | 0777, 0, &uio, NULL)))
185 return err;
186
187 /* look up the node just made, for a reference to it */
188 if ((err = vfs_lookup(addr_un->sun_path, &uio, &vnode)))
189 goto unlink;
190
191 struct un_socket *socket = kmalloc(sizeof(struct un_socket), &M_UN_SOCKET, M_ZERO);
192
193 if (!socket) {
194 err = -ENOMEM;
195 goto close;
196 }
197
198 socket->vnode = vnode;
199
200 /* connect() finds a bound socket on this list */
201 if (!enqueue(sockets, socket)) {
202 kfree(socket);
203 err = -ENOMEM;
204 goto close;
205 }
206
207 file->socket->p = socket;
208
209 return 0;
210
211 /* bind() failed after making the node: the node goes, so that the path
212 * can be bound again */
213close:
215unlink:
216 vfs_unlink(addr_un->sun_path, &uio);
217 return err;
218}
219
223static int socket_unix_connect(struct file *file, const struct sockaddr *addr, socklen_t len)
224{
225 struct sockaddr_un *addr_un = (struct sockaddr_un *) addr;
226
227 int err = 0;
228 struct vnode *vnode = NULL;
229 struct uio uio = PROC_UIO(curproc);
230
231 if ((err = unix_addr_check(addr)))
232 return err;
233
234 if (file->socket->domain != AF_UNIX)
235 return -EISCONN;
236
237 /* find the socket bound to the path */
238 if ((err = vfs_lookup(addr_un->sun_path, &uio, &vnode))) {
239 return err;
240 }
241
242 if (!vnode)
243 return -ENOENT;
244
245 struct un_socket *socket = NULL;
246
247 queue_for (node, sockets) {
248 struct un_socket *_socket = (struct un_socket *) node->value;
249 if (_socket->vnode == vnode) {
250 socket = _socket;
251 break;
252 }
253 }
254
255 /* the bound socket holds its own reference to the vnode */
257
258 /* the path isn't a bound socket, or it isn't listening, or its backlog
259 * is full */
260 if (!socket || !socket->listening || socket->requests.count >= socket->backlog)
261 return -ECONNREFUSED;
262
263 struct un_conn *request = kmalloc(sizeof(struct un_conn), &M_UN_CONN, M_ZERO);
264 if (!request) return -ENOMEM;
265
266 if (!enqueue(&socket->requests, request)) {
267 kfree(request);
268 return -ENOMEM;
269 }
270
271 /* wake up the server, if it waits in accept() */
272 waitq_wakeup(&socket->accept);
273
274 /* sleep until the connection is accepted, or refused */
275 while (!request->connected) {
276 int err = waitq_sleep(&request->connect);
277
278 /* a signal gives the connection up, unless it was accepted or
279 * refused meanwhile. The request is still on the listener's queue
280 * then (the listener is alive: closing it would have refused the
281 * request), and is taken off it, so accept() never sees it */
282 if (err && !request->connected) {
283 queue_remove(&socket->requests, request);
284 kfree(request);
285 return err;
286 }
287 }
288
289 /* the listening socket was closed before accepting it */
290 if (request->connected < 0) {
291 kfree(request);
292 return -ECONNREFUSED;
293 }
294
295 /* the connection's client side: offset 1 marks it */
296 file->socket->domain = AF_UNIX_CONN;
297 file->socket->p = request;
298 file->offset = 1;
299
300 return 0;
301}
302
304static int socket_unix_listen(struct file *file, int backlog)
305{
306 struct un_socket *socket = (struct un_socket *) file->socket->p;
307
308 /* it must be bound (and not a connection) */
309 if (file->socket->domain != AF_UNIX || !socket)
310 return -EINVAL;
311
312 /* allow at least one pending connection */
313 socket->backlog = MIN(MAX(backlog, 1), SOMAXCONN);
314 socket->listening = 1;
315
316 return 0;
317}
318
326static ssize_t ring_to_iobuf(struct ringbuf **ring_p, size_t n, struct iobuf *io)
327{
328 char chunk[256];
329 size_t done = 0;
330
331 while (done < n && *ring_p) {
332 size_t len = ringbuf_read_noconsume(*ring_p, 0, MIN(n - done, sizeof(chunk)), chunk);
333
334 if (!len)
335 break;
336
337 ssize_t r = iobuf_out(io, chunk, len);
338
339 if (r < 0)
340 return done ? (ssize_t) done : r;
341
342 /* what was copied out comes off the ring */
343 if (*ring_p)
344 ringbuf_discard(*ring_p, r);
345
346 done += r;
347
348 if ((size_t) r < len)
349 break;
350 }
351
352 return done;
353}
354
358static ssize_t iobuf_to_ring(struct ringbuf **ring_p, size_t n, struct iobuf *io)
359{
360 char chunk[256];
361 size_t done = 0;
362
363 while (done < n && *ring_p) {
364 ssize_t len = iobuf_peek(io, chunk, MIN(n - done, sizeof(chunk)));
365
366 if (len <= 0)
367 return done ? (ssize_t) done : len;
368
369 if (!*ring_p)
370 break;
371
372 size_t w = ringbuf_write(*ring_p, len, chunk);
373 iobuf_skip(io, w);
374 done += w;
375
376 if (w < (size_t) len || io->fault)
377 break;
378 }
379
380 return done;
381}
382
387static ssize_t socket_unix_send(struct file *file, struct iobuf *io, int flags,
388 const struct sockaddr *to, socklen_t tolen)
389{
390 size_t len = io->resid;
391
392 if (file->socket->domain != AF_UNIX_CONN)
393 return -ENOTCONN;
394
395 struct un_conn *conn = file->socket->p;
396
397 /* the peer may free the ring by shutting down while we sleep, so keep
398 * a pointer to the connection's field and read it again each time */
399 struct ringbuf **ring_p = NULL;
400
401 struct waitq *recv_queue = NULL;
402 struct waitq *send_queue = NULL;
403
404 if (file->offset == 0) { /* Server */
405 ring_p = &conn->soci;
406 recv_queue = &conn->client_recv;
407 send_queue = &conn->server_send;
408 } else { /* Client */
409 ring_p = &conn->sico;
410 recv_queue = &conn->server_recv;
411 send_queue = &conn->client_send;
412 }
413
414 /* writing is shut down */
415 if (file->offset == 0 ? conn->soci_end : conn->sico_end)
416 return -EPIPE;
417
418 ssize_t retval = 0;
419 ssize_t incr = 0;
420
421 for (;;) {
422 struct ringbuf *ring = *ring_p;
423
424 if (!ring) /* the connection was closed */
425 return retval;
426
427 size_t wlen = MIN(len - retval, SOCKBUF - ringbuf_available(ring));
428
429 if ((incr = iobuf_to_ring(ring_p, wlen, io)) < 0)
430 return retval ? retval : incr;
431
432 if (incr > 0)
433 waitq_wakeup(recv_queue);
434
435 if (incr > 0 && !(flags & MSG_WAITALL))
436 return incr;
437
438 retval += incr;
439
440 if ((size_t) retval == len || io->fault)
441 return retval;
442
443 /* the ring is full: wait, unless the socket doesn't block */
444 if (file->flags & O_NONBLOCK)
445 return retval ? retval : -EAGAIN;
446
447 int err = waitq_sleep(send_queue);
448
449 if (err)
450 return retval ? retval : err;
451 }
452}
453
458static ssize_t socket_unix_recv(struct file *file, struct iobuf *io, int flags,
459 struct sockaddr *from, socklen_t *fromlen)
460{
461 size_t len = io->resid;
462
463 if (file->socket->domain != AF_UNIX_CONN)
464 return -ENOTCONN;
465
466 /* the peer is unnamed (names aren't kept) */
467 if (from && fromlen) {
468 if (*fromlen >= sizeof(sa_family_t))
469 from->sa_family = AF_UNIX;
470 *fromlen = sizeof(sa_family_t);
471 }
472
473 struct un_conn *conn = file->socket->p;
474
475 /* see socket_unix_send() */
476 struct ringbuf **ring_p = NULL;
477
478 struct waitq *recv_queue = NULL;
479 struct waitq *send_queue = NULL;
480
481 int *end_p;
482
483 if (file->offset == 0) { /* Server */
484 ring_p = &conn->sico;
485 end_p = &conn->sico_end;
486 recv_queue = &conn->server_recv;
487 send_queue = &conn->client_send;
488 } else { /* Client */
489 ring_p = &conn->soci;
490 end_p = &conn->soci_end;
491 recv_queue = &conn->client_recv;
492 send_queue = &conn->server_send;
493 }
494
495 ssize_t retval = 0;
496 ssize_t incr = 0;
497
498 for (;;) {
499 struct ringbuf *ring = *ring_p;
500
501 if (!ring) /* the connection was closed */
502 return retval;
503
504 if ((incr = ring_to_iobuf(ring_p, len - retval, io)) < 0)
505 return retval ? retval : incr;
506
507 if (incr > 0)
508 waitq_wakeup(send_queue);
509
510 /* the peer is done writing: nothing more will come */
511 if (!incr && *end_p)
512 return retval;
513
514 if (incr > 0 && !(flags & MSG_WAITALL))
515 return incr;
516
517 retval += incr;
518
519 if ((size_t) retval == len || io->fault)
520 return retval;
521
522 /* the ring is empty: wait, unless the socket doesn't block */
523 if (file->flags & O_NONBLOCK)
524 return retval ? retval : -EAGAIN;
525
526 int err = waitq_sleep(recv_queue);
527
528 if (err)
529 return retval ? retval : err;
530 }
531}
532
535static int socket_unix_can_read(struct file *file, size_t len)
536{
537 if (!file || !file->socket)
538 return -EINVAL;
539
540 if (file->socket->domain == AF_UNIX) {
541 struct un_socket *socket = file->socket->p;
542 return socket? (int) socket->requests.count : 0;
543 }
544
545 if (file->socket->domain != AF_UNIX_CONN)
546 return -ENOTCONN;
547
548 struct un_conn *conn = file->socket->p;
549
550 struct ringbuf *ring = NULL;
551
552 int end;
553
554 if (file->offset == 0) {
555 /* Server */
556 ring = conn->sico;
557 end = conn->sico_end;
558 } else {
559 /* Client */
560 ring = conn->soci;
561 end = conn->soci_end;
562 }
563
564 if (!ring)
565 return -ENOTCONN; /* reading was shut down */
566
567 /* at the end, a read doesn't wait either: it returns 0 */
568 size_t available = ringbuf_available(ring);
569 return available ? (int) available : end;
570}
571
574static struct waitq *socket_unix_wait_queue(struct file *file, int write)
575{
576 if (file->socket->domain == AF_UNIX) {
577 struct un_socket *socket = file->socket->p;
578 return socket && !write ? &socket->accept : NULL;
579 }
580
581 if (file->socket->domain != AF_UNIX_CONN)
582 return NULL;
583
584 struct un_conn *conn = file->socket->p;
585
586 if (file->offset == 0) /* Server */
587 return write ? &conn->server_send : &conn->server_recv;
588 else /* Client */
589 return write ? &conn->client_send : &conn->client_recv;
590}
591
594static int socket_unix_can_write(struct file *file, size_t len)
595{
596 if (file->socket->domain != AF_UNIX_CONN)
597 return -ENOTCONN;
598
599 struct un_conn *conn = file->socket->p;
600
601 struct ringbuf *ring = NULL;
602
603 if (file->offset == 0) {
604 /* Server */
605 ring = conn->soci;
606 } else {
607 /* Client */
608 ring = conn->sico;
609 }
610
611 if (!ring)
612 return -ENOTCONN;
613
614 return ring->size - ringbuf_available(ring);
615}
616
617
622static void unix_conn_shut(struct file *file, int how)
623{
624 struct un_conn *conn = file->socket->p;
625 int client = file->offset;
626
627 struct ringbuf **in = client ? &conn->soci : &conn->sico;
628 int *out_end = client ? &conn->sico_end : &conn->soci_end;
629
630 if ((how & SHUT_RD) && *in) {
631 ringbuf_free(*in);
632 *in = NULL;
633 }
634
635 if (how & SHUT_WR)
636 *out_end = 1;
637
638 /* wake up the peer, which may wait on a ring that went or ended */
639 unix_conn_wakeup(conn);
640}
641
643static int socket_unix_shut(struct file *file, int how)
644{
645 if (!file || !file->socket)
646 return -EINVAL;
647
648 if (file->socket->domain != AF_UNIX_CONN)
649 return -ENOTCONN;
650
651 unix_conn_shut(file, how);
652 return 0;
653}
654
658static int socket_unix_shutdown(struct file *file, int how)
659{
660 if (!file || !file->socket)
661 return -EINVAL;
662
663 if (file->socket->domain == AF_UNIX_CONN) {
664 struct un_conn *conn = file->socket->p;
665
666 unix_conn_shut(file, how);
667
668 /* this side is gone; the connection goes once both are (each side
669 * frees the ring it read) */
670 if (!conn->soci && !conn->sico)
671 kfree(conn);
672
673 kfree(file->socket);
674 file->socket = NULL;
675
676 return 0;
677 }
678
679 /* not a connection: unbind it, if it is bound */
680 struct un_socket *socket = file->socket->p;
681
682 if (socket) {
683 struct un_conn *request;
684
685 queue_remove(sockets, socket);
686
687 /* refuse the waiting connection requests; connect() frees each */
688 while ((request = dequeue(&socket->requests))) {
689 request->connected = -1;
690 waitq_wakeup(&request->connect);
691 }
692
693 vfs_close(socket->vnode);
694 kfree(socket);
695 }
696
697 kfree(file->socket);
698 file->socket = NULL;
699
700 return 0;
701}
702
705static int socket_unix_getname(struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
706{
707 if (*len >= sizeof(sa_family_t))
708 addr->sa_family = AF_UNIX;
709
710 *len = sizeof(sa_family_t);
711 return 0;
712}
713
715static int socket_unix_ioctl(struct file *file, int request, void *argp)
716{
717 if (request == FIONREAD) {
718 int n = socket_unix_can_read(file, 0);
719
720 /* a listening socket has connection requests, not bytes, and the
721 * end of a connection is 0 bytes */
722 n = file->socket->domain == AF_UNIX_CONN && n > 0 ? n : 0;
723 return copyout(argp, &n, sizeof(n));
724 }
725
726 return -ENOTTY;
727}
728
729static struct sock_ops socket_unix_ops = {
730 .accept = socket_unix_accept,
731 .bind = socket_unix_bind,
732 .connect = socket_unix_connect,
733 .listen = socket_unix_listen,
734 .recv = socket_unix_recv,
735 .send = socket_unix_send,
736 .can_read = socket_unix_can_read,
737 .can_write = socket_unix_can_write,
738 .wait_queue = socket_unix_wait_queue,
739 .shutdown = socket_unix_shutdown,
740 .shut = socket_unix_shut,
741 .getname = socket_unix_getname,
742 .ioctl = socket_unix_ioctl,
743};
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
Definition close.c:18
#define MIN(a, b)
Definition system.h:11
#define MAX(a, b)
Definition system.h:10
ssize_t iobuf_out(struct iobuf *io, const void *src, size_t n)
Copies bytes from the kernel into the iobuf's buffer, and moves past them.
Definition iobuf.c:115
size_t iobuf_skip(struct iobuf *io, size_t n)
Moves an iobuf past bytes, without copying them.
Definition iobuf.c:81
ssize_t iobuf_peek(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, without moving past them.
Definition iobuf.c:154
#define MALLOC_DEFINE(type, _name, _desc)
Definition kvmem.h:30
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
#define M_ZERO
Definition kvmem.h:26
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition libc.c:11
int vfs_lookup(const char *path, struct uio *uio, struct vnode **ref)
Finds the vnode a path names.
Definition lookup.c:349
int vfs_mknod(const char *path, mode_t mode, dev_t dev, struct uio *uio, struct vnode **ref)
Makes a node at a path.
Definition mknod.c:21
#define PROC_UIO(proc)
Definition proc.h:210
#define queue_for(n, q)
Definition queue.h:37
#define QUEUE_NEW()
Definition queue.h:40
static void ringbuf_discard(struct ringbuf *ring, size_t n)
Throws away the first n bytes of the ring, unread (at most what it holds).
Definition ringbuf.h:113
#define curproc
Definition sched.h:13
#define FILE_SOCKET
Definition socket.h:70
int socket_unix_create(struct file *file, int domain, int type, int protocol)
Makes an AF_UNIX socket, for socket().
Definition unix.c:68
#define NULL
Definition stddef.h:27
static size_t strnlen(const char *s, size_t max)
Returns the length of a string, or max if there is no NUL in its first max bytes.
Definition string.h:97
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
off_t offset
Definition vfs.h:163
int flags
Definition vfs.h:164
An iobuf.
Definition iobuf.h:35
int fault
Definition iobuf.h:40
size_t resid
Definition iobuf.h:38
A queue.
Definition queue.h:29
A ring buffer.
Definition ringbuf.h:18
size_t size
Definition ringbuf.h:20
A domain's socket operations.
Definition socket.h:29
A socket.
Definition socket.h:16
int domain
Definition socket.h:17
void * p
Definition socket.h:25
int type
Definition socket.h:18
struct sock_ops * ops
Definition socket.h:22
int protocol
Definition socket.h:19
Who does a filesystem operation: where its paths start, and its credentials and umask.
Definition vfs.h:60
A connection between a client socket and the server that accepted it.
Definition unix.h:11
struct waitq server_recv
Definition unix.h:19
struct ringbuf * sico
Definition unix.h:13
int connected
Definition unix.h:26
struct waitq server_send
Definition unix.h:20
struct waitq connect
Definition unix.h:23
struct ringbuf * soci
Definition unix.h:12
struct waitq client_send
Definition unix.h:22
int soci_end
Definition unix.h:17
int sico_end
Definition unix.h:17
struct waitq client_recv
Definition unix.h:21
A listening socket, bound to a name in the file system.
Definition unix.h:30
struct vnode * vnode
Definition unix.h:31
size_t backlog
Definition unix.h:33
A file in memory (a vnode): what its inode says, and the kernel's own state.
Definition vfs.h:113
Definition waitq.h:19
long int ssize_t
Definition types.h:12
static int socket_unix_can_read(struct file *file, size_t len)
Says whether a read (or an accept) wouldn't wait: how many bytes or connection requests wait,...
Definition unix.c:535
static void unix_conn_shut(struct file *file, int how)
Shuts down one side of a connection for reading, writing or both.
Definition unix.c:622
static int socket_unix_getname(struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
Gets a socket's name or its peer's: always unnamed, since names aren't kept.
Definition unix.c:705
static ssize_t socket_unix_recv(struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
Receives data from a connection: what the ring has, waiting for data unless the socket doesn't block ...
Definition unix.c:458
static void unix_conn_wakeup(struct un_conn *conn)
Wakes up every thread sleeping on a connection, so that they notice that its state changed.
Definition unix.c:50
static int socket_unix_bind(struct file *file, const struct sockaddr *addr, socklen_t len)
Binds a socket to a path: a socket node is made there, which must not exist yet (-EADDRINUSE).
Definition unix.c:155
static int socket_unix_connect(struct file *file, const struct sockaddr *addr, socklen_t len)
Connects to the socket bound to a path: the request waits on the listening socket until it is accepte...
Definition unix.c:223
static int socket_unix_can_write(struct file *file, size_t len)
Says how much a write could send without waiting: the room in the ring.
Definition unix.c:594
#define SOCKBUF
Definition unix.c:28
static ssize_t ring_to_iobuf(struct ringbuf **ring_p, size_t n, struct iobuf *io)
Moves up to n bytes from a connection's ring to user memory, a chunk at a time through the kernel's m...
Definition unix.c:326
static int socket_unix_ioctl(struct file *file, int request, void *argp)
Handles FIONREAD: how many bytes a connection has to read.
Definition unix.c:715
static struct waitq * socket_unix_wait_queue(struct file *file, int write)
Returns the wait queue that a socket's readers (or writers) sleep on: a listener's accept,...
Definition unix.c:574
static int socket_unix_shutdown(struct file *file, int how)
Frees a socket when its last descriptor is closed.
Definition unix.c:658
static int socket_unix_accept(struct file *file, struct file *conn, const struct sockaddr *addr, socklen_t *len)
Accepts a connection request on a listening socket, waiting for one unless the socket doesn't block.
Definition unix.c:95
static int socket_unix_listen(struct file *file, int backlog)
Makes a bound socket listen for connections.
Definition unix.c:304
static ssize_t socket_unix_send(struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
Sends data on a connection: as much as the ring takes, waiting for room unless the socket doesn't blo...
Definition unix.c:387
static int unix_addr_check(const struct sockaddr *addr)
Checks an AF_UNIX address (the kernel's copy, as big as a struct sockaddr_un): its path must end with...
Definition unix.c:41
static ssize_t iobuf_to_ring(struct ringbuf **ring_p, size_t n, struct iobuf *io)
Moves up to n bytes from user memory to a connection's ring, as ring_to_iobuf() does the other way.
Definition unix.c:358
static struct queue * sockets
Definition unix.c:36
static struct sock_ops socket_unix_ops
Definition unix.c:34
static int socket_unix_shut(struct file *file, int how)
Handles shutdown(), which only applies to a connection.
Definition unix.c:643
#define AF_UNIX_CONN
Definition unix.h:8
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
Definition waitq.c:178
int waitq_sleep(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up.
Definition waitq.c:50