NetSurf: what GTK's images and libcurl's resolver needed
NetSurf (GTK 3) now starts under X and loads pages over HTTPS. Every icon GTK draws goes gdk-pixbuf -> glycin -> a loader process -> a sealed memfd -> GMappedFile, and each hop found something missing: - mkaroot runs Alpine's package triggers in the root under bubblewrap. --no-scripts had skipped them, so there was no MIME cache, pixbuf loader list, compiled GSettings schemas, GIO module cache, font cache or busybox applet links. - /usr/bin/bwrap is a stand-in that parses bubblewrap's options and runs the program with no sandbox: glycin starts its loaders only through bwrap, and real bwrap needs namespaces. schos-base replaces bubblewrap for it. - ioctl: FIOCLEX, FIONCLEX, FIONBIO and FIOASYNC on any descriptor (Rust's std uses them; pipes and sockets answered ENOTTY). - capget/capset: root has every capability, others none. - socketpair accepts SOCK_DGRAM and SOCK_SEQPACKET, carried as a stream. - waitpid and setpgid match children against the thread group leader, so a thread can wait for the process it spawned (ECHILD before). - memfd: fstat reports the ftruncate length, not the page-rounded one; file seals (F_ADD_SEALS, F_GET_SEALS, MFD_ALLOW_SEALING) are recorded and enforced on later writes, truncation and writable mappings; MFD_CLOEXEC is honoured; read-only MAP_PRIVATE maps are allowed. - recvfrom honours O_NONBLOCK and MSG_DONTWAIT. musl's resolver reads its socket until EAGAIN and blocked for ever after the first DNS answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
f4d7f9100d
commit
393bf674f5
11 changed files with 251 additions and 21 deletions
|
|
@ -459,7 +459,12 @@ SYSCALL_DEFINE(socketpair)
|
|||
return -EAFNOSUPPORT;
|
||||
int sflags = type & (SOCK_CLOEXEC | SOCK_NONBLOCK);
|
||||
type &= 0xFF;
|
||||
if (type != SOCK_STREAM)
|
||||
// Datagram and sequenced-packet pairs are carried as a stream. What they
|
||||
// are used for between two processes is passing a descriptor or a status
|
||||
// word -- Rust's process spawning asks for SOCK_SEQPACKET to hear back
|
||||
// from its child -- and one message at a time is all of that. A reader
|
||||
// that sends two and wants them kept apart would see them joined.
|
||||
if (type != SOCK_STREAM && type != 2 /* DGRAM */ && type != 5 /* SEQPACKET */)
|
||||
return -EPROTOTYPE;
|
||||
|
||||
if ((r = sockpair(&a, &b)) < 0)
|
||||
|
|
@ -532,15 +537,18 @@ SYSCALL_DEFINE(sendto)
|
|||
return socksendto(s, p, len, ip, port);
|
||||
}
|
||||
|
||||
static int argsockfile(int n, struct socket **sp, struct file **fp);
|
||||
|
||||
SYSCALL_DEFINE(recvfrom)
|
||||
{
|
||||
struct socket *s;
|
||||
struct file *file;
|
||||
addr_t ubuf, uaddr, ulenp;
|
||||
int len, flags, r;
|
||||
uint ip = 0;
|
||||
ushort port = 0;
|
||||
|
||||
if ((r = argsock(0, &s)) < 0)
|
||||
if ((r = argsockfile(0, &s, &file)) < 0)
|
||||
return r;
|
||||
argaddr(1, &ubuf);
|
||||
argint(2, &len);
|
||||
|
|
@ -554,6 +562,13 @@ SYSCALL_DEFINE(recvfrom)
|
|||
if (len && !p)
|
||||
return -EFAULT;
|
||||
|
||||
// As in recvmsg. This one blocked regardless, and musl's resolver -- which
|
||||
// sends the A and AAAA queries together and reads its non-blocking socket
|
||||
// until EAGAIN -- waited for ever after the first answer: NetSurf sat on
|
||||
// "Loading" with the reply in hand.
|
||||
if ((file->nonblock || (flags & MSG_DONTWAIT)) && !sockreadable(s))
|
||||
return -EAGAIN;
|
||||
|
||||
r = sockrecvfrom(s, p, len, &ip, &port);
|
||||
if (r < 0 || uaddr == 0)
|
||||
return r;
|
||||
|
|
|
|||
Loading…
Reference in a new issue