kernel: an inert AF_NETLINK socket (libudev's device monitor)

SDL's joystick/haptic start-up opens libudev's uevent monitor; socket(AF_NETLINK)
failing with EAFNOSUPPORT made SDL_Init fail and undo its video subsystem, so
Unity 6 selected no window backend and built its display list empty (0x0):
Hollow Knight's cameras never rendered. The socket now binds, takes options
and never has a message (an empty eventfd behind it); Unity selects x11.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_461fe3ff06374ecba693831148697ba6
This commit is contained in:
velzieandClaude Opus 5.5 committed 2026-10-06 03:18:46 -04:00
1 parent eae7916986
commit e50a8cb5de
1 file changed
+13 -1
+13 -1
View File
@@ -5192,7 +5192,7 @@ impl Kernel {
// -- sockets ---------------------------------------------------------------
/// `socket`. Only AF_INET, and only the two kinds that matter: a stream,
/// `socket`. AF_UNIX, an inert AF_NETLINK (below), and AF_INET with only the two kinds that matter: a stream,
/// which the host carries, and a datagram, which only ever goes to the
/// resolver this kernel is.
fn sys_socket(&mut self, domain: u64, ty: u64) -> SysResult {
@@ -5217,6 +5217,18 @@ impl Kernel {
let flags = if nonblock { oflags::O_NONBLOCK } else { 0 };
return self.install_unix(sock, flags, ty & SOCK_CLOEXEC != 0);
}
// AF_NETLINK, which libudev's device monitor opens (SDL's joystick
// and haptic start-up through it; a failure there made SDL_Init undo
// its video subsystem too, and Unity 6 then saw no display). There
// are no devices to announce, so the socket binds, takes its options
// and never has a message: an empty eventfd behind the descriptor.
const AF_NETLINK: u64 = 16;
if domain == AF_NETLINK {
let handle: Arc<dyn crate::vfs::FileHandle> = Arc::new(crate::eventfd::EventFd::new(0, false));
let flags = if ty & SOCK_NONBLOCK != 0 { crate::fs::oflags::O_NONBLOCK } else { 0 };
let file = OpenFile::new(handle, "socket:[netlink]".to_string(), flags, true, true);
return self.fds.insert(file, ty & SOCK_CLOEXEC != 0);
}
let Some(net) = self.net.clone() else {
return Err(Errno::EAFNOSUPPORT);
};