#pragma once #include "types.h" // Unix domain sockets. // // These exist for Schcom. A compositor and its clients have to exchange // messages, and a pipe cannot do it: a pipe is one-directional, has no // notion of a connection, and gives no way for a server to be *found* by a // client that starts later. A socket with a name in the filesystem is // exactly the missing piece. // // AF_INET is deliberately absent. The socket layer is being built around the // local case first because that is the one the GUI needs and the one whose // semantics are simplest; a network stack plugs in underneath the same // syscalls later rather than reshaping them. #define AF_UNIX 1 #define AF_LOCAL 1 #define AF_INET 2 // recognised so it can be refused honestly #define SOCK_STREAM 1 #define SOCK_DGRAM 2 #define UNIX_PATH_MAX 108 #define SHUT_RD 0 #define SHUT_WR 1 #define SHUT_RDWR 2 struct sockaddr_un { uint16 sun_family; char sun_path[UNIX_PATH_MAX]; }; // The generic form syscalls take. Same shape as Linux's, so a musl-linked // program's struct lines up byte for byte. struct sockaddr { uint16 sa_family; char sa_data[UNIX_PATH_MAX]; }; #ifdef _KERNEL_SOCKET_INTERNALS #define NSOCK 32 // sockets in the system #define SOCKBUF 4096 // receive buffer per connected socket #define NBACKLOG 8 enum sockstate { SS_FREE = 0, SS_UNBOUND, SS_BOUND, SS_LISTENING, SS_CONNECTED, }; // Every field here is protected by the socket table's single lock in // kernel/net/unix.c -- there is deliberately no per-socket lock; see the // comment at the top of that file for why. struct socket { int ref; int type; int state; char name[UNIX_PATH_MAX]; // the bound path, for a listener // A connected socket's peer. Writing to a socket appends to the *peer's* // buffer, which is what makes one buffer per socket enough for a // bidirectional connection. struct socket *peer; int peer_closed; char data[SOCKBUF]; uint nread, nwrite; // Connections waiting to be accepted, on a listener. struct socket *queue[NBACKLOG]; int nqueue; }; #endif