15#include <aquila/ioctl.h>
23#include <aquila/fcntl.h>
31MALLOC_DEFINE(M_UN_SOCKET,
"unix socket",
"unix socket struct");
32MALLOC_DEFINE(M_UN_CONN,
"unix conn",
"unix connection struct");
43 struct sockaddr_un *addr_un = (
struct sockaddr_un *) addr;
45 return strnlen(addr_un->sun_path,
sizeof(addr_un->sun_path)) <
sizeof(addr_un->sun_path) ? 0 : -EINVAL;
72 if (type != SOCK_STREAM)
73 return -EPROTONOSUPPORT;
76 return -EPROTONOSUPPORT;
79 if (!
socket)
return -ENOMEM;
106 while (!
socket->requests.count) {
122 if (!conn_socket || !soci || !sico) {
124 if (soci) ringbuf_free(soci);
125 if (sico) ringbuf_free(sico);
134 conn_socket->
p = request;
137 conn->socket = conn_socket;
157 struct sockaddr_un *addr_un = (
struct sockaddr_un *) addr;
166 if (
file->socket->domain != AF_UNIX ||
file->socket->p)
172 if (err && err != -ENOENT)
225 struct sockaddr_un *addr_un = (
struct sockaddr_un *) addr;
234 if (
file->socket->domain != AF_UNIX)
261 return -ECONNREFUSED;
264 if (!request)
return -ENOMEM;
266 if (!enqueue(&
socket->requests, request)) {
283 queue_remove(&
socket->requests, request);
292 return -ECONNREFUSED;
297 file->socket->p = request;
309 if (
file->socket->domain != AF_UNIX || !
socket)
331 while (done < n && *ring_p) {
332 size_t len = ringbuf_read_noconsume(*ring_p, 0,
MIN(n - done,
sizeof(chunk)), chunk);
340 return done ? (
ssize_t) done : r;
348 if ((
size_t) r < len)
363 while (done < n && *ring_p) {
367 return done ? (
ssize_t) done : len;
372 size_t w = ringbuf_write(*ring_p, len, chunk);
376 if (w < (
size_t) len || io->
fault)
388 const struct sockaddr *to, socklen_t tolen)
390 size_t len = io->
resid;
405 ring_p = &conn->
soci;
409 ring_p = &conn->
sico;
422 struct ringbuf *ring = *ring_p;
427 size_t wlen =
MIN(len - retval,
SOCKBUF - ringbuf_available(ring));
430 return retval ? retval : incr;
435 if (incr > 0 && !(flags & MSG_WAITALL))
440 if ((
size_t) retval == len || io->
fault)
445 return retval ? retval : -EAGAIN;
450 return retval ? retval : err;
459 struct sockaddr *from, socklen_t *fromlen)
461 size_t len = io->
resid;
467 if (from && fromlen) {
468 if (*fromlen >=
sizeof(sa_family_t))
469 from->sa_family = AF_UNIX;
470 *fromlen =
sizeof(sa_family_t);
484 ring_p = &conn->
sico;
489 ring_p = &conn->
soci;
499 struct ringbuf *ring = *ring_p;
505 return retval ? retval : incr;
514 if (incr > 0 && !(flags & MSG_WAITALL))
519 if ((
size_t) retval == len || io->
fault)
524 return retval ? retval : -EAGAIN;
529 return retval ? retval : err;
540 if (
file->socket->domain == AF_UNIX) {
568 size_t available = ringbuf_available(ring);
569 return available ? (int) available : end;
576 if (
file->socket->domain == AF_UNIX) {
614 return ring->
size - ringbuf_available(ring);
630 if ((how & SHUT_RD) && *in) {
688 while ((request = dequeue(&
socket->requests))) {
707 if (*len >=
sizeof(sa_family_t))
708 addr->sa_family = AF_UNIX;
710 *len =
sizeof(sa_family_t);
717 if (request == FIONREAD) {
723 return copyout(argp, &n,
sizeof(n));
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
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.
size_t iobuf_skip(struct iobuf *io, size_t n)
Moves an iobuf past bytes, without copying them.
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.
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int vfs_lookup(const char *path, struct uio *uio, struct vnode **ref)
Finds the vnode a path names.
int vfs_mknod(const char *path, mode_t mode, dev_t dev, struct uio *uio, struct vnode **ref)
Makes a node at a path.
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).
int socket_unix_create(struct file *file, int domain, int type, int protocol)
Makes an AF_UNIX socket, for socket().
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.
An open file (POSIX's "open file description", fs/file.c).
A domain's socket operations.
Who does a filesystem operation: where its paths start, and its credentials and umask.
A connection between a client socket and the server that accepted it.
A listening socket, bound to a name in the file system.
A file in memory (a vnode): what its inode says, and the kernel's own state.
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,...
static void unix_conn_shut(struct file *file, int how)
Shuts down one side of a connection for reading, writing or both.
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.
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 ...
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.
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).
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...
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.
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...
static int socket_unix_ioctl(struct file *file, int request, void *argp)
Handles FIONREAD: how many bytes a connection has to read.
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,...
static int socket_unix_shutdown(struct file *file, int how)
Frees a socket when its last descriptor is closed.
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.
static int socket_unix_listen(struct file *file, int backlog)
Makes a bound socket listen for connections.
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...
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...
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.
static struct queue * sockets
static struct sock_ops socket_unix_ops
static int socket_unix_shut(struct file *file, int how)
Handles shutdown(), which only applies to a connection.
int vfs_unlink(const char *path, struct uio *uio)
Removes the name of a file (not a directory) at a path.
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
int waitq_sleep(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up.