feat: ports - netsurf with the monkey frontend
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Ae69wJS7sueQMUwNxV3nX
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Minimal <sys/select.h> for the MontaukOS NetSurf port.
|
||||
*
|
||||
* MontaukOS has no select(). Readiness on a socket is expressed through the
|
||||
* kernel's waitset (SYS_WAITSET_*), which is a different shape entirely, and
|
||||
* stdio descriptors are not waitable objects at all.
|
||||
*
|
||||
* NetSurf's core uses select() in exactly one place -- content/fetch.c's
|
||||
* fetch_fdset() collects descriptors from the registered fetchers, and the
|
||||
* frontend's main loop selects over them plus its own input. With
|
||||
* NETSURF_USE_CURL=NO no fetcher registers a descriptor, so the only fd that
|
||||
* ever appears is the monkey frontend's stdin (fd 0).
|
||||
*
|
||||
* That makes a useful shim possible:
|
||||
*
|
||||
* - if any read descriptor is requested, report them ready immediately and
|
||||
* let the caller block in read(). monkey is a line-driven REPL, so
|
||||
* blocking on stdin is what it wants anyway.
|
||||
* - otherwise sleep for the timeout so an idle loop does not spin.
|
||||
*
|
||||
* LIMITATION: because a requested read fd is always reported ready, scheduled
|
||||
* callbacks do not fire while the process sits idle waiting for a command.
|
||||
* That is fine for driving monkey by hand or by script, and it is wrong for
|
||||
* anything with real network activity. When fetch_montauk lands it will
|
||||
* register descriptors here and this needs replacing with a genuine
|
||||
* waitset-backed implementation.
|
||||
*/
|
||||
#ifndef _MONTAUK_COMPAT_SYS_SELECT_H_
|
||||
#define _MONTAUK_COMPAT_SYS_SELECT_H_
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FD_SETSIZE 64
|
||||
|
||||
typedef struct {
|
||||
unsigned long fds_bits[(FD_SETSIZE + (8 * sizeof(unsigned long)) - 1) /
|
||||
(8 * sizeof(unsigned long))];
|
||||
} fd_set;
|
||||
|
||||
#define __NFDBITS (8 * (int) sizeof(unsigned long))
|
||||
|
||||
#define FD_ZERO(s) memset((s), 0, sizeof(fd_set))
|
||||
#define FD_SET(fd, s) \
|
||||
((void) ((s)->fds_bits[(fd) / __NFDBITS] |= \
|
||||
(1UL << ((fd) % __NFDBITS))))
|
||||
#define FD_CLR(fd, s) \
|
||||
((void) ((s)->fds_bits[(fd) / __NFDBITS] &= \
|
||||
~(1UL << ((fd) % __NFDBITS))))
|
||||
#define FD_ISSET(fd, s) \
|
||||
(((s)->fds_bits[(fd) / __NFDBITS] & (1UL << ((fd) % __NFDBITS))) != 0)
|
||||
|
||||
static inline int montauk_fdset_empty(const fd_set *s)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (s == NULL)
|
||||
return 1;
|
||||
for (i = 0; i < sizeof(s->fds_bits) / sizeof(s->fds_bits[0]); i++) {
|
||||
if (s->fds_bits[i] != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int montauk_fdset_count(const fd_set *s, int nfds)
|
||||
{
|
||||
int fd, n = 0;
|
||||
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
for (fd = 0; fd < nfds && fd < FD_SETSIZE; fd++) {
|
||||
if (FD_ISSET(fd, s))
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout)
|
||||
{
|
||||
int ready;
|
||||
|
||||
if (writefds != NULL)
|
||||
FD_ZERO(writefds);
|
||||
if (exceptfds != NULL)
|
||||
FD_ZERO(exceptfds);
|
||||
|
||||
if (montauk_fdset_empty(readfds) == 0) {
|
||||
/* leave readfds as-is: every requested fd is "ready" */
|
||||
return montauk_fdset_count(readfds, nfds);
|
||||
}
|
||||
|
||||
ready = 0;
|
||||
|
||||
if (timeout != NULL) {
|
||||
unsigned long usec = (unsigned long) timeout->tv_sec * 1000000UL +
|
||||
(unsigned long) timeout->tv_usec;
|
||||
if (usec != 0)
|
||||
usleep(usec);
|
||||
}
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Minimal <sys/socket.h> for the MontaukOS NetSurf port.
|
||||
*
|
||||
* NetSurf includes this via utils/inet.h. MontaukOS has no BSD socket layer
|
||||
* (the kernel exposes sockets as IPC handles through montauk::socket), so this
|
||||
* supplies only the few declarations NetSurf's non-curl paths actually touch:
|
||||
* the address families and socklen_t. Nothing here opens a socket.
|
||||
*/
|
||||
#ifndef _MONTAUK_COMPAT_SYS_SOCKET_H_
|
||||
#define _MONTAUK_COMPAT_SYS_SOCKET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_INET 2
|
||||
#define AF_INET6 10
|
||||
|
||||
typedef uint32_t socklen_t;
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
|
||||
/*
|
||||
* socket() exists only so desktop/gui_factory.c compiles: it installs
|
||||
* gui_default_socket_open() into the fetch table, and that default is reached
|
||||
* only by a fetcher that opens sockets -- i.e. curl, which is not built here.
|
||||
*
|
||||
* It deliberately FAILS rather than pretending. MontaukOS sockets are IPC
|
||||
* handles obtained through montauk::socket() and are not interchangeable with
|
||||
* BSD descriptors, so any caller reaching this wants the real fetcher instead.
|
||||
* fetch_montauk will provide its own socket_open in the fetch table.
|
||||
*/
|
||||
static inline int socket(int domain, int type, int protocol)
|
||||
{
|
||||
(void) domain;
|
||||
(void) type;
|
||||
(void) protocol;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user