kernel: timers that fire, raw ping, and the sockets X needs

alarm() and setitimer() stored a countdown nothing counted down, so no
timer has ever fired; setitimer and getitimer were also registered with
no Linux number. alarmd now posts SIGALRM on the tick, while any process
has a timer armed. busybox's ping, /bin/ping on the Alpine root, sends
every request after the first from its SIGALRM handler.

It also opens SOCK_RAW, which was EPROTOTYPE. A raw ICMP socket is now a
ping socket whose reads start at the IP header. And a blocked socket
call gives up for a signal with a handler, not only for a kill: the
alarm woke recvfrom, and the wait put it straight back to sleep.

For Xorg: AF_UNIX abstract names, which read as the empty path and so as
EADDRINUSE ("server already running"); and getsockname and getpeername,
which did not exist, so libxcb sent no cookie and the server refused
every client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 19:44:10 +02:00
commit a4ed556543
9 changed files with 428 additions and 28 deletions

View file

@ -492,6 +492,10 @@ int sockbind(struct socket*, const char *path, uint dev, uint64 ino)
int socklisten(struct socket*, int backlog);
struct socket* sockaccept(struct socket*);
int sockconnect(struct socket*, uint dev, uint64 ino);
int sockbind_abstract(struct socket*, uint64 key);
int sockname_unix(struct socket*, int peer, char *path);
int sockname_inet(struct socket*, int peer, uint *addr, ushort *port);
#define SOCK_ABSTRACT_DEV 0xFFFFFFFFu // no filesystem has it; see unix.c
int sockreadable(struct socket*);
int sock_hup(struct socket*);
int sock_shutdown(struct socket*, int how);
@ -523,6 +527,7 @@ void* inet_accept(void *h);
int inet_connect(void *h, uint addr, ushort port);
int inet_read(void *h, char *buf, int n);
int inet_write(void *h, char *buf, int n);
int inet_name(void *h, int peer, uint *addr, ushort *port);
int inet_recvfrom(void *h, char *buf, int n,
uint *addr, ushort *port);
int inet_sendto(void *h, char *buf, int n,
@ -544,6 +549,9 @@ int proc_pgid(int pid);
int proc_setpgid(int pid, int pgid);
int proc_setsid(void);
int sigsend(int pid, int sig);
void alarm_arm(struct proc *p, uint after, uint every);
uint alarm_left(struct proc *p);
void alarm_thread_start(void);
int sig_default_kills(int sig);
int proc_exists(int);
int proc_num(void);

View file

@ -231,7 +231,11 @@ struct proc {
uint64 signal_mask;
uint64 pending_signals;
int alarm_ticks;
// ITIMER_REAL, which alarm() is the whole-second form of: SIGALRM is due at
// tick alarm_at (0 = not armed) and then every alarm_every ticks after.
// alarmd, in kernel/proc/proc.c, is what posts it.
uint alarm_at;
uint alarm_every;
char ofile_flags[NOFILE];
// Real signal delivery (added for SIGCHLD — see kernel/sys/syscall.c's