diff --git a/racket/src/racket/src/error.c b/racket/src/racket/src/error.c index f6a1c03108..ffb55e149f 100644 --- a/racket/src/racket/src/error.c +++ b/racket/src/racket/src/error.c @@ -4514,6 +4514,8 @@ scheme_raise_exn(int id, ...) Scheme_Object *eargs[MZEXN_MAXARGS], *errno_val = NULL; char *buffer; + rktio_remap_last_error(scheme_rktio); + /* Precise GC: Don't allocate before getting hidden args off stack */ HIDE_FROM_XFORM(va_start(args, id)); diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 2f88ea861e..622b8b615a 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -4634,9 +4634,9 @@ static Scheme_Object *filesystem_root_list(int argc, Scheme_Object *argv[]) scheme_security_check_file("filesystem-root-list", NULL, SCHEME_GUARD_FILE_EXISTS); - roots = rktio_filesystem_root_list(scheme_rktio); + roots = rktio_filesystem_roots(scheme_rktio); for (i = 0; roots[i]; i++) { - v = scheme_make_pair(scheme_make_sized_offset_path(roots[i], strlen(roots[i]), -1, 1), scheme_null); + v = scheme_make_pair(scheme_make_sized_offset_path(roots[i], 0, -1, 1), scheme_null); if (last) SCHEME_CDR(last) = v; else diff --git a/racket/src/racket/src/mzmark_port.inc b/racket/src/racket/src/mzmark_port.inc index 0b5528b695..e8860adea2 100644 --- a/racket/src/racket/src/mzmark_port.inc +++ b/racket/src/racket/src/mzmark_port.inc @@ -97,7 +97,7 @@ static int mark_input_fd_MARK(void *p, struct NewGC *gc) { Scheme_FD *fd = (Scheme_FD *)p; gcMARK2(fd->buffer, gc); - gcMARK2(fd->refcount, gc); + /* fd->refcount is malloc()ed */ gcMARK2(fd->flush_handle, gc); gcMARK2(fd->bufwidths, gc); @@ -115,7 +115,7 @@ static int mark_input_fd_FIXUP(void *p, struct NewGC *gc) { Scheme_FD *fd = (Scheme_FD *)p; gcFIXUP2(fd->buffer, gc); - gcFIXUP2(fd->refcount, gc); + /* fd->refcount is malloc()ed */ gcFIXUP2(fd->flush_handle, gc); gcFIXUP2(fd->bufwidths, gc); diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index 4118017551..1b861591d8 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -1736,7 +1736,7 @@ mark_input_fd { Scheme_FD *fd = (Scheme_FD *)p; gcMARK2(fd->buffer, gc); - gcMARK2(fd->refcount, gc); + /* fd->refcount is malloc()ed */ gcMARK2(fd->flush_handle, gc); gcMARK2(fd->bufwidths, gc); diff --git a/racket/src/racket/src/network.c b/racket/src/racket/src/network.c index ca6e79a5da..2006869fee 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -40,6 +40,7 @@ typedef struct { typedef struct Scheme_Tcp_Buf { MZTAG_IF_REQUIRED short refcount; + short forget_on_close; char *buffer, *out_buffer; short bufpos, bufmax; short hiteof, bufmode; @@ -462,7 +463,10 @@ static void tcp_close_input(Scheme_Input_Port *port) (void)scheme_rktio_fd_to_semaphore(data->tcp, MZFD_REMOVE); - rktio_close(scheme_rktio, data->tcp); + if (data->b.forget_on_close) + rktio_forget(scheme_rktio, data->tcp); + else + rktio_close(scheme_rktio, data->tcp); } static int @@ -635,7 +639,10 @@ static void tcp_close_output(Scheme_Output_Port *port) (void)scheme_rktio_fd_to_semaphore(data->tcp, MZFD_REMOVE); - rktio_close(scheme_rktio, data->tcp); + if (data->b.forget_on_close) + rktio_forget(scheme_rktio, data->tcp); + else + rktio_close(scheme_rktio, data->tcp); } static int @@ -741,6 +748,7 @@ static Connect_Progress_Data *make_connect_progress_data() pd->connect = NULL; pd->dest_addr = NULL; pd->src_addr = NULL; + pd->trying_s = NULL; pd->s = NULL; return pd; @@ -1583,7 +1591,9 @@ void scheme_socket_to_ports(intptr_t s, const char *name, int takeover, rfd = rktio_system_fd(scheme_rktio, s, RKTIO_OPEN_READ | RKTIO_OPEN_WRITE | RKTIO_OPEN_SOCKET | RKTIO_OPEN_OWN); - tcp = make_tcp_port_data(rfd, takeover ? 2 : 3); + tcp = make_tcp_port_data(rfd, 2); + if (!takeover) + tcp->b.forget_on_close = 1; v = make_tcp_input_port(tcp, name, NULL); *_inp = v; diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 26d960021d..2a377031de 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -4740,11 +4740,10 @@ fd_close_input(Scheme_Input_Port *port) fip = (Scheme_FD *)port->port_data; rc = adj_refcount(fip->refcount, -1); - if (!rc) { + if (!rc) rktio_close(scheme_rktio, fip->fd); - } else { + else rktio_forget(scheme_rktio, fip->fd); - } } static void @@ -5327,6 +5326,7 @@ make_fd_output_port(rktio_fd_t *fd, Scheme_Object *name, int and_read, int flush Scheme_Object *a[2]; rc = malloc_refcount(1, 1); fop->refcount = rc; + fd = rktio_system_fd(scheme_rktio, rktio_fd_system_fd(scheme_rktio, fd), rktio_fd_modes(scheme_rktio, fd)); a[1] = the_port; a[0] = make_fd_input_port(fd, name, rc, 0); return scheme_values(2, a); diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 4e8973c33a..7c60454e32 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -3916,6 +3916,8 @@ static int check_fd_semaphores() if (!scheme_semaphore_fd_set) return 0; + rktio_ltps_poll(scheme_rktio, scheme_semaphore_fd_set); + while (1) { h = rktio_ltps_get_signaled_handle(scheme_rktio, scheme_semaphore_fd_set); if (h) { diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index 60913649ea..6b1b6fbc69 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -153,7 +153,7 @@ RKTIO_EXTERN int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd); RKTIO_EXTERN rktio_fd_t *rktio_open(rktio_t *rktio, const char *src, int modes); /* Can report `RKTIO_ERROR_DOES_NOT_EXIST` in place of system error, - and can report `RKTIO_ERROR_UNSUPPORTED_TEXT_MODE` on Windows:=. */ + and can report `RKTIO_ERROR_UNSUPPORTED_TEXT_MODE` on Windows. */ RKTIO_EXTERN rktio_ok_t rktio_close(rktio_t *rktio, rktio_fd_t *fd); /* Can report `RKTIO_ERROR_EXISTS` in place of system error, @@ -702,7 +702,7 @@ RKTIO_EXTERN void rktio_directory_list_stop(rktio_t *rktio, rktio_directory_list /* Interrupt a directory list in progress, not needed after rktio_directory_list_step() returns "": */ -RKTIO_EXTERN char **rktio_filesystem_root_list(rktio_t *rktio); +RKTIO_EXTERN char **rktio_filesystem_roots(rktio_t *rktio); /* Returns a NULL-terminated array. Free each string. Currently never errors. */ @@ -822,6 +822,11 @@ enum { RKTIO_EXTERN void rktio_set_last_error(rktio_t *rktio, int kind, int errid); /* In case you need to save and restore error information. */ +RKTIO_EXTERN void rktio_remap_last_error(rktio_t *rktio); +/* In a few cases, rktio substitutes a `RKTIO_ERROR_KIND_RACKET` error + for an OS-supplied error. This function can sometimes undo the + substitition, modifying the current error and kind. */ + RKTIO_EXTERN const char *rktio_get_last_error_string(rktio_t *rktio); RKTIO_EXTERN const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid); /* The returned strings for `rktio_...error_string()` should not be diff --git a/racket/src/rktio/rktio_envvars.c b/racket/src/rktio/rktio_envvars.c index 17cf4b578d..09367c2e4f 100644 --- a/racket/src/rktio/rktio_envvars.c +++ b/racket/src/rktio/rktio_envvars.c @@ -9,6 +9,10 @@ struct rktio_envvars_t { char **vals; }; +#ifdef OS_X +# define SETENV_DROPS_LEADING_EQUAL_SIGN +#endif + #if defined(OS_X) && !TARGET_OS_IPHONE # include # define GET_ENVIRON_ARRAY *_NSGetEnviron() @@ -85,8 +89,24 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val) #ifdef RKTIO_SYSTEM_UNIX if (val) { int r; +#ifdef SETENV_DROPS_LEADING_EQUAL_SIGN + char *tmp = NULL; + + if (val[0] == '=') { + intptr_t len = strlen(val); + tmp = malloc(len + 2); + memcpy(tmp + 1, val, len + 1); + tmp[0] = '='; + val = tmp; + } +#endif r = setenv(name, val, 1); + +#ifdef SETENV_DROPS_LEADING_EQUAL_SIGN + if (tmp) + free(tmp); +#endif if (r) get_posix_error(); diff --git a/racket/src/rktio/rktio_error.c b/racket/src/rktio/rktio_error.c index fd4f69a94f..ba8d765c08 100644 --- a/racket/src/rktio/rktio_error.c +++ b/racket/src/rktio/rktio_error.c @@ -81,6 +81,22 @@ void rktio_set_last_error(rktio_t *rktio, int kind, int errid) rktio->errid = errid; } +void rktio_remap_last_error(rktio_t *rktio) +{ + if (rktio->errkind == RKTIO_ERROR_KIND_RACKET) { + switch (rktio->errid) { + case RKTIO_ERROR_DOES_NOT_EXIST: +#ifdef RKTIO_SYSTEM_UNIX + rktio_set_last_error(rktio, RKTIO_ERROR_KIND_POSIX, ENOENT); +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + rktio_set_last_error(rktio, RKTIO_ERROR_KIND_WINDOWS, ERROR_FILE_NOT_FOUND); +#endif + break; + } + } +} + const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid) { const char *s = NULL; diff --git a/racket/src/rktio/rktio_fs.c b/racket/src/rktio/rktio_fs.c index cd6bdb1733..91e9b30b51 100644 --- a/racket/src/rktio/rktio_fs.c +++ b/racket/src/rktio/rktio_fs.c @@ -1630,7 +1630,7 @@ void rktio_copy_file_stop(rktio_t *rktio, rktio_file_copy_t *fc) /* filesystem root list */ /*========================================================================*/ -char **rktio_filesystem_root_list(rktio_t *rktio) +char **rktio_filesystem_roots(rktio_t *rktio) /* returns a NULL-terminated array of strings */ { #ifdef RKTIO_SYSTEM_WINDOWS @@ -1682,8 +1682,8 @@ char **rktio_filesystem_root_list(rktio_t *rktio) char **ss; ss = malloc(sizeof(char*) * 2); - ss[1] = strdup("/"); - ss[0] = NULL; + ss[0] = strdup("/"); + ss[1] = NULL; return ss; #endif