mirror of
https://github.com/fluffos/fluffos
synced 2026-08-12 18:26:06 -04:00
Source resolution is now explicit-extension-exact: load_object("/foo.c")
probes only foo.c, never foo.lpc (and vice versa); extension-less names
prefer .lpc and fall back to .c. Object identity stays extension-blind:
object names carry no extension, any spelling finds a loaded object, and
the registry is consulted before the filesystem. The caller's raw
spelling now flows through find_object()/inherit/master/simul_efun loads
instead of being pre-stripped away.
- filename_to_obname and otable basename() strip .lpc too (children())
- save_object() strips either source extension before appending .o
- replace_program()/function_exists() handle both suffixes
- testsuite: all LPC sources renamed to .lpc; runner globs, master
get_include_path cases, and program-name assertions updated;
README.md rewritten with the extension rules and suite conventions
- new single/tests/efuns/dual_extension.lpc pins exact-pick, fallback,
no-crossover, identity, and registry-before-filesystem with .c/.lpc
fixture pairs in /clone
Verified: ctest 297/297 and driver-autotest x3 (ASan Debug) plus
RelWithDebInfo ctest + autotest.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
126 lines
4 KiB
Text
126 lines
4 KiB
Text
#define EESUCCESS 1 /* Call was successful */
|
|
#define EESOCKET -1 /* Problem creating socket */
|
|
#define EESETSOCKOPT -2 /* Problem with setsockopt */
|
|
#define EENONBLOCK -3 /* Problem setting non-blocking mode */
|
|
#define EENOSOCKS -4 /* UNUSED */
|
|
#define EEFDRANGE -5 /* Descriptor out of range */
|
|
#define EEBADF -6 /* Descriptor is invalid */
|
|
#define EESECURITY -7 /* Security violation attempted */
|
|
#define EEISBOUND -8 /* Socket is already bound */
|
|
#define EEADDRINUSE -9 /* Address already in use */
|
|
#define EEBIND -10 /* Problem with bind */
|
|
#define EEGETSOCKNAME -11 /* Problem with getsockname */
|
|
#define EEMODENOTSUPP -12 /* Socket mode not supported */
|
|
#define EENOADDR -13 /* Socket not bound to an address */
|
|
#define EEISCONN -14 /* Socket is already connected */
|
|
#define EELISTEN -15 /* Problem with listen */
|
|
#define EENOTLISTN -16 /* Socket not listening */
|
|
#define EEWOULDBLOCK -17 /* Operation would block */
|
|
#define EEINTR -18 /* Interrupted system call */
|
|
#define EEACCEPT -19 /* Problem with accept */
|
|
#define EEISLISTEN -20 /* Socket is listening */
|
|
#define EEBADADDR -21 /* Problem with address format */
|
|
#define EEALREADY -22 /* Operation already in progress */
|
|
#define EECONNREFUSED -23 /* Connection refused */
|
|
#define EECONNECT -24 /* Problem with connect */
|
|
#define EENOTCONN -25 /* Socket not connected */
|
|
#define EETYPENOTSUPP -26 /* Object type not supported */
|
|
#define EESENDTO -27 /* Problem with sendto */
|
|
#define EESEND -28 /* Problem with send */
|
|
#define EECALLBACK -29 /* Wait for callback */
|
|
#define EESOCKRLSD -30 /* Socket already released */
|
|
#define EESOCKNOTRLSD -31 /* Socket not released */
|
|
#define EEBADDATA -32 /* sending data with too many nested levels */
|
|
#define WRITE_WAIT_CALLBACK 0
|
|
#define WRITE_GO_AHEAD 1
|
|
|
|
#define STREAM 1
|
|
#define DATAGRAM 2
|
|
#define STREAM_TLS 5
|
|
|
|
#define STATE_RESOLVING 0
|
|
#define STATE_CONNECTING 1
|
|
#define STATE_CLOSED 2
|
|
#define STATE_CONNECTED 3
|
|
|
|
#define SO_TLS_VERIFY_PEER 1
|
|
#define SO_TLS_SNI_HOSTNAME 2
|
|
|
|
|
|
nosave mapping hostname_to_fd;
|
|
nosave mapping status;
|
|
nosave object receiver;
|
|
|
|
void create() {
|
|
hostname_to_fd = ([]);
|
|
status = ([]);
|
|
}
|
|
|
|
void socket_shutdown(int fd) {
|
|
status[fd]["status"] = STATE_CLOSED;
|
|
evaluate(status[fd]["callback"], status[fd]["result"]);
|
|
}
|
|
|
|
void receive_data(int fd, mixed result) {
|
|
tell_object(receiver, sprintf("fd %d received %d bytes.\n", fd, sizeof(result)));
|
|
status[fd]["result"] += result;
|
|
}
|
|
|
|
void write_data(int fd) {
|
|
status[fd]["status"] = STATE_CONNECTED;
|
|
tell_object(receiver, sprintf("write_data: %O\n", status));
|
|
|
|
socket_write(fd, "GET " + status[fd]["path"] + " HTTP/1.0\nHost: " + status[fd]["host"] + "\n\r\n\r");
|
|
}
|
|
|
|
void on_resolve(string host, string addr, int key) {
|
|
int fd;
|
|
int ret;
|
|
|
|
tell_object(receiver, sprintf("%s: %s\n", host, addr));
|
|
|
|
if (addr)
|
|
{
|
|
fd = hostname_to_fd[host];
|
|
|
|
ret = socket_connect(fd, addr + " " + status[fd]["port"], "receive_data", "write_data");
|
|
if(ret != EESUCCESS){
|
|
tell_object(receiver, "unable to connect: " + socket_error(ret) + "\n");
|
|
socket_close(fd);
|
|
return ;
|
|
}
|
|
|
|
status[fd]["status"] = STATE_CONNECTING;
|
|
tell_object(receiver, sprintf("on_resolve: %O\n", socket_status(fd)));
|
|
}
|
|
}
|
|
|
|
|
|
int get(string host, int port, string path, int tls, mixed callback) {
|
|
int ret;
|
|
int fd;
|
|
|
|
receiver = this_player();
|
|
|
|
fd = socket_create(tls ? STREAM_TLS : STREAM, "receive_data", "socket_shutdown");
|
|
|
|
if (tls) {
|
|
socket_set_option(fd, SO_TLS_VERIFY_PEER, 1);
|
|
socket_set_option(fd, SO_TLS_SNI_HOSTNAME, host);
|
|
}
|
|
|
|
status[fd] = ([]);
|
|
status[fd]["status"] = STATE_RESOLVING;
|
|
status[fd]["host"] = host;
|
|
status[fd]["port"] = port;
|
|
status[fd]["path"] = path;
|
|
status[fd]["result"] = "";
|
|
status[fd]["caller"] = previous_object();
|
|
status[fd]["callback"] = bind(callback, previous_object());
|
|
|
|
|
|
tell_object(receiver, sprintf("get: %O\n", status));
|
|
hostname_to_fd[host] = fd;
|
|
resolve(host, "on_resolve");
|
|
return 0;
|
|
}
|