rktio: put "globals" in an rktio_t
Avoid thread-local state by threading a `rktio_t` record through everything.
This commit is contained in:
parent
68352ef86a
commit
09703b94f7
|
@ -9,13 +9,17 @@ RKTIO_HEADERS = $(srcdir)/rktio.h $(srcdir)/rktio_private.h rktio_config.h
|
||||||
OBJS = rktio_filesystem.o \
|
OBJS = rktio_filesystem.o \
|
||||||
rktio_read_write.o \
|
rktio_read_write.o \
|
||||||
rktio_poll_set.o \
|
rktio_poll_set.o \
|
||||||
rktio_error.o
|
rktio_error.o \
|
||||||
|
rktio_main.o
|
||||||
|
|
||||||
all: $(OBJS)
|
all: $(OBJS)
|
||||||
|
|
||||||
demo: $(OBJS) main.o
|
demo: $(OBJS) main.o demo_fifo
|
||||||
$(CC) -o demo $(CFLAGS) $(LDFLAGS) main.o $(OBJS)
|
$(CC) -o demo $(CFLAGS) $(LDFLAGS) main.o $(OBJS)
|
||||||
|
|
||||||
|
demo_fifo:
|
||||||
|
mkfifo demo_fifo
|
||||||
|
|
||||||
rktio_filesystem.o: $(srcdir)/rktio_filesystem.c $(RKTIO_HEADERS)
|
rktio_filesystem.o: $(srcdir)/rktio_filesystem.c $(RKTIO_HEADERS)
|
||||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_filesystem.o -c $(srcdir)/rktio_filesystem.c
|
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_filesystem.o -c $(srcdir)/rktio_filesystem.c
|
||||||
|
|
||||||
|
@ -28,5 +32,8 @@ rktio_poll_set.o: $(srcdir)/rktio_poll_set.c $(RKTIO_HEADERS)
|
||||||
rktio_error.o: $(srcdir)/rktio_error.c $(RKTIO_HEADERS)
|
rktio_error.o: $(srcdir)/rktio_error.c $(RKTIO_HEADERS)
|
||||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_error.o -c $(srcdir)/rktio_error.c
|
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_error.o -c $(srcdir)/rktio_error.c
|
||||||
|
|
||||||
|
rktio_main.o: $(srcdir)/rktio_main.c $(RKTIO_HEADERS)
|
||||||
|
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_main.o -c $(srcdir)/rktio_main.c
|
||||||
|
|
||||||
main.o: $(srcdir)/main.c $(RKTIO_HEADERS)
|
main.o: $(srcdir)/main.c $(RKTIO_HEADERS)
|
||||||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o main.o -c $(srcdir)/main.c
|
$(CC) $(CFLAGS) -I$(srcdir) -I. -o main.o -c $(srcdir)/main.c
|
||||||
|
|
|
@ -3,19 +3,20 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static void do_check_valid(int ok, int where)
|
static void do_check_valid(rktio_t *rktio, int ok, int where)
|
||||||
{
|
{
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
printf("error at %d: %d@%d = %s\n",
|
printf("error at %d: %d@%d = %s\n",
|
||||||
where,
|
where,
|
||||||
rktio_get_last_error(),
|
rktio_get_last_error(rktio),
|
||||||
rktio_get_last_error_kind(),
|
rktio_get_last_error_kind(rktio),
|
||||||
rktio_get_error_string(rktio_get_last_error(),
|
rktio_get_error_string(rktio,
|
||||||
rktio_get_last_error_kind()));
|
rktio_get_last_error_kind(rktio),
|
||||||
|
rktio_get_last_error(rktio)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_check_expected_error(int err, int where)
|
static void do_check_expected_error(rktio_t *rktio, int err, int where)
|
||||||
{
|
{
|
||||||
if (!err) {
|
if (!err) {
|
||||||
printf("error expected at %d\n",
|
printf("error expected at %d\n",
|
||||||
|
@ -23,121 +24,165 @@ static void do_check_expected_error(int err, int where)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_check_expected_racket_error(int err, int what, int where)
|
static void do_check_expected_racket_error(rktio_t *rktio, int err, int what, int where)
|
||||||
{
|
{
|
||||||
if (!err) {
|
if (!err) {
|
||||||
printf("error expected at %d\n",
|
printf("error expected at %d\n",
|
||||||
where);
|
where);
|
||||||
} else if ((what != rktio_get_last_error())
|
} else if ((what != rktio_get_last_error(rktio))
|
||||||
|| (RKTIO_ERROR_KIND_RACKET != rktio_get_last_error_kind())) {
|
|| (RKTIO_ERROR_KIND_RACKET != rktio_get_last_error_kind(rktio))) {
|
||||||
printf("wrong error at %d: %d@%d = %s\n",
|
printf("wrong error at %d: %d@%d = %s\n",
|
||||||
where,
|
where,
|
||||||
rktio_get_last_error(),
|
rktio_get_last_error(rktio),
|
||||||
rktio_get_last_error_kind(),
|
rktio_get_last_error_kind(rktio),
|
||||||
rktio_get_error_string(rktio_get_last_error(),
|
rktio_get_error_string(rktio,
|
||||||
rktio_get_last_error_kind()));
|
rktio_get_last_error_kind(rktio),
|
||||||
|
rktio_get_last_error(rktio)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define check_valid(e) do_check_valid(e, __LINE__)
|
#define check_valid(e) do_check_valid(rktio, e, __LINE__)
|
||||||
#define check_expected_error(e) do_check_expected_error(e, __LINE__)
|
#define check_expected_error(e) do_check_expected_error(rktio, e, __LINE__)
|
||||||
#define check_expected_racket_error(e, what) do_check_expected_racket_error(e, what, __LINE__)
|
#define check_expected_racket_error(e, what) do_check_expected_racket_error(rktio, e, what, __LINE__)
|
||||||
|
|
||||||
static void check_hello_content(char *fn)
|
static void check_hello_content(rktio_t *rktio, char *fn)
|
||||||
{
|
{
|
||||||
rktio_fd_t *fd;
|
rktio_fd_t *fd;
|
||||||
intptr_t amt;
|
intptr_t amt;
|
||||||
char buffer[256], *s;
|
char buffer[256], *s;
|
||||||
|
|
||||||
fd = rktio_open(fn, RKTIO_OPEN_READ);
|
fd = rktio_open(rktio, fn, RKTIO_OPEN_READ);
|
||||||
check_valid(!!fd);
|
check_valid(!!fd);
|
||||||
check_valid(rktio_poll_read_ready(fd) != RKTIO_POLL_ERROR);
|
check_valid(rktio_poll_read_ready(rktio, fd) != RKTIO_POLL_ERROR);
|
||||||
amt = rktio_read(fd, buffer, sizeof(buffer));
|
amt = rktio_read(rktio, fd, buffer, sizeof(buffer));
|
||||||
check_valid(amt == 5);
|
check_valid(amt == 5);
|
||||||
check_valid(!strncmp(buffer, "hello", 5));
|
check_valid(!strncmp(buffer, "hello", 5));
|
||||||
check_valid(rktio_close(fd));
|
amt = rktio_read(rktio, fd, buffer, sizeof(buffer));
|
||||||
|
check_valid(amt == RKTIO_READ_EOF);
|
||||||
|
check_valid(rktio_close(rktio, fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
rktio_t *rktio;
|
||||||
rktio_size_t *sz;
|
rktio_size_t *sz;
|
||||||
rktio_fd_t *fd;
|
rktio_fd_t *fd, *fd2;
|
||||||
intptr_t amt, i,saw_file;
|
intptr_t amt, i, saw_file;
|
||||||
char *s, *pwd;
|
int perms;
|
||||||
|
char buffer[256], *s, *pwd;
|
||||||
rktio_directory_list_t *ls;
|
rktio_directory_list_t *ls;
|
||||||
rktio_file_copy_t *cp;
|
rktio_file_copy_t *cp;
|
||||||
|
rktio_timestamp_t *ts1, *ts1a;
|
||||||
|
|
||||||
fd = rktio_open("test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
|
rktio = rktio_init();
|
||||||
|
|
||||||
|
/* Basic file I/O */
|
||||||
|
|
||||||
|
fd = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
|
||||||
check_valid(!!fd);
|
check_valid(!!fd);
|
||||||
check_valid(rktio_poll_write_ready(fd) != RKTIO_POLL_ERROR);
|
check_valid(rktio_poll_write_ready(rktio, fd) != RKTIO_POLL_ERROR);
|
||||||
amt = rktio_write(fd, "hello", 5);
|
amt = rktio_write(rktio, fd, "hello", 5);
|
||||||
check_valid(amt == 5);
|
check_valid(amt == 5);
|
||||||
check_valid(rktio_close(fd));
|
check_valid(rktio_close(rktio, fd));
|
||||||
|
|
||||||
check_valid(rktio_file_exists("test1"));
|
check_valid(rktio_file_exists(rktio, "test1"));
|
||||||
check_valid(!rktio_directory_exists("test1"));
|
check_valid(!rktio_directory_exists(rktio, "test1"));
|
||||||
check_valid(rktio_is_regular_file("test1"));
|
check_valid(rktio_is_regular_file(rktio, "test1"));
|
||||||
|
|
||||||
s = rktio_get_current_directory();
|
s = rktio_get_current_directory(rktio);
|
||||||
check_valid(!!s);
|
check_valid(!!s);
|
||||||
check_valid(rktio_directory_exists(s));
|
check_valid(rktio_directory_exists(rktio, s));
|
||||||
check_valid(!rktio_file_exists(s));
|
check_valid(!rktio_file_exists(rktio, s));
|
||||||
check_valid(!rktio_is_regular_file(s));
|
check_valid(!rktio_is_regular_file(rktio, s));
|
||||||
check_expected_racket_error(!rktio_open(s, RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST),
|
check_expected_racket_error(!rktio_open(rktio, s, RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST),
|
||||||
RKTIO_ERROR_IS_A_DIRECTORY);
|
RKTIO_ERROR_IS_A_DIRECTORY);
|
||||||
pwd = s;
|
pwd = s;
|
||||||
|
|
||||||
sz = rktio_file_size("test1");
|
sz = rktio_file_size(rktio, "test1");
|
||||||
check_valid(!!sz);
|
check_valid(!!sz);
|
||||||
check_valid(sz->lo == 5);
|
check_valid(sz->lo == 5);
|
||||||
check_valid(sz->hi == 0);
|
check_valid(sz->hi == 0);
|
||||||
free(sz);
|
free(sz);
|
||||||
|
|
||||||
fd = rktio_open("test2", RKTIO_OPEN_WRITE | RKTIO_OPEN_MUST_EXIST);
|
fd = rktio_open(rktio, "test2", RKTIO_OPEN_WRITE | RKTIO_OPEN_MUST_EXIST);
|
||||||
check_expected_error(!fd);
|
check_expected_error(!fd);
|
||||||
|
|
||||||
fd = rktio_open("test1", RKTIO_OPEN_WRITE);
|
fd = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE);
|
||||||
check_expected_racket_error(!fd, RKTIO_ERROR_EXISTS);
|
check_expected_racket_error(!fd, RKTIO_ERROR_EXISTS);
|
||||||
|
|
||||||
check_hello_content("test1");
|
check_hello_content(rktio, "test1");
|
||||||
|
|
||||||
if (rktio_file_exists("test1a"))
|
/* Copying, renaming, and deleting files */
|
||||||
check_valid(rktio_delete_file("test1a", 1));
|
|
||||||
if (rktio_file_exists("test1b"))
|
|
||||||
check_valid(rktio_delete_file("test1b", 1));
|
|
||||||
|
|
||||||
cp = rktio_copy_file_start("test1a", "test1", 0);
|
if (rktio_file_exists(rktio, "test1a"))
|
||||||
|
check_valid(rktio_delete_file(rktio, "test1a", 1));
|
||||||
|
if (rktio_file_exists(rktio, "test1b"))
|
||||||
|
check_valid(rktio_delete_file(rktio, "test1b", 1));
|
||||||
|
|
||||||
|
ts1 = rktio_get_file_modify_seconds(rktio, "test1a");
|
||||||
|
check_expected_error(!ts1);
|
||||||
|
perms = rktio_get_file_or_directory_permissions(rktio, "test1a", 1);
|
||||||
|
check_expected_error(perms == -1);
|
||||||
|
check_expected_error(!rktio_set_file_or_directory_permissions(rktio, "test1a", 511));
|
||||||
|
|
||||||
|
ts1 = rktio_get_file_modify_seconds(rktio, "test1");
|
||||||
|
perms = rktio_get_file_or_directory_permissions(rktio, "test1", 0);
|
||||||
|
check_valid(perms != -1);
|
||||||
|
check_valid(perms & (RKTIO_PERMISSION_READ << 6));
|
||||||
|
check_valid(perms & (RKTIO_PERMISSION_WRITE << 6));
|
||||||
|
perms = rktio_get_file_or_directory_permissions(rktio, "test1", 1);
|
||||||
|
check_valid(perms != -1);
|
||||||
|
check_valid(perms & (RKTIO_PERMISSION_READ << 6));
|
||||||
|
check_valid(perms & (RKTIO_PERMISSION_WRITE << 6));
|
||||||
|
check_valid(rktio_set_file_or_directory_permissions(rktio, "test1", perms & (0x7 << 6)));
|
||||||
|
check_valid((perms & (0x7 << 6)) == rktio_get_file_or_directory_permissions(rktio, "test1", 1));
|
||||||
|
rktio_set_file_or_directory_permissions(rktio, "test1", perms);
|
||||||
|
|
||||||
|
cp = rktio_copy_file_start(rktio, "test1a", "test1", 0);
|
||||||
check_valid(!!cp);
|
check_valid(!!cp);
|
||||||
while (!rktio_copy_file_is_done(cp)) {
|
while (!rktio_copy_file_is_done(rktio, cp)) {
|
||||||
check_valid(rktio_copy_file_step(cp));
|
check_valid(rktio_copy_file_step(rktio, cp));
|
||||||
}
|
}
|
||||||
rktio_copy_file_stop(cp);
|
rktio_copy_file_stop(rktio, cp);
|
||||||
check_hello_content("test1a");
|
check_hello_content(rktio, "test1a");
|
||||||
|
|
||||||
check_valid(rktio_file_exists("test1a"));
|
ts1a = rktio_get_file_modify_seconds(rktio, "test1a");
|
||||||
cp = rktio_copy_file_start("test1a", "test1", 0);
|
check_valid(*ts1a >= *ts1);
|
||||||
|
|
||||||
|
rktio_set_file_modify_seconds(rktio, "test1a", *ts1 - 10);
|
||||||
|
free(ts1a);
|
||||||
|
ts1a = rktio_get_file_modify_seconds(rktio, "test1a");
|
||||||
|
check_valid(*ts1a == (*ts1 - 10));
|
||||||
|
|
||||||
|
free(ts1);
|
||||||
|
free(ts1a);
|
||||||
|
|
||||||
|
check_valid(rktio_file_exists(rktio, "test1a"));
|
||||||
|
cp = rktio_copy_file_start(rktio, "test1a", "test1", 0);
|
||||||
check_expected_racket_error(!cp, RKTIO_ERROR_EXISTS);
|
check_expected_racket_error(!cp, RKTIO_ERROR_EXISTS);
|
||||||
|
|
||||||
cp = rktio_copy_file_start("test1a", "test1", 1);
|
cp = rktio_copy_file_start(rktio, "test1a", "test1", 1);
|
||||||
check_valid(!!cp);
|
check_valid(!!cp);
|
||||||
rktio_copy_file_stop(cp);
|
rktio_copy_file_stop(rktio, cp);
|
||||||
|
|
||||||
check_valid(rktio_rename_file("test1b", "test1a", 0));
|
check_valid(rktio_rename_file(rktio, "test1b", "test1a", 0));
|
||||||
check_valid(rktio_file_exists("test1b"));
|
check_valid(rktio_file_exists(rktio, "test1b"));
|
||||||
check_expected_racket_error(!rktio_rename_file("test1b", "test1", 0),
|
check_expected_racket_error(!rktio_rename_file(rktio, "test1b", "test1", 0),
|
||||||
RKTIO_ERROR_EXISTS);
|
RKTIO_ERROR_EXISTS);
|
||||||
check_valid(rktio_file_exists("test1"));
|
check_valid(rktio_file_exists(rktio, "test1"));
|
||||||
check_valid(rktio_file_exists("test1b"));
|
check_valid(rktio_file_exists(rktio, "test1b"));
|
||||||
check_valid(!rktio_file_exists("test1a"));
|
check_valid(!rktio_file_exists(rktio, "test1a"));
|
||||||
|
|
||||||
check_valid(rktio_delete_file("test1b", 0));
|
check_valid(rktio_delete_file(rktio, "test1b", 0));
|
||||||
check_valid(!rktio_file_exists("test1b"));
|
check_valid(!rktio_file_exists(rktio, "test1b"));
|
||||||
|
|
||||||
ls = rktio_directory_list_start(pwd, 0);
|
/* Listing directory content */
|
||||||
|
|
||||||
|
ls = rktio_directory_list_start(rktio, pwd, 0);
|
||||||
check_valid(!!ls);
|
check_valid(!!ls);
|
||||||
saw_file = 0;
|
saw_file = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
s = rktio_directory_list_step(ls);
|
s = rktio_directory_list_step(rktio, ls);
|
||||||
check_valid(!!s);
|
check_valid(!!s);
|
||||||
if (!*s) break;
|
if (!*s) break;
|
||||||
if (!strcmp(s, "test1"))
|
if (!strcmp(s, "test1"))
|
||||||
|
@ -146,5 +191,53 @@ int main()
|
||||||
}
|
}
|
||||||
check_valid(saw_file);
|
check_valid(saw_file);
|
||||||
|
|
||||||
|
/* Pipes and non-blocking operations */
|
||||||
|
|
||||||
|
fd = rktio_open(rktio, "demo_fifo", RKTIO_OPEN_READ);
|
||||||
|
check_valid(!!fd);
|
||||||
|
check_valid(!rktio_poll_read_ready(rktio, fd));
|
||||||
|
fd2 = rktio_open(rktio, "demo_fifo", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
|
||||||
|
check_valid(!!fd2);
|
||||||
|
check_valid(!rktio_poll_read_ready(rktio, fd));
|
||||||
|
|
||||||
|
amt = rktio_write(rktio, fd2, "hello", 5);
|
||||||
|
check_valid(amt == 5);
|
||||||
|
check_valid(rktio_poll_read_ready(rktio, fd));
|
||||||
|
amt = rktio_read(rktio, fd, buffer, sizeof(buffer));
|
||||||
|
check_valid(amt == 5);
|
||||||
|
check_valid(!strncmp(buffer, "hello", 5));
|
||||||
|
check_valid(!rktio_poll_read_ready(rktio, fd));
|
||||||
|
|
||||||
|
check_valid(rktio_close(rktio, fd2));
|
||||||
|
amt = rktio_read(rktio, fd, buffer, sizeof(buffer));
|
||||||
|
check_valid(amt == RKTIO_READ_EOF);
|
||||||
|
check_valid(rktio_close(rktio, fd));
|
||||||
|
|
||||||
|
fd2 = rktio_open(rktio, "demo_fifo", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
|
||||||
|
check_valid(!!fd2);
|
||||||
|
/* should eventually block: */
|
||||||
|
for (i = 0; i < 100000; i++) {
|
||||||
|
amt = rktio_write(rktio, fd2, "hello", 5);
|
||||||
|
check_valid(amt != RKTIO_WRITE_ERROR);
|
||||||
|
if (!amt)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
check_valid(i < 100000);
|
||||||
|
|
||||||
|
fd = rktio_open(rktio, "demo_fifo", RKTIO_OPEN_READ);
|
||||||
|
check_valid(!!fd);
|
||||||
|
/* should eventually block: */
|
||||||
|
for (i = 0; i < 100000; i++) {
|
||||||
|
amt = rktio_read(rktio, fd2, buffer, sizeof(buffer));
|
||||||
|
check_valid(amt != RKTIO_READ_ERROR);
|
||||||
|
check_valid(amt != RKTIO_READ_EOF);
|
||||||
|
if (!amt)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
check_valid(i < 100000);
|
||||||
|
|
||||||
|
check_valid(rktio_close(rktio, fd));
|
||||||
|
check_valid(rktio_close(rktio, fd2));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,18 @@
|
||||||
|
|
||||||
#include "rktio_config.h"
|
#include "rktio_config.h"
|
||||||
|
|
||||||
|
/* A rktio_t value represents an instance of the Racket I/O system.
|
||||||
|
Every rktio_...() function takes it as the first argument, except
|
||||||
|
for rktio_init(), rktio_signal_received_at(), and rktio_free(). */
|
||||||
|
typedef struct rktio_t rktio_t;
|
||||||
|
|
||||||
|
rktio_t *rktio_init(void);
|
||||||
|
void rktio_destroy(rktio_t *);
|
||||||
|
|
||||||
|
/* Normally equivalent to free(), but ensures the same malloc()/free()
|
||||||
|
that rktio function use: */
|
||||||
|
void rktio_free(void *p);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Reading and writing files */
|
/* Reading and writing files */
|
||||||
|
|
||||||
|
@ -16,23 +28,23 @@ typedef struct rktio_fd_t rktio_fd_t;
|
||||||
#define RKTIO_OPEN_MUST_EXIST (1<<5)
|
#define RKTIO_OPEN_MUST_EXIST (1<<5)
|
||||||
#define RKTIO_OPEN_CAN_EXIST (1<<6)
|
#define RKTIO_OPEN_CAN_EXIST (1<<6)
|
||||||
|
|
||||||
rktio_fd_t *rktio_system_fd(intptr_t system_fd, int modes);
|
rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes);
|
||||||
intptr_t rktio_fd_system_fd(rktio_fd_t *rfd);
|
intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
|
|
||||||
rktio_fd_t *rktio_open(char *src, int modes);
|
rktio_fd_t *rktio_open(rktio_t *rktio, char *src, int modes);
|
||||||
int rktio_close(rktio_fd_t *fd);
|
int rktio_close(rktio_t *rktio, rktio_fd_t *fd);
|
||||||
|
|
||||||
#define RKTIO_READ_EOF (-1)
|
#define RKTIO_READ_EOF (-1)
|
||||||
#define RKTIO_READ_ERROR (-2)
|
#define RKTIO_READ_ERROR (-2)
|
||||||
#define RKTIO_WRITE_ERROR (-2)
|
#define RKTIO_WRITE_ERROR (-2)
|
||||||
#define RKTIO_POLL_ERROR (-2)
|
#define RKTIO_POLL_ERROR (-2)
|
||||||
|
|
||||||
intptr_t rktio_read(rktio_fd_t *fd, char *buffer, intptr_t len);
|
intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
|
||||||
intptr_t rktio_write(rktio_fd_t *fd, char *buffer, intptr_t len);
|
intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
|
||||||
|
|
||||||
int rktio_poll_read_ready(rktio_fd_t *rfd);
|
int rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
int rktio_poll_write_ready(rktio_fd_t *rfd);
|
int rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
int rktio_poll_write_flushed(rktio_fd_t *rfd);
|
int rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* File-descriptor sets */
|
/* File-descriptor sets */
|
||||||
|
@ -42,26 +54,26 @@ typedef struct rktio_poll_set_t rktio_poll_set_t;
|
||||||
#define RKTIO_POLL_READ RKTIO_OPEN_READ
|
#define RKTIO_POLL_READ RKTIO_OPEN_READ
|
||||||
#define RKTIO_POLL_WRITE RKTIO_OPEN_WRITE
|
#define RKTIO_POLL_WRITE RKTIO_OPEN_WRITE
|
||||||
|
|
||||||
void rktio_poll_add(rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes);
|
void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Files, directories, and links */
|
/* Files, directories, and links */
|
||||||
|
|
||||||
int rktio_file_exists(char *filename);
|
int rktio_file_exists(rktio_t *rktio, char *filename);
|
||||||
int rktio_directory_exists(char *dirname);
|
int rktio_directory_exists(rktio_t *rktio, char *dirname);
|
||||||
int rktio_link_exists(char *filename);
|
int rktio_link_exists(rktio_t *rktio, char *filename);
|
||||||
int rktio_is_regular_file(char *filename);
|
int rktio_is_regular_file(rktio_t *rktio, char *filename);
|
||||||
|
|
||||||
int rktio_delete_file(char *fn, int enable_write_on_fail);
|
int rktio_delete_file(rktio_t *rktio, char *fn, int enable_write_on_fail);
|
||||||
int rktio_rename_file(char *dest, char *src, int exists_ok);
|
int rktio_rename_file(rktio_t *rktio, char *dest, char *src, int exists_ok);
|
||||||
|
|
||||||
char *rktio_get_current_directory();
|
char *rktio_get_current_directory(rktio_t *rktio);
|
||||||
int rktio_set_current_directory(char *expanded);
|
int rktio_set_current_directory(rktio_t *rktio, char *expanded);
|
||||||
int rktio_make_directory(char *filename);
|
int rktio_make_directory(rktio_t *rktio, char *filename);
|
||||||
int rktio_delete_directory(char *filename, char *current_directory, int enable_write_on_fail);
|
int rktio_delete_directory(rktio_t *rktio, char *filename, char *current_directory, int enable_write_on_fail);
|
||||||
|
|
||||||
char *rktio_readlink(char *fullfilename);
|
char *rktio_readlink(rktio_t *rktio, char *fullfilename);
|
||||||
int rktio_make_link(char *src, char *dest, int dest_is_directory);
|
int rktio_make_link(rktio_t *rktio, char *src, char *dest, int dest_is_directory);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* File attributes */
|
/* File attributes */
|
||||||
|
@ -76,43 +88,44 @@ typedef struct {
|
||||||
uintptr_t a, b, c;
|
uintptr_t a, b, c;
|
||||||
} rktio_identity_t;
|
} rktio_identity_t;
|
||||||
|
|
||||||
rktio_size_t *rktio_file_size(char *filename);
|
rktio_size_t *rktio_file_size(rktio_t *rktio, char *filename);
|
||||||
|
|
||||||
rktio_timestamp_t *rktio_get_file_modify_seconds(char *file);
|
rktio_timestamp_t *rktio_get_file_modify_seconds(rktio_t *rktio, char *file);
|
||||||
int rktio_set_file_modify_seconds(char *file, rktio_timestamp_t secs);
|
int rktio_set_file_modify_seconds(rktio_t *rktio, char *file, rktio_timestamp_t secs);
|
||||||
|
|
||||||
rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path);
|
rktio_identity_t *rktio_fd_identity(rktio_t *rktio, rktio_fd_t *fd);
|
||||||
|
rktio_identity_t *rktio_path_identity(rktio_t *rktio, char *path, int follow_links);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Permissions */
|
/* Permissions */
|
||||||
|
|
||||||
/* Must match OS bits: */
|
/* Must match OS bits: */
|
||||||
#define RKTIO_PERMISSION_READ 0x1
|
#define RKTIO_PERMISSION_READ 0x4
|
||||||
#define RKTIO_PERMISSION_WRITE 0x2
|
#define RKTIO_PERMISSION_WRITE 0x2
|
||||||
#define RKTIO_PERMISSION_EXEC 0x4
|
#define RKTIO_PERMISSION_EXEC 0x1
|
||||||
|
|
||||||
int rktio_get_file_or_directory_permissions(char *filename, int all_bits);
|
int rktio_get_file_or_directory_permissions(rktio_t *rktio, char *filename, int all_bits);
|
||||||
int rktio_set_file_or_directory_permissions(char *filename, int new_bits);
|
int rktio_set_file_or_directory_permissions(rktio_t *rktio, char *filename, int new_bits);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Directory listing */
|
/* Directory listing */
|
||||||
|
|
||||||
typedef struct rktio_directory_list_t rktio_directory_list_t;
|
typedef struct rktio_directory_list_t rktio_directory_list_t;
|
||||||
|
|
||||||
rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive);
|
rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive);
|
||||||
char *rktio_directory_list_step(rktio_directory_list_t *dl);
|
char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl);
|
||||||
|
|
||||||
char **rktio_filesystem_root_list();
|
char **rktio_filesystem_root_list(rktio_t *rktio);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* File copying */
|
/* File copying */
|
||||||
|
|
||||||
typedef struct rktio_file_copy_t rktio_file_copy_t;
|
typedef struct rktio_file_copy_t rktio_file_copy_t;
|
||||||
|
|
||||||
rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok);
|
rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, char *dest, char *src, int exists_ok);
|
||||||
int rktio_copy_file_is_done(rktio_file_copy_t *fc);
|
int rktio_copy_file_is_done(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||||
int rktio_copy_file_step(rktio_file_copy_t *fc);
|
int rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||||
void rktio_copy_file_stop(rktio_file_copy_t *fc);
|
void rktio_copy_file_stop(rktio_t *rktio, rktio_file_copy_t *fc);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* System paths */
|
/* System paths */
|
||||||
|
@ -130,8 +143,17 @@ enum {
|
||||||
RKTIO_PATH_INIT_FILE
|
RKTIO_PATH_INIT_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
char *rktio_system_path(int which);
|
char *rktio_system_path(rktio_t *rktio, int which);
|
||||||
char *rktio_expand_user_tilde(char *filename);
|
char *rktio_expand_user_tilde(rktio_t *rktio, char *filename);
|
||||||
|
|
||||||
|
/*************************************************/
|
||||||
|
/* Sleep and signals */
|
||||||
|
|
||||||
|
typedef struct rktio_signal_handle_t rktio_signal_handle_t;
|
||||||
|
|
||||||
|
rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio);
|
||||||
|
void rktio_signal_received_at(rktio_signal_handle_t *h);
|
||||||
|
void rktio_signal_received(rktio_t *rktio);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* Errors */
|
/* Errors */
|
||||||
|
@ -155,13 +177,14 @@ enum {
|
||||||
RKTIO_ERROR_NOT_A_DIRECTORY,
|
RKTIO_ERROR_NOT_A_DIRECTORY,
|
||||||
RKTIO_ERROR_NO_TILDE,
|
RKTIO_ERROR_NO_TILDE,
|
||||||
RKTIO_ERROR_ILL_FORMED_USER,
|
RKTIO_ERROR_ILL_FORMED_USER,
|
||||||
RKTIO_ERROR_UNKNOWN_USER
|
RKTIO_ERROR_UNKNOWN_USER,
|
||||||
|
RKTIO_ERROR_INIT_FAILED
|
||||||
};
|
};
|
||||||
|
|
||||||
int rktio_get_last_error(void);
|
int rktio_get_last_error(rktio_t *rktio);
|
||||||
int rktio_get_last_error_kind(void);
|
int rktio_get_last_error_kind(rktio_t *rktio);
|
||||||
|
|
||||||
char *rktio_get_error_string(int kind, int errid);
|
char *rktio_get_error_string(rktio_t *rktio, int kind, int errid);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
|
|
||||||
|
|
|
@ -4,41 +4,43 @@
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
THREAD_LOCAL_DECL(static intptr_t errid);
|
void rktio_get_posix_error(rktio_t *rktio)
|
||||||
THREAD_LOCAL_DECL(static int errkind);
|
|
||||||
|
|
||||||
void rktio_get_posix_error(void)
|
|
||||||
{
|
{
|
||||||
errid = errno;
|
rktio->errid = errno;
|
||||||
errkind = RKTIO_ERROR_KIND_POSIX;
|
rktio->errkind = RKTIO_ERROR_KIND_POSIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rktio_set_racket_error(int new_errid)
|
void rktio_set_racket_error(rktio_t *rktio, int new_errid)
|
||||||
{
|
{
|
||||||
errid = new_errid;
|
rktio->errid = new_errid;
|
||||||
errkind = RKTIO_ERROR_KIND_RACKET;
|
rktio->errkind = RKTIO_ERROR_KIND_RACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
void rktio_get_windows_error(void)
|
void rktio_get_windows_error(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
errid = GetLastError();
|
rktio->errid = GetLastError();
|
||||||
errkind = RKTIO_ERROR_KIND_WINDOWS;
|
rktio->errkind = RKTIO_ERROR_KIND_WINDOWS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rktio_get_last_error(void)
|
int rktio_get_last_error(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
return errid;
|
return rktio->errid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_get_last_error_kind(void)
|
int rktio_get_last_error_kind(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
return errkind;
|
return rktio->errkind;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_get_error_string(int kind, int errid)
|
char *rktio_get_error_string(rktio_t *rktio, int kind, int errid)
|
||||||
{
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
if (kind == RKTIO_ERROR_KIND_POSIX)
|
||||||
|
s = strerror(errid);
|
||||||
|
if (s) return s;
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,6 @@
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
# define A_PATH_SEP '/'
|
# define A_PATH_SEP '/'
|
||||||
|
@ -43,12 +40,11 @@ static gid_t egid;
|
||||||
#define GROUP_MEMBER_CACHE_STATE_UNUSED 0
|
#define GROUP_MEMBER_CACHE_STATE_UNUSED 0
|
||||||
#define GROUP_MEMBER_CACHE_STATE_IN 1
|
#define GROUP_MEMBER_CACHE_STATE_IN 1
|
||||||
#define GROUP_MEMBER_CACHE_STATE_NOT_IN 2
|
#define GROUP_MEMBER_CACHE_STATE_NOT_IN 2
|
||||||
typedef struct {
|
typedef struct group_member_cache_entry_t {
|
||||||
int state;
|
int state;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
} group_member_cache_entry_t;
|
} group_member_cache_entry_t;
|
||||||
THREAD_LOCAL_DECL(static group_member_cache_entry_t *group_member_cache);
|
|
||||||
# define GROUP_CACHE_SIZE 10
|
# define GROUP_CACHE_SIZE 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -307,7 +303,7 @@ static char *UNC_readlink(const char *fn)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int UNC_stat(const char *dirname, int *flags, int *isdir, int *islink,
|
static int UNC_stat(rktio_t *rktio, const char *dirname, int *flags, int *isdir, int *islink,
|
||||||
rktio_timestamp_t **date, rktio_file_size_t *filesize,
|
rktio_timestamp_t **date, rktio_file_size_t *filesize,
|
||||||
const char **resolved_path, int set_flags)
|
const char **resolved_path, int set_flags)
|
||||||
/* dirname must be absolute */
|
/* dirname must be absolute */
|
||||||
|
@ -337,7 +333,7 @@ static int UNC_stat(const char *dirname, int *flags, int *isdir, int *islink,
|
||||||
copy = malloc(len+1);
|
copy = malloc(len+1);
|
||||||
memcpy(copy, dirname, len+1);
|
memcpy(copy, dirname, len+1);
|
||||||
|
|
||||||
if (!rktio_windows_nt_or_later()
|
if (!rktio->windows_nt_or_later
|
||||||
|| ((len >= 4)
|
|| ((len >= 4)
|
||||||
&& (copy[0] == '\\')
|
&& (copy[0] == '\\')
|
||||||
&& (copy[1] == '\\')
|
&& (copy[1] == '\\')
|
||||||
|
@ -478,7 +474,7 @@ static int UNC_stat(const char *dirname, int *flags, int *isdir, int *islink,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rktio_file_exists(char *filename)
|
int rktio_file_exists(rktio_t *rktio, char *filename)
|
||||||
/* Windows: check for special filenames before calling */
|
/* Windows: check for special filenames before calling */
|
||||||
{
|
{
|
||||||
# ifdef NO_STAT_PROC
|
# ifdef NO_STAT_PROC
|
||||||
|
@ -494,7 +490,7 @@ int rktio_file_exists(char *filename)
|
||||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
{
|
{
|
||||||
int isdir;
|
int isdir;
|
||||||
return (UNC_stat(filename, NULL, &isdir, NULL, NULL, NULL, NULL, -1)
|
return (UNC_stat(rktio, filename, NULL, &isdir, NULL, NULL, NULL, NULL, -1)
|
||||||
&& !isdir);
|
&& !isdir);
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
|
@ -510,7 +506,7 @@ int rktio_file_exists(char *filename)
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_directory_exists(char *dirname)
|
int rktio_directory_exists(rktio_t *rktio, char *dirname)
|
||||||
{
|
{
|
||||||
# ifdef NO_STAT_PROC
|
# ifdef NO_STAT_PROC
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -518,7 +514,7 @@ int rktio_directory_exists(char *dirname)
|
||||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int isdir;
|
int isdir;
|
||||||
|
|
||||||
return (UNC_stat(dirname, NULL, &isdir, NULL, NULL, NULL, NULL, -1)
|
return (UNC_stat(rktio, dirname, NULL, &isdir, NULL, NULL, NULL, NULL, -1)
|
||||||
&& isdir);
|
&& isdir);
|
||||||
# else
|
# else
|
||||||
struct MSC_IZE(stat) buf;
|
struct MSC_IZE(stat) buf;
|
||||||
|
@ -535,7 +531,7 @@ int rktio_directory_exists(char *dirname)
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_is_regular_file(char *filename)
|
int rktio_is_regular_file(rktio_t *rktio, char *filename)
|
||||||
/* Windows: check for special filenames before calling */
|
/* Windows: check for special filenames before calling */
|
||||||
{
|
{
|
||||||
# ifdef NO_STAT_PROC
|
# ifdef NO_STAT_PROC
|
||||||
|
@ -554,12 +550,12 @@ int rktio_is_regular_file(char *filename)
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_link_exists(char *filename)
|
int rktio_link_exists(rktio_t *rktio, char *filename)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
{
|
{
|
||||||
int islink;
|
int islink;
|
||||||
if (UNC_stat(filename, NULL, NULL, &islink, NULL, NULL, NULL, -1)
|
if (UNC_stat(rktio, filename, NULL, NULL, &islink, NULL, NULL, NULL, -1)
|
||||||
&& islink)
|
&& islink)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
|
@ -583,7 +579,7 @@ int rktio_link_exists(char *filename)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_get_current_directory()
|
char *rktio_get_current_directory(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int need_l, bl = 256;
|
int need_l, bl = 256;
|
||||||
|
@ -631,7 +627,7 @@ char *rktio_get_current_directory()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_set_current_directory(char *expanded)
|
int rktio_set_current_directory(rktio_t *rktio, char *expanded)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -646,8 +642,7 @@ int rktio_set_current_directory(char *expanded)
|
||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path)
|
static rktio_identity_t *get_identity(rktio_t *rktio, rktio_fd_t *fd, char *path, int follow_links)
|
||||||
/* If path is supplied, then fd is 0 for stat, 1 for lstat */
|
|
||||||
{
|
{
|
||||||
uintptr_t devi = 0, inoi = 0, inoi2 = 0;
|
uintptr_t devi = 0, inoi = 0, inoi2 = 0;
|
||||||
|
|
||||||
|
@ -656,11 +651,11 @@ rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path)
|
||||||
struct MSC_IZE(stat) buf;
|
struct MSC_IZE(stat) buf;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!path && !MSC_IZE(fstat)(fd, &buf))
|
if (!path && !MSC_IZE(fstat)(rktio_fd_system_fd(rktio, fd), &buf))
|
||||||
break;
|
break;
|
||||||
else if (path && !fd && !MSC_IZE(stat)(path, &buf))
|
else if (path && follow_links && !MSC_IZE(stat)(path, &buf))
|
||||||
break;
|
break;
|
||||||
else if (path && fd && !MSC_IZE(lstat)(path, &buf))
|
else if (path && !follow_links && !MSC_IZE(lstat)(path, &buf))
|
||||||
break;
|
break;
|
||||||
else if (errno != EINTR) {
|
else if (errno != EINTR) {
|
||||||
errid = errno;
|
errid = errno;
|
||||||
|
@ -679,7 +674,7 @@ rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path)
|
||||||
#endif
|
#endif
|
||||||
#ifdef WINDOWS_FILE_HANDLES
|
#ifdef WINDOWS_FILE_HANDLES
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
HANDLE fdh = (HANDLE)fd;
|
HANDLE fdh;
|
||||||
|
|
||||||
init_procs();
|
init_procs();
|
||||||
|
|
||||||
|
@ -698,7 +693,8 @@ rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path)
|
||||||
get_windows_error();
|
get_windows_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
fdh = (HANDLE)rktio_fd_system_fd(rktio, fd);
|
||||||
|
|
||||||
if (!GetFileInformationByHandle(fdh, &info)) {
|
if (!GetFileInformationByHandle(fdh, &info)) {
|
||||||
get_windows_error();
|
get_windows_error();
|
||||||
|
@ -726,16 +722,26 @@ rktio_identity_t *rktio_get_fd_identity(intptr_t fd, char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rktio_identity_t *rktio_fd_identity(rktio_t *rktio, rktio_fd_t *fd)
|
||||||
|
{
|
||||||
|
return get_identity(rktio, fd, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rktio_identity_t *rktio_path_identity(rktio_t *rktio, char *path, int follow_links)
|
||||||
|
{
|
||||||
|
return get_identity(rktio, NULL, path, follow_links);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
static int enable_write_permission(const char *fn)
|
static int enable_write_permission(const char *fn)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
return UNC_stat(fn, &flags, NULL, NULL, NULL, NULL, NULL, MZ_UNC_WRITE);
|
return UNC_stat(rktio, fn, &flags, NULL, NULL, NULL, NULL, NULL, MZ_UNC_WRITE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rktio_delete_file(char *fn, int enable_write_on_fail)
|
int rktio_delete_file(rktio_t *rktio, char *fn, int enable_write_on_fail)
|
||||||
{
|
{
|
||||||
int errid;
|
int errid;
|
||||||
|
|
||||||
|
@ -767,7 +773,7 @@ int rktio_delete_file(char *fn, int enable_write_on_fail)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_rename_file(char *dest, char *src, int exists_ok)
|
int rktio_rename_file(rktio_t *rktio, char *dest, char *src, int exists_ok)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int errid;
|
int errid;
|
||||||
|
@ -798,7 +804,7 @@ int rktio_rename_file(char *dest, char *src, int exists_ok)
|
||||||
free(src_w);
|
free(src_w);
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
if (!exists_ok && (rktio_file_exists(dest) || rktio_directory_exists(dest))) {
|
if (!exists_ok && (rktio_file_exists(rktio, dest) || rktio_directory_exists(rktio, dest))) {
|
||||||
/* We use a specialized error here, because it's not
|
/* We use a specialized error here, because it's not
|
||||||
a system error (e.g., setting `errval` to `EEXIST` would
|
a system error (e.g., setting `errval` to `EEXIST` would
|
||||||
be a lie). */
|
be a lie). */
|
||||||
|
@ -818,10 +824,10 @@ int rktio_rename_file(char *dest, char *src, int exists_ok)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_readlink(char *fullfilename)
|
char *rktio_readlink(rktio_t *rktio, char *fullfilename)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
if (UNC_stat(fullfilename, NULL, NULL, &is_link, NULL, NULL, NULL, -1)
|
if (UNC_stat(rktio, fullfilename, NULL, NULL, &is_link, NULL, NULL, NULL, -1)
|
||||||
&& is_link) {
|
&& is_link) {
|
||||||
return UNC_readlink(fullfilename);
|
return UNC_readlink(fullfilename);
|
||||||
} else {
|
} else {
|
||||||
|
@ -852,7 +858,7 @@ char *rktio_readlink(char *fullfilename)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_make_directory(char *filename)
|
int rktio_make_directory(rktio_t *rktio, char *filename)
|
||||||
{
|
{
|
||||||
#ifdef NO_MKDIR
|
#ifdef NO_MKDIR
|
||||||
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
||||||
|
@ -893,7 +899,7 @@ int rktio_make_directory(char *filename)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_delete_directory(char *filename, char *current_directory, int enable_write_on_fail)
|
int rktio_delete_directory(rktio_t *rktio, char *filename, char *current_directory, int enable_write_on_fail)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int tried_cwd = 0, tried_perm = 0;
|
int tried_cwd = 0, tried_perm = 0;
|
||||||
|
@ -922,7 +928,7 @@ int rktio_delete_directory(char *filename, char *current_directory, int enable_w
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_make_link(char *src, char *dest, int dest_is_directory)
|
int rktio_make_link(rktio_t *rktio, char *src, char *dest, int dest_is_directory)
|
||||||
/* `src` is the file that is written, and `dest` is written to that
|
/* `src` is the file that is written, and `dest` is written to that
|
||||||
file */
|
file */
|
||||||
{
|
{
|
||||||
|
@ -960,12 +966,12 @@ int rktio_make_link(char *src, char *dest, int dest_is_directory)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
rktio_timestamp_t *rktio_get_file_modify_seconds(char *file)
|
rktio_timestamp_t *rktio_get_file_modify_seconds(rktio_t *rktio, char *file)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
rktio_timestamp_t *secs;
|
rktio_timestamp_t *secs;
|
||||||
|
|
||||||
if (UNC_stat(file, NULL, NULL, NULL, &secs, NULL, NULL, -1))
|
if (UNC_stat(rktio, file, NULL, NULL, NULL, &secs, NULL, NULL, -1))
|
||||||
return secs;
|
return secs;
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
|
@ -986,7 +992,7 @@ rktio_timestamp_t *rktio_get_file_modify_seconds(char *file)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_set_file_modify_seconds(char *file, rktio_timestamp_t secs)
|
int rktio_set_file_modify_seconds(rktio_t *rktio, char *file, rktio_timestamp_t secs)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
struct MSC_IZE(utimbuf) ut;
|
struct MSC_IZE(utimbuf) ut;
|
||||||
|
@ -1003,20 +1009,20 @@ int rktio_set_file_modify_seconds(char *file, rktio_timestamp_t secs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(NO_UNIX_USERS)
|
#if defined(RKTIO_SYSTEM_UNIX) && !defined(NO_UNIX_USERS)
|
||||||
static int user_in_group(uid_t uid, gid_t gid)
|
static int user_in_group(rktio_t *rktio, uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
struct group *g;
|
struct group *g;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
int i, in;
|
int i, in;
|
||||||
|
|
||||||
if (!group_member_cache)
|
if (!rktio->group_member_cache)
|
||||||
group_member_cache = calloc(GROUP_CACHE_SIZE, sizeof(group_member_cache_entry_t));
|
rktio->group_member_cache = calloc(GROUP_CACHE_SIZE, sizeof(group_member_cache_entry_t));
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CACHE_SIZE; i++) {
|
for (i = 0; i < GROUP_CACHE_SIZE; i++) {
|
||||||
if ((group_member_cache[i].state != GROUP_MEMBER_CACHE_STATE_UNUSED)
|
if ((rktio->group_member_cache[i].state != GROUP_MEMBER_CACHE_STATE_UNUSED)
|
||||||
&& (group_member_cache[i].gid == gid)
|
&& (rktio->group_member_cache[i].gid == gid)
|
||||||
&& (group_member_cache[i].uid == uid))
|
&& (rktio->group_member_cache[i].uid == uid))
|
||||||
return (group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_IN);
|
return (rktio->group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
pw = getpwuid(uid);
|
pw = getpwuid(uid);
|
||||||
|
@ -1035,10 +1041,10 @@ static int user_in_group(uid_t uid, gid_t gid)
|
||||||
in = !!(g->gr_mem[i]);
|
in = !!(g->gr_mem[i]);
|
||||||
|
|
||||||
for (i = 0; i < GROUP_CACHE_SIZE; i++) {
|
for (i = 0; i < GROUP_CACHE_SIZE; i++) {
|
||||||
if (group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_UNUSED) {
|
if (rktio->group_member_cache[i].state == GROUP_MEMBER_CACHE_STATE_UNUSED) {
|
||||||
group_member_cache[i].gid = gid;
|
rktio->group_member_cache[i].gid = gid;
|
||||||
group_member_cache[i].uid = uid;
|
rktio->group_member_cache[i].uid = uid;
|
||||||
group_member_cache[i].state = (in
|
rktio->group_member_cache[i].state = (in
|
||||||
? GROUP_MEMBER_CACHE_STATE_IN
|
? GROUP_MEMBER_CACHE_STATE_IN
|
||||||
: GROUP_MEMBER_CACHE_STATE_NOT_IN);
|
: GROUP_MEMBER_CACHE_STATE_NOT_IN);
|
||||||
break;
|
break;
|
||||||
|
@ -1049,7 +1055,7 @@ static int user_in_group(uid_t uid, gid_t gid)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rktio_get_file_or_directory_permissions(char *filename, int all_bits)
|
int rktio_get_file_or_directory_permissions(rktio_t *rktio, char *filename, int all_bits)
|
||||||
/* -1 result indicates an error */
|
/* -1 result indicates an error */
|
||||||
{
|
{
|
||||||
# ifdef NO_STAT_PROC
|
# ifdef NO_STAT_PROC
|
||||||
|
@ -1117,13 +1123,13 @@ int rktio_get_file_or_directory_permissions(char *filename, int all_bits)
|
||||||
{
|
{
|
||||||
/* Use stat, because setuid, or because or no user info available */
|
/* Use stat, because setuid, or because or no user info available */
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
int ok, read, write, execute;
|
int cr, read, write, execute;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ok = stat(filename, &buf);
|
cr = stat(filename, &buf);
|
||||||
} while ((ok == -1) && (errno == EINTR));
|
} while ((cr == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ok) {
|
if (cr) {
|
||||||
get_posix_error();
|
get_posix_error();
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1145,7 +1151,7 @@ int rktio_get_file_or_directory_permissions(char *filename, int all_bits)
|
||||||
read = !!(buf.st_mode & S_IRUSR);
|
read = !!(buf.st_mode & S_IRUSR);
|
||||||
write = !!(buf.st_mode & S_IWUSR);
|
write = !!(buf.st_mode & S_IWUSR);
|
||||||
execute = !!(buf.st_mode & S_IXUSR);
|
execute = !!(buf.st_mode & S_IXUSR);
|
||||||
} else if ((egid == buf.st_gid) || user_in_group(euid, buf.st_gid)) {
|
} else if ((egid == buf.st_gid) || user_in_group(rktio, euid, buf.st_gid)) {
|
||||||
read = !!(buf.st_mode & S_IRGRP);
|
read = !!(buf.st_mode & S_IRGRP);
|
||||||
write = !!(buf.st_mode & S_IWGRP);
|
write = !!(buf.st_mode & S_IWGRP);
|
||||||
execute = !!(buf.st_mode & S_IXGRP);
|
execute = !!(buf.st_mode & S_IXGRP);
|
||||||
|
@ -1171,7 +1177,7 @@ int rktio_get_file_or_directory_permissions(char *filename, int all_bits)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
if (UNC_stat(filename, &flags, NULL, NULL, NULL, NULL, NULL, -1)) {
|
if (UNC_stat(rktio, filename, &flags, NULL, NULL, NULL, NULL, NULL, -1)) {
|
||||||
if (as_bits)
|
if (as_bits)
|
||||||
return (flags | (flags << 3) | (flags << 6));
|
return (flags | (flags << 3) | (flags << 6));
|
||||||
else {
|
else {
|
||||||
|
@ -1187,7 +1193,7 @@ int rktio_get_file_or_directory_permissions(char *filename, int all_bits)
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_set_file_or_directory_permissions(char *filename, int new_bits)
|
int rktio_set_file_or_directory_permissions(rktio_t *rktio, char *filename, int new_bits)
|
||||||
{
|
{
|
||||||
# ifdef NO_STAT_PROC
|
# ifdef NO_STAT_PROC
|
||||||
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
||||||
|
@ -1221,7 +1227,7 @@ int rktio_set_file_or_directory_permissions(char *filename, int new_bits)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNC_stat(filename, NULL, NULL, NULL, NULL, NULL, NULL, new_bits))
|
if (UNC_stat(rktio, filename, NULL, NULL, NULL, NULL, NULL, NULL, new_bits))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1230,12 +1236,12 @@ int rktio_set_file_or_directory_permissions(char *filename, int new_bits)
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
rktio_size_t *rktio_file_size(char *filename)
|
rktio_size_t *rktio_file_size(rktio_t *rktio, char *filename)
|
||||||
{
|
{
|
||||||
rktio_size_t *sz = NULL;
|
rktio_size_t *sz = NULL;
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
{
|
{
|
||||||
if (UNC_stat(filename, NULL, NULL, NULL, NULL, &sz, NULL, -1)) {
|
if (UNC_stat(rktio, filename, NULL, NULL, NULL, NULL, &sz, NULL, -1)) {
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1281,7 +1287,7 @@ struct rktio_directory_list_t {
|
||||||
FF_TYPE info;
|
FF_TYPE info;
|
||||||
};
|
};
|
||||||
|
|
||||||
rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive)
|
||||||
/* path must be normalized */
|
/* path must be normalized */
|
||||||
{
|
{
|
||||||
char *pattern;
|
char *pattern;
|
||||||
|
@ -1340,7 +1346,7 @@ rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
||||||
if ((err_val == ERROR_DIRECTORY) && CreateSymbolicLinkProc) {
|
if ((err_val == ERROR_DIRECTORY) && CreateSymbolicLinkProc) {
|
||||||
/* check for symbolic link */
|
/* check for symbolic link */
|
||||||
const char *resolved;
|
const char *resolved;
|
||||||
if (UNC_stat(filename, NULL, NULL, NULL, NULL, NULL, &resolved, -1)) {
|
if (UNC_stat(rktio, filename, NULL, NULL, NULL, NULL, NULL, &resolved, -1)) {
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
filename = (char *)resolved;
|
filename = (char *)resolved;
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -1358,7 +1364,7 @@ rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
||||||
return dl;
|
return dl;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_directory_list_step(rktio_directory_list_t *dl)
|
char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl)
|
||||||
/* empty-strng result (don't deallocate) means done */
|
/* empty-strng result (don't deallocate) means done */
|
||||||
{
|
{
|
||||||
while (dl->first_ready || FIND_NEXT(dl->hfile, &dl->info)) {
|
while (dl->first_ready || FIND_NEXT(dl->hfile, &dl->info)) {
|
||||||
|
@ -1385,7 +1391,7 @@ struct rktio_directory_list_t {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive)
|
||||||
{
|
{
|
||||||
rktio_directory_list_t *dl;
|
rktio_directory_list_t *dl;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
@ -1403,7 +1409,7 @@ rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
||||||
return dl;
|
return dl;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_directory_list_step(rktio_directory_list_t *dl)
|
char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl)
|
||||||
/* empty-strng result (don't deallocate) means done */
|
/* empty-strng result (don't deallocate) means done */
|
||||||
{
|
{
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
|
@ -1437,13 +1443,13 @@ char *rktio_directory_list_step(rktio_directory_list_t *dl)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
rktio_directory_list_t *rktio_directory_list_start(char *filename, int is_drive)
|
rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive)
|
||||||
{
|
{
|
||||||
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_directory_list_step(rktio_directory_list_t *dl)
|
char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl)
|
||||||
{
|
{
|
||||||
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1460,7 +1466,7 @@ struct rktio_file_copy_t {
|
||||||
rktio_fd_t *src_fd, *dest_fd;
|
rktio_fd_t *src_fd, *dest_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok)
|
rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, char *dest, char *src, int exists_ok)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
{
|
{
|
||||||
|
@ -1469,12 +1475,12 @@ rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
rktio_fd_t *src_fd, *dest_fd;
|
rktio_fd_t *src_fd, *dest_fd;
|
||||||
|
|
||||||
src_fd = rktio_open(src, RKTIO_OPEN_READ);
|
src_fd = rktio_open(rktio, src, RKTIO_OPEN_READ);
|
||||||
if (!src_fd)
|
if (!src_fd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ok = fstat(rktio_fd_system_fd(src_fd), &buf);
|
ok = fstat(rktio_fd_system_fd(rktio, src_fd), &buf);
|
||||||
} while ((ok == -1) && (errno == EINTR));
|
} while ((ok == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ok || S_ISDIR(buf.st_mode)) {
|
if (ok || S_ISDIR(buf.st_mode)) {
|
||||||
|
@ -1482,14 +1488,14 @@ rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok)
|
||||||
get_posix_error();
|
get_posix_error();
|
||||||
else
|
else
|
||||||
set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY);
|
set_racket_error(RKTIO_ERROR_IS_A_DIRECTORY);
|
||||||
rktio_close(src_fd);
|
rktio_close(rktio, src_fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest_fd = rktio_open(dest, (RKTIO_OPEN_WRITE
|
dest_fd = rktio_open(rktio, dest, (RKTIO_OPEN_WRITE
|
||||||
| (exists_ok ? RKTIO_OPEN_TRUNCATE : 0)));
|
| (exists_ok ? RKTIO_OPEN_TRUNCATE : 0)));
|
||||||
if (!dest_fd) {
|
if (!dest_fd) {
|
||||||
rktio_close(src_fd);
|
rktio_close(rktio, src_fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1532,12 +1538,12 @@ rktio_file_copy_t *rktio_copy_file_start(char *dest, char *src, int exists_ok)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_copy_file_is_done(rktio_file_copy_t *fc)
|
int rktio_copy_file_is_done(rktio_t *rktio, rktio_file_copy_t *fc)
|
||||||
{
|
{
|
||||||
return fc->done;
|
return fc->done;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_copy_file_step(rktio_file_copy_t *fc)
|
int rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
|
@ -1546,7 +1552,7 @@ int rktio_copy_file_step(rktio_file_copy_t *fc)
|
||||||
if (fc->done)
|
if (fc->done)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
len = rktio_read(fc->src_fd, buffer, sizeof(buffer));
|
len = rktio_read(rktio, fc->src_fd, buffer, sizeof(buffer));
|
||||||
if (len == RKTIO_READ_EOF) {
|
if (len == RKTIO_READ_EOF) {
|
||||||
fc->done = 1;
|
fc->done = 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1556,7 +1562,7 @@ int rktio_copy_file_step(rktio_file_copy_t *fc)
|
||||||
intptr_t done = 0, amt;
|
intptr_t done = 0, amt;
|
||||||
|
|
||||||
while (done < len) {
|
while (done < len) {
|
||||||
amt = rktio_write(fc->dest_fd, buffer + done, len - done);
|
amt = rktio_write(rktio, fc->dest_fd, buffer + done, len - done);
|
||||||
if (amt < 0)
|
if (amt < 0)
|
||||||
return 0;
|
return 0;
|
||||||
done += amt;
|
done += amt;
|
||||||
|
@ -1569,11 +1575,11 @@ int rktio_copy_file_step(rktio_file_copy_t *fc)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void rktio_copy_file_stop(rktio_file_copy_t *fc)
|
void rktio_copy_file_stop(rktio_t *rktio, rktio_file_copy_t *fc)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
rktio_close(fc->src_fd);
|
rktio_close(rktio, fc->src_fd);
|
||||||
rktio_close(fc->dest_fd);
|
rktio_close(rktio, fc->dest_fd);
|
||||||
#endif
|
#endif
|
||||||
free(fc);
|
free(fc);
|
||||||
}
|
}
|
||||||
|
@ -1582,7 +1588,7 @@ void rktio_copy_file_stop(rktio_file_copy_t *fc)
|
||||||
/* filesystem root list */
|
/* filesystem root list */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
char **rktio_filesystem_root_list(void)
|
char **rktio_filesystem_root_list(rktio_t *rktio)
|
||||||
/* returns a NULL-terminated array of strings */
|
/* returns a NULL-terminated array of strings */
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
@ -1645,7 +1651,7 @@ char **rktio_filesystem_root_list(void)
|
||||||
/* expand user tilde & system paths */
|
/* expand user tilde & system paths */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
char *rktio_expand_user_tilde(char *filename) {
|
char *rktio_expand_user_tilde(rktio_t *rktio, char *filename) {
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1737,7 +1743,7 @@ static char *append_paths(char *a, char *b, int free_a, int free_b)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rktio_system_path(int which)
|
char *rktio_system_path(rktio_t *rktio, int which)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
if (which == RKTIO_PATH_SYS_DIR) {
|
if (which == RKTIO_PATH_SYS_DIR) {
|
||||||
|
@ -1748,20 +1754,20 @@ char *rktio_system_path(int which)
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if ((p = getenv("TMPDIR"))) {
|
if ((p = getenv("TMPDIR"))) {
|
||||||
if (rktio_directory_exists(p))
|
if (rktio_directory_exists(rktio, p))
|
||||||
return strdup(p);
|
return strdup(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rktio_directory_exists("/var/tmp"))
|
if (rktio_directory_exists(rktio, "/var/tmp"))
|
||||||
return strdup("/var/tmp");
|
return strdup("/var/tmp");
|
||||||
|
|
||||||
if (rktio_directory_exists("/usr/tmp"))
|
if (rktio_directory_exists(rktio, "/usr/tmp"))
|
||||||
return strdup("/usr/tmp");
|
return strdup("/usr/tmp");
|
||||||
|
|
||||||
if (rktio_directory_exists("/tmp"))
|
if (rktio_directory_exists(rktio, "/tmp"))
|
||||||
return strdup("/tmp");
|
return strdup("/tmp");
|
||||||
|
|
||||||
return rktio_get_current_directory();
|
return rktio_get_current_directory(rktio);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1797,7 +1803,7 @@ char *rktio_system_path(int which)
|
||||||
if (alt_home)
|
if (alt_home)
|
||||||
home = append_paths(alt_home, home_str + 2, 0, 0);
|
home = append_paths(alt_home, home_str + 2, 0, 0);
|
||||||
else {
|
else {
|
||||||
home = rktio_expand_user_tilde(home_str);
|
home = rktio_expand_user_tilde(rktio, home_str);
|
||||||
|
|
||||||
if (!home) {
|
if (!home) {
|
||||||
/* Something went wrong with the user lookup. Just drop "~'. */
|
/* Something went wrong with the user lookup. Just drop "~'. */
|
||||||
|
|
33
racket/src/rktio/rktio_main.c
Normal file
33
racket/src/rktio/rktio_main.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include "rktio.h"
|
||||||
|
#include "rktio_private.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
rktio_t *rktio_init(void)
|
||||||
|
{
|
||||||
|
rktio_t *rktio;
|
||||||
|
|
||||||
|
rktio = malloc(sizeof(rktio_t));
|
||||||
|
memset(rktio, 0, sizeof(rktio_t));
|
||||||
|
|
||||||
|
rktio_alloc_global_poll_set(rktio);
|
||||||
|
if (!rktio_initialize_signal(rktio)) {
|
||||||
|
rktio_destroy(rktio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rktio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rktio_destroy(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
free(rktio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Useful on Windows to make sure everyone is using the same malloc()
|
||||||
|
and fre(): */
|
||||||
|
void rktio_free(void *p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
# include <sys/select.h>
|
# include <sys/select.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
# include <fcntl.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <math.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
@ -13,13 +16,9 @@
|
||||||
special hooks for Windows "descriptors" like even queues and
|
special hooks for Windows "descriptors" like even queues and
|
||||||
semaphores, etc. */
|
semaphores, etc. */
|
||||||
|
|
||||||
|
void rktio_alloc_global_poll_set(rktio_t *rktio) {
|
||||||
#ifdef USE_FAR_RKTIO_FDCALLS
|
#ifdef USE_FAR_RKTIO_FDCALLS
|
||||||
THREAD_LOCAL_DECL(rktio_poll_set_t *rktio_global_poll_set);
|
rktio->rktio_global_poll_set = rktio_alloc_fdset_array(3);
|
||||||
#endif
|
|
||||||
|
|
||||||
void rktio_alloc_global_poll_set() {
|
|
||||||
#ifdef USE_FAR_RKTIO_FDCALLS
|
|
||||||
rktio_global_poll_set = rktio_alloc_fdset_array(3);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,3 +776,362 @@ int rktio_get_fd_limit(rktio_poll_set_t *fds)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Sleeping as a generalized select() */
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
int rktio_initialize_signal(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
/* Set up a pipe for signaling external events: */
|
||||||
|
int fds[2];
|
||||||
|
if (!pipe(fds)) {
|
||||||
|
rktio->external_event_fd = fds[0];
|
||||||
|
rktio->put_external_event_fd = fds[1];
|
||||||
|
fcntl(rktio->external_event_fd, F_SETFL, RKTIO_NONBLOCKING);
|
||||||
|
fcntl(rktio->put_external_event_fd, F_SETFL, RKTIO_NONBLOCKING);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
set_racket_error(RKTIO_ERROR_INIT_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32_FD_HANDLES
|
||||||
|
break_semaphore = (void*)CreateSemaphore(NULL, 0, 1, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
return (rktio_signal_handle_t *)&rktio->put_external_event_fd;
|
||||||
|
#endif
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
return (rktio_signal_handle_t *)rktio->break_semaphore;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void rktio_signal_received(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
rktio_signal_received_at(rktio_get_signal_handle(rktio));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rktio_signal_received_at(rktio_signal_handle_t *h)
|
||||||
|
{
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
int put_ext_event_fd = *(int *)h;
|
||||||
|
int saved_errno = errno;
|
||||||
|
if (put_ext_event_fd) {
|
||||||
|
int v;
|
||||||
|
do {
|
||||||
|
v = write(put_ext_event_fd, "!", 1);
|
||||||
|
} while ((v == -1) && (errno == EINTR));
|
||||||
|
}
|
||||||
|
errno = saved_errno;
|
||||||
|
#endif
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
ReleaseSemaphore(*(HANDLE *)h, 1, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_signal(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
/* Clear external event flag */
|
||||||
|
if (rktio->external_event_fd) {
|
||||||
|
int rc;
|
||||||
|
char buf[10];
|
||||||
|
do {
|
||||||
|
rc = read(rktio->external_event_fd, buf, 10);
|
||||||
|
} while ((rc == -1) && errno == EINTR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void rktio_wait_until_signal_received(rktio_t *rktio)
|
||||||
|
{
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
int r;
|
||||||
|
# ifdef HAVE_POLL_SYSCALL
|
||||||
|
GC_CAN_IGNORE struct pollfd pfd[1];
|
||||||
|
pfd[0].fd = rktio->external_event_fd;
|
||||||
|
pfd[0].events = POLLIN;
|
||||||
|
do {
|
||||||
|
r = poll(pfd, 1, -1);
|
||||||
|
} while ((r == -1) && (errno == EINTR));
|
||||||
|
# else
|
||||||
|
DECL_FDSET(readfds, 1);
|
||||||
|
|
||||||
|
INIT_DECL_RD_FDSET(readfds);
|
||||||
|
|
||||||
|
RKTIO_FD_ZERO(readfds);
|
||||||
|
RKTIO_FD_SET(rktio->external_event_fd, readfds);
|
||||||
|
|
||||||
|
do {
|
||||||
|
r = select(rktio->external_event_fd + 1, RKTIO_FDS(readfds), NULL, NULL, NULL);
|
||||||
|
} while ((r == -1) && (errno == EINTR));
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
WaitForSingleObject(rktio->break_semaphore, INFINITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
clear_signal(rktio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************** Windows cleanup *****************/
|
||||||
|
|
||||||
|
#if RKTIO_SYSTEM_WINDOWS
|
||||||
|
|
||||||
|
static void clean_up_wait(intptr_t result, OS_SEMAPHORE_TYPE *array,
|
||||||
|
int *rps, int count)
|
||||||
|
{
|
||||||
|
if ((result >= (intptr_t)WAIT_OBJECT_0) && (result < (intptr_t)WAIT_OBJECT_0 + count)) {
|
||||||
|
result -= WAIT_OBJECT_0;
|
||||||
|
if (rps[result])
|
||||||
|
ReleaseSemaphore(array[result], 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear out break semaphore */
|
||||||
|
WaitForSingleObject((HANDLE)scheme_break_semaphore, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int made_progress;
|
||||||
|
static DWORD max_sleep_time;
|
||||||
|
|
||||||
|
void rkio_notify_sleep_progress(void)
|
||||||
|
{
|
||||||
|
made_progress = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void rkio_notify_sleep_progress(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************** Main sleep function *****************/
|
||||||
|
/* The simple select() stuff is buried in various kinds of complexity. */
|
||||||
|
|
||||||
|
/* FIXME: don't forget SIGCHILD_DOESNT_INTERRUPT_SELECT handling in Racket */
|
||||||
|
|
||||||
|
void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds)
|
||||||
|
{
|
||||||
|
if (!fds) {
|
||||||
|
/* Nothing to block on - just sleep for some amount of time. */
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
# ifdef HAVE_POLL_SYSCALL
|
||||||
|
int timeout;
|
||||||
|
if (nsecs <= 0.0)
|
||||||
|
timeout = -1;
|
||||||
|
else {
|
||||||
|
timeout = (int)(nsecs * 1000.0);
|
||||||
|
if (timeout < 0)
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
if (external_event_fd) {
|
||||||
|
GC_CAN_IGNORE struct pollfd pfd[1];
|
||||||
|
pfd[0].fd = external_event_fd;
|
||||||
|
pfd[0].events = POLLIN;
|
||||||
|
poll(pfd, 1, timeout);
|
||||||
|
} else {
|
||||||
|
poll(NULL, 0, timeout);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
/* Sleep by selecting on the external event fd */
|
||||||
|
struct timeval time;
|
||||||
|
intptr_t secs = (intptr_t)nsecs;
|
||||||
|
intptr_t usecs = (intptr_t)(fmod(nsecs, 1.0) * 1000000);
|
||||||
|
|
||||||
|
if (nsecs && (nsecs > 100000))
|
||||||
|
secs = 100000;
|
||||||
|
if (usecs < 0)
|
||||||
|
usecs = 0;
|
||||||
|
if (usecs >= 1000000)
|
||||||
|
usecs = 999999;
|
||||||
|
|
||||||
|
time.tv_sec = secs;
|
||||||
|
time.tv_usec = usecs;
|
||||||
|
|
||||||
|
if (rktio->external_event_fd) {
|
||||||
|
DECL_FDSET(readfds, 1);
|
||||||
|
|
||||||
|
INIT_DECL_RD_FDSET(readfds);
|
||||||
|
|
||||||
|
RKTIO_FD_ZERO(readfds);
|
||||||
|
RKTIO_FD_SET(rktio->external_event_fd, readfds);
|
||||||
|
|
||||||
|
select(rktio->external_event_fd + 1, RKTIO_FDS(readfds), NULL, NULL, &time);
|
||||||
|
} else {
|
||||||
|
select(0, NULL, NULL, NULL, &time);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifndef NO_SLEEP
|
||||||
|
# ifndef NO_USLEEP
|
||||||
|
usleep((unsigned)(nsecs * 1000));
|
||||||
|
# else
|
||||||
|
sleep(nsecs);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
/* Something to block on.... */
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_SYSCALL
|
||||||
|
|
||||||
|
/******* poll() variant *******/
|
||||||
|
|
||||||
|
{
|
||||||
|
struct mz_fd_set_data_t *data = fds->data;
|
||||||
|
intptr_t count = data->count;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
if (v <= 0.0)
|
||||||
|
timeout = -1;
|
||||||
|
else if (v > 100000)
|
||||||
|
timeout = 100000000;
|
||||||
|
else {
|
||||||
|
timeout = (int)(v * 1000.0);
|
||||||
|
if (timeout < 0)
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (external_event_fd) {
|
||||||
|
data->pfd[count].fd = external_event_fd;
|
||||||
|
data->pfd[count].events = POLLIN;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
poll(data->pfd, count, timeout);
|
||||||
|
}
|
||||||
|
#elif !defined(RKTIO_SYSTEM_WINDOWS)
|
||||||
|
|
||||||
|
/******* select() variant *******/
|
||||||
|
|
||||||
|
{
|
||||||
|
int actual_limit;
|
||||||
|
fd_set *rd, *wr, *ex;
|
||||||
|
struct timeval time;
|
||||||
|
intptr_t secs = (intptr_t)nsecs;
|
||||||
|
intptr_t usecs = (intptr_t)(fmod(nsecs, 1.0) * 1000000);
|
||||||
|
|
||||||
|
if (nsecs && (nsecs > 100000))
|
||||||
|
secs = 100000;
|
||||||
|
if (usecs < 0)
|
||||||
|
usecs = 0;
|
||||||
|
if (usecs >= 1000000)
|
||||||
|
usecs = 999999;
|
||||||
|
|
||||||
|
time.tv_sec = secs;
|
||||||
|
time.tv_usec = usecs;
|
||||||
|
|
||||||
|
rd = RKTIO_FDS(fds);
|
||||||
|
wr = RKTIO_FDS(RKTIO_GET_FDSET(fds, 1));
|
||||||
|
ex = RKTIO_FDS(RKTIO_GET_FDSET(fds, 2));
|
||||||
|
|
||||||
|
actual_limit = rktio_get_fd_limit(fds);
|
||||||
|
|
||||||
|
/* Watch for external events, too: */
|
||||||
|
if (rktio->external_event_fd) {
|
||||||
|
FD_SET(rktio->external_event_fd, rd);
|
||||||
|
if (rktio->external_event_fd >= actual_limit)
|
||||||
|
actual_limit = rktio->external_event_fd + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
select(actual_limit, rd, wr, ex, nsecs ? &time : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/******* Windows variant *******/
|
||||||
|
|
||||||
|
{
|
||||||
|
intptr_t result;
|
||||||
|
HANDLE *array, just_two_array[2], break_sema;
|
||||||
|
int count, rcount, *rps;
|
||||||
|
|
||||||
|
if (fds->no_sleep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scheme_collapse_win_fd(fds); /* merges */
|
||||||
|
|
||||||
|
rcount = fds->num_handles;
|
||||||
|
count = fds->combined_len;
|
||||||
|
array = fds->combined_wait_array;
|
||||||
|
rps = fds->repost_sema;
|
||||||
|
|
||||||
|
/* add break semaphore: */
|
||||||
|
if (!count)
|
||||||
|
array = just_two_array;
|
||||||
|
break_sema = (HANDLE)scheme_break_semaphore;
|
||||||
|
array[count++] = break_sema;
|
||||||
|
|
||||||
|
/* Extensions may handle events.
|
||||||
|
If the event queue is empty (as reported by GetQueueStatus),
|
||||||
|
everything's ok.
|
||||||
|
|
||||||
|
Otherwise, we have trouble sleeping until an event is ready. We
|
||||||
|
sometimes leave events on th queue because, say, an eventspace is
|
||||||
|
not ready. The problem is that MsgWait... only unblocks when a new
|
||||||
|
event appears. Since extensions may check the queue using a sequence of
|
||||||
|
PeekMessages, it's possible that an event is added during the
|
||||||
|
middle of the sequence, but doesn't get handled.
|
||||||
|
|
||||||
|
To avoid this problem, we don't actually sleep indefinitely if an event
|
||||||
|
is pending. Instead, we slep 10 ms, then 20 ms, etc. This exponential
|
||||||
|
backoff ensures that we eventually handle a pending event, but we don't
|
||||||
|
spin and eat CPU cycles. The back-off is reset whenever a thread makes
|
||||||
|
progress. */
|
||||||
|
|
||||||
|
if (SCHEME_INT_VAL(((win_extended_fd_set *)fds)->wait_event_mask)
|
||||||
|
&& GetQueueStatus(SCHEME_INT_VAL(((win_extended_fd_set *)fds)->wait_event_mask))) {
|
||||||
|
if (!made_progress) {
|
||||||
|
/* Ok, we've gone around at least once. */
|
||||||
|
if (max_sleep_time < 0x20000000)
|
||||||
|
max_sleep_time *= 2;
|
||||||
|
} else {
|
||||||
|
/* Starting back-off mode */
|
||||||
|
made_progress = 0;
|
||||||
|
max_sleep_time = 5;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Disable back-off mode */
|
||||||
|
made_progress = 1;
|
||||||
|
max_sleep_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for HANDLE-based input: */
|
||||||
|
{
|
||||||
|
DWORD msec;
|
||||||
|
if (nsecs) {
|
||||||
|
if (nsecs > 100000)
|
||||||
|
msec = 100000000;
|
||||||
|
else
|
||||||
|
msec = (DWORD)(nsecs * 1000);
|
||||||
|
if (max_sleep_time && (msec > max_sleep_time))
|
||||||
|
msec = max_sleep_time;
|
||||||
|
} else {
|
||||||
|
if (max_sleep_time)
|
||||||
|
msec = max_sleep_time;
|
||||||
|
else
|
||||||
|
msec = INFINITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = MsgWaitForMultipleObjects(count, array, FALSE, msec,
|
||||||
|
SCHEME_INT_VAL(((win_extended_fd_set *)fds)->wait_event_mask));
|
||||||
|
}
|
||||||
|
clean_up_wait(result, array, rps, rcount);
|
||||||
|
scheme_collapse_win_fd(fds); /* cleans up */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_signal(rktio);
|
||||||
|
}
|
||||||
|
|
|
@ -1,33 +1,15 @@
|
||||||
#if ((defined(_MSC_VER) || defined(__MINGW32__)) \
|
#if ((defined(_MSC_VER) || defined(__MINGW32__)) \
|
||||||
&& (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)))
|
&& (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)))
|
||||||
# define RKTIO_SYSTEM_WINDOWS
|
# define RKTIO_SYSTEM_WINDOWS
|
||||||
# define MSC_IZE(n) _ ## n
|
|
||||||
# define MSC_W_IZE(n) _w ## n
|
|
||||||
# define MSC_WIDE_PATH_temp(n) WIDE_PATH_temp(n)
|
|
||||||
#else
|
#else
|
||||||
# define RKTIO_SYSTEM_UNIX
|
# define RKTIO_SYSTEM_UNIX
|
||||||
# define MSC_IZE(n) n
|
|
||||||
# define MSC_W_IZE(n) MSC_IZE(n)
|
|
||||||
# define MSC_WIDE_PATH_temp(n) n
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THREAD_LOCAL_DECL(decl) decl
|
|
||||||
|
|
||||||
void rktio_get_posix_error(void);
|
|
||||||
#define get_posix_error() rktio_get_posix_error()
|
|
||||||
|
|
||||||
void rktio_set_racket_error(int errid);
|
|
||||||
#define set_racket_error(e) rktio_set_racket_error(e)
|
|
||||||
|
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
void rktio_get_windows_error(void);
|
# include <windows.h>
|
||||||
# define get_windows_error() rktio_get_windows_error()
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************/
|
|
||||||
|
|
||||||
typedef struct rktio_poll_set_t rktio_poll_set_t;
|
|
||||||
|
|
||||||
#if RKTIO_SYSTEM_WINDOWS
|
#if RKTIO_SYSTEM_WINDOWS
|
||||||
# define USE_FAR_RKTIO_FDCALLS
|
# define USE_FAR_RKTIO_FDCALLS
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,19 +20,47 @@ typedef struct rktio_poll_set_t rktio_poll_set_t;
|
||||||
# define USE_FAR_RKTIO_FDCALLS
|
# define USE_FAR_RKTIO_FDCALLS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_FAR_RKTIO_FDCALLS
|
/************************************************************/
|
||||||
/* A single fdset that can be reused for immediate actions: */
|
/* Globals, as gathered into `rktio_t` */
|
||||||
THREAD_LOCAL_DECL(extern rktio_poll_set_t *rktio_global_fd_set);
|
/************************************************************/
|
||||||
|
|
||||||
|
struct rktio_t {
|
||||||
|
intptr_t errid;
|
||||||
|
int errkind;
|
||||||
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
struct group_member_cache_entry_t *group_member_cache;
|
||||||
|
int external_event_fd;
|
||||||
|
int put_external_event_fd;
|
||||||
|
#endif
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
int windows_nt_or_later;
|
||||||
|
HANDLE break_semaphore;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAR_RKTIO_FDCALLS
|
||||||
|
/* A single fdset that can be reused for immediate actions: */
|
||||||
|
struct rktio_poll_set_t *rktio_global_fd_set;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Poll sets */
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
typedef struct rktio_poll_set_t rktio_poll_set_t;
|
||||||
|
|
||||||
|
void rktio_alloc_global_poll_set(rktio_t *rktio);
|
||||||
|
int rktio_initialize_signal(rktio_t *rktio);
|
||||||
|
|
||||||
|
#ifdef USE_FAR_RKTIO_FDCALLS
|
||||||
# define DECL_FDSET(n, c) fd_set *n
|
# define DECL_FDSET(n, c) fd_set *n
|
||||||
# define INIT_DECL_FDSET(r, w, e) { \
|
# define INIT_DECL_FDSET(r, w, e) { \
|
||||||
r = RKTIO_GET_FDSET(rktio_global_poll_set, 0 ); \
|
r = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 0 ); \
|
||||||
w = RKTIO_GET_FDSET(rktio_global_poll_set, 1 ); \
|
w = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 1 ); \
|
||||||
e = RKTIO_GET_FDSET(rktio_global_poll_set, 2 ); \
|
e = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 2 ); \
|
||||||
}
|
}
|
||||||
# define INIT_DECL_RD_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 0 )
|
# define INIT_DECL_RD_FDSET(r) r = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 0 )
|
||||||
# define INIT_DECL_WR_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 1 )
|
# define INIT_DECL_WR_FDSET(r) r = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 1 )
|
||||||
# define INIT_DECL_ER_FDSET(r) r = RKTIO_GET_FDSET(rktio_global_poll_set, 2 )
|
# define INIT_DECL_ER_FDSET(r) r = RKTIO_GET_FDSET(rktio->rktio_global_poll_set, 2 )
|
||||||
|
|
||||||
# define RKTIO_GET_FDSET(p, n) rktio_get_fdset(p, n)
|
# define RKTIO_GET_FDSET(p, n) rktio_get_fdset(p, n)
|
||||||
# define RKTIO_FD_ZERO(p) rktio_fdzero(p)
|
# define RKTIO_FD_ZERO(p) rktio_fdzero(p)
|
||||||
|
@ -58,6 +68,10 @@ THREAD_LOCAL_DECL(extern rktio_poll_set_t *rktio_global_fd_set);
|
||||||
# define RKTIO_FD_CLR(n, p) rktio_fdclr(p, n)
|
# define RKTIO_FD_CLR(n, p) rktio_fdclr(p, n)
|
||||||
# define RKTIO_FD_ISSET(n, p) rktio_fdisset(p, n)
|
# define RKTIO_FD_ISSET(n, p) rktio_fdisset(p, n)
|
||||||
|
|
||||||
|
# if !defined(HAVE_POLL_SYSCALL) && !defined(RKTIO_SYSTEM_WINDOWS)
|
||||||
|
# define RKTIO_FDS(p) ((fd_set *)fds)
|
||||||
|
# endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
@ -82,3 +96,34 @@ struct rktio_poll_set_t { fd_set data; };
|
||||||
rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds);
|
rktio_poll_set_t *rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds);
|
||||||
void rktio_clean_fd_set(rktio_poll_set_t *fds);
|
void rktio_clean_fd_set(rktio_poll_set_t *fds);
|
||||||
int rktio_get_fd_limit(rktio_poll_set_t *fds);
|
int rktio_get_fd_limit(rktio_poll_set_t *fds);
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Misc */
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
# define MSC_IZE(n) _ ## n
|
||||||
|
# define MSC_W_IZE(n) _w ## n
|
||||||
|
# define MSC_WIDE_PATH_temp(n) WIDE_PATH_temp(n)
|
||||||
|
#else
|
||||||
|
# define MSC_IZE(n) n
|
||||||
|
# define MSC_W_IZE(n) MSC_IZE(n)
|
||||||
|
# define MSC_WIDE_PATH_temp(n) n
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rktio_get_posix_error(rktio_t *rktio);
|
||||||
|
#define get_posix_error() rktio_get_posix_error(rktio)
|
||||||
|
|
||||||
|
void rktio_set_racket_error(rktio_t *rktio, int errid);
|
||||||
|
#define set_racket_error(e) rktio_set_racket_error(rktio, e)
|
||||||
|
|
||||||
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
void rktio_get_windows_error(rktio_t *rktio);
|
||||||
|
# define get_windows_error() rktio_get_windows_error(rktio)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_FCNTL_O_NONBLOCK)
|
||||||
|
# define RKTIO_NONBLOCKING O_NONBLOCK
|
||||||
|
#else
|
||||||
|
# define RKTIO_NONBLOCKING FNDELAY
|
||||||
|
#endif
|
||||||
|
|
|
@ -12,12 +12,6 @@
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_FCNTL_O_NONBLOCK)
|
|
||||||
# define RKTIO_NONBLOCKING O_NONBLOCK
|
|
||||||
#else
|
|
||||||
# define RKTIO_NONBLOCKING FNDELAY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RKTIO_BINARY
|
#ifndef RKTIO_BINARY
|
||||||
# define RKTIO_BINARY 0
|
# define RKTIO_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -97,7 +91,7 @@ static void init_read_fd(rktio_fd_t *rfd)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
rktio_fd_t *rktio_system_fd(intptr_t system_fd, int modes)
|
rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes)
|
||||||
{
|
{
|
||||||
rktio_fd_t *rfd;
|
rktio_fd_t *rfd;
|
||||||
|
|
||||||
|
@ -128,7 +122,7 @@ rktio_fd_t *rktio_system_fd(intptr_t system_fd, int modes)
|
||||||
return rfd;
|
return rfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t rktio_fd_system_fd(rktio_fd_t *rfd)
|
intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd)
|
||||||
{
|
{
|
||||||
return rfd->fd;
|
return rfd->fd;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +131,7 @@ intptr_t rktio_fd_system_fd(rktio_fd_t *rfd)
|
||||||
/* opening a file fd */
|
/* opening a file fd */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
static rktio_fd_t *open_read(char *filename)
|
static rktio_fd_t *open_read(rktio_t *rktio, char *filename)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -212,7 +206,7 @@ static rktio_fd_t *open_read(char *filename)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static rktio_fd_t *open_write(char *filename, int modes)
|
static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -369,19 +363,19 @@ static rktio_fd_t *open_write(char *filename, int modes)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
rktio_fd_t *rktio_open(char *filename, int modes)
|
rktio_fd_t *rktio_open(rktio_t *rktio, char *filename, int modes)
|
||||||
{
|
{
|
||||||
if (modes & RKTIO_OPEN_WRITE)
|
if (modes & RKTIO_OPEN_WRITE)
|
||||||
return open_write(filename, modes);
|
return open_write(rktio, filename, modes);
|
||||||
else
|
else
|
||||||
return open_read(filename);
|
return open_read(rktio, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* closing */
|
/* closing */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
int rktio_close(rktio_fd_t *rfd)
|
int rktio_close(rktio_t *rktio, rktio_fd_t *rfd)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
int cr;
|
int cr;
|
||||||
|
@ -483,7 +477,7 @@ static int try_get_fd_char(int fd, int *ready)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rktio_poll_read_ready(rktio_fd_t *rfd)
|
int rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd)
|
||||||
{
|
{
|
||||||
if (rfd->regfile)
|
if (rfd->regfile)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -573,7 +567,7 @@ int rktio_poll_read_ready(rktio_fd_t *rfd)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int poll_write_ready_or_flushed(rktio_fd_t *rfd, int check_flushed)
|
int poll_write_ready_or_flushed(rktio_t *rktio, rktio_fd_t *rfd, int check_flushed)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
if (check_flushed)
|
if (check_flushed)
|
||||||
|
@ -645,17 +639,17 @@ int poll_write_ready_or_flushed(rktio_fd_t *rfd, int check_flushed)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_poll_write_ready(rktio_fd_t *rfd)
|
int rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd)
|
||||||
{
|
{
|
||||||
return poll_write_ready_or_flushed(rfd, 0);
|
return poll_write_ready_or_flushed(rktio, rfd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_poll_write_flushed(rktio_fd_t *rfd)
|
int rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd)
|
||||||
{
|
{
|
||||||
return poll_write_ready_or_flushed(rfd, 1);
|
return poll_write_ready_or_flushed(rktio, rfd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rktio_poll_add(rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes)
|
void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
rktio_poll_set_t *fds2;
|
rktio_poll_set_t *fds2;
|
||||||
|
@ -708,7 +702,7 @@ void rktio_poll_add(rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes)
|
||||||
/* reading */
|
/* reading */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
intptr_t rktio_read(rktio_fd_t *rfd, char *buffer, intptr_t len)
|
intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
intptr_t bc;
|
intptr_t bc;
|
||||||
|
@ -875,10 +869,10 @@ static void WindowsFDICleanup(Win_FD_Input_Thread *th)
|
||||||
/* writing */
|
/* writing */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
intptr_t rktio_write(rktio_fd_t *rfd, char *buffer, intptr_t len)
|
intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
int flags;
|
int flags, errsaved;
|
||||||
intptr_t amt;
|
intptr_t amt;
|
||||||
|
|
||||||
flags = fcntl(rfd->fd, F_GETFL, 0);
|
flags = fcntl(rfd->fd, F_GETFL, 0);
|
||||||
|
@ -898,15 +892,20 @@ intptr_t rktio_write(rktio_fd_t *rfd, char *buffer, intptr_t len)
|
||||||
amt = amt >> 1;
|
amt = amt >> 1;
|
||||||
} while ((len == -1) && (errno == EAGAIN) && (amt > 0));
|
} while ((len == -1) && (errno == EAGAIN) && (amt > 0));
|
||||||
|
|
||||||
if (len == -1)
|
if (len == -1) {
|
||||||
|
errsaved = errno;
|
||||||
get_posix_error();
|
get_posix_error();
|
||||||
|
}
|
||||||
|
|
||||||
if (!(flags & RKTIO_NONBLOCKING))
|
if (!(flags & RKTIO_NONBLOCKING))
|
||||||
fcntl(rfd->fd, F_SETFL, flags);
|
fcntl(rfd->fd, F_SETFL, flags);
|
||||||
|
|
||||||
if (len == -1)
|
if (len == -1) {
|
||||||
return RKTIO_WRITE_ERROR;
|
if (errsaved == EAGAIN)
|
||||||
|
return 0;
|
||||||
else
|
else
|
||||||
|
return RKTIO_WRITE_ERROR;
|
||||||
|
} else
|
||||||
return len;
|
return len;
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
|
|
0
racket/src/rktio/rktio_sleep.c
Normal file
0
racket/src/rktio/rktio_sleep.c
Normal file
Loading…
Reference in New Issue
Block a user