rktio: add filesystem-change events

This commit is contained in:
Matthew Flatt 2017-06-12 17:06:30 -06:00
parent 19776f6bb9
commit 2187e77e65
11 changed files with 629 additions and 44 deletions

View File

@ -8,7 +8,7 @@ LIBS = @LIBS@
RKTIO_HEADERS = $(srcdir)/rktio.h $(srcdir)/rktio_private.h rktio_config.h
OBJS = rktio_filesystem.o \
OBJS = rktio_fs.o \
rktio_fd.o \
rktio_file.o \
rktio_poll_set.o \
@ -16,6 +16,7 @@ OBJS = rktio_filesystem.o \
rktio_network.o \
rktio_process.o \
rktio_envvars.o \
rktio_fs_change.o \
rktio_error.o \
rktio_main.o
@ -30,8 +31,8 @@ rktio_demo: $(OBJS) demo.o demo_fifo
demo_fifo:
mkfifo demo_fifo
rktio_filesystem.o: $(srcdir)/rktio_filesystem.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_filesystem.o -c $(srcdir)/rktio_filesystem.c
rktio_fs.o: $(srcdir)/rktio_fs.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_fs.o -c $(srcdir)/rktio_fs.c
rktio_fd.o: $(srcdir)/rktio_fd.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_fd.o -c $(srcdir)/rktio_fd.c
@ -54,6 +55,9 @@ rktio_process.o: $(srcdir)/rktio_process.c $(RKTIO_HEADERS)
rktio_envvars.o: $(srcdir)/rktio_envvars.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_envvars.o -c $(srcdir)/rktio_envvars.c
rktio_fs_change.o: $(srcdir)/rktio_fs_change.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_fs_change.o -c $(srcdir)/rktio_fs_change.c
rktio_error.o: $(srcdir)/rktio_error.c $(RKTIO_HEADERS)
$(CC) $(CFLAGS) -I$(srcdir) -I. -o rktio_error.o -c $(srcdir)/rktio_error.c

View File

@ -882,6 +882,43 @@ int main(int argc, char **argv)
rktio_forget(rktio, err_fd);
}
/* Filesystem-change events */
if (rktio_fs_change_properties(rktio) & RKTIO_FS_CHANGE_SUPPORTED) {
char *path = "test1";
rktio_fs_change_t *fc;
rktio_poll_set_t *ps;
if (verbose)
printf("fs change\n");
fc = rktio_fs_change(rktio, path);
check_valid(fc);
check_valid(!rktio_poll_fs_change_ready(rktio, fc));
ps = rktio_make_poll_set(rktio);
check_valid(ps);
rktio_poll_add_fs_change(rktio, fc, ps);
rktio_sleep(rktio, 0.1, ps, NULL);
/* FIXME: check that at least 0.1 seconds have passed */
fd2 = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
check_valid(fd2);
amt = rktio_write(rktio, fd2, "hola", 4);
check_valid(amt == 4);
rktio_sleep(rktio, 0, ps, NULL);
check_valid(rktio_poll_fs_change_ready(rktio, fc) == RKTIO_POLL_READY);
check_valid(rktio_poll_fs_change_ready(rktio, fc) == RKTIO_POLL_READY);
check_valid(rktio_close(rktio, fd2));
rktio_poll_set_close(rktio, ps);
rktio_fs_change_forget(rktio, fc);
}
if (verbose)
printf("done\n");

View File

@ -200,6 +200,22 @@ rktio_status_t *rktio_process_status(rktio_t *rktio, rktio_process_t *sp);
void rktio_block_child_signals(rktio_t*rktio, int block);
/*************************************************/
/* Filesystem-change events */
#define RKTIO_FS_CHANGE_SUPPORTED (1 << 0)
#define RKTIO_FS_CHANGE_SCALABLE (1 << 1)
#define RKTIO_FS_CHANGE_LOW_LATENCY (1 << 2)
#define RKTIO_FS_CHANGE_FILE_LEVEL (1 << 3)
int rktio_fs_change_properties(rktio_t *rktio);
typedef struct rktio_fs_change_t rktio_fs_change_t;
rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path);
void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc);
int rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
/*************************************************/
/* File-descriptor sets for polling */
@ -219,6 +235,7 @@ void rktio_poll_add_receive(rktio_t *rktio, rktio_listener_t *listener, rktio_po
void rktio_poll_add_connect(rktio_t *rktio, rktio_connect_t *conn, rktio_poll_set_t *fds);
void rktio_poll_add_addrinfo_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup, rktio_poll_set_t *fds);
void rktio_poll_add_process(rktio_t *rktio, rktio_process_t *sp, rktio_poll_set_t *fds);
void rktio_poll_add_fs_change(rktio_t *rktio, rktio_fs_change_t *fc, rktio_poll_set_t *fds);
void rktio_poll_set_add_nosleep(rktio_t *rktio, rktio_poll_set_t *fds);
@ -243,6 +260,7 @@ enum {
RKTIO_LTPS_CHECK_READ,
RKTIO_LTPS_CHECK_WRITE,
RKTIO_LTPS_REMOVE,
/* Internal, for filesystem-change events with kqueue: */
RKTIO_LTPS_CREATE_VNODE,
RKTIO_LTPS_CHECK_VNODE,
RKTIO_LTPS_REMOVE_VNODE

View File

@ -196,6 +196,15 @@ rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd)
/* closing */
/*************************************************************/
#ifdef RKTIO_SYSTEM_UNIX
void rktio_reliably_close(intptr_t s) {
int cr;
do {
cr = close(s);
} while ((cr == -1) && (errno == EINTR));
}
#endif
int rktio_close(rktio_t *rktio, rktio_fd_t *rfd)
{
#ifdef RKTIO_SYSTEM_UNIX
@ -206,9 +215,7 @@ int rktio_close(rktio_t *rktio, rktio_fd_t *rfd)
release_lockf(rfd->fd);
# endif
do {
cr = close(rfd->fd);
} while ((cr == -1) && (errno == EINTR));
rktio_reliably_close(rfd->fd);
#endif
#ifdef RKTIO_SYSTEM_WINDOWS
if (rfd->modes & RKTIO_OPEN_SOCKET)

View File

@ -12,10 +12,6 @@
# include <windows.h>
#endif
#ifndef RKTIO_BINARY
# define RKTIO_BINARY 0
#endif
/*************************************************************/
/* opening a file fd */
/*************************************************************/

View File

@ -0,0 +1,522 @@
#include "rktio.h"
#include "rktio_private.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#if defined(HAVE_KQUEUE_SYSCALL)
# include <fcntl.h>
#endif
#if defined(HAVE_INOTIFY_SYSCALL)
# include <poll.h>
# include <sys/inotify.h>
#endif
#if defined(HAVE_KQUEUE_SYSCALL) \
|| defined(RKTIO_SYSTEM_WINDOWS) \
|| defined(HAVE_INOTIFY_SYSCALL) \
|| defined(FILESYSTEM_NEVER_CHANGES)
# define HAVE_FILESYSTEM_CHANGE_EVTS
#else
# define NO_FILESYSTEM_CHANGE_EVTS
#endif
#if defined(HAVE_INOTIFY_SYSCALL)
static void do_inotify_init(rktio_t *rktio);
static int do_inotify_ready(rktio_t *rktio);
static int do_inotify_errid(rktio_t *rktio);
static int do_inotify_add(rktio_t *rktio, char *filename);
static void do_inotify_remove(rktio_t *rktio, int p2);
static int do_inotify_poll(rktio_t *rktio, int p2);
static void do_inotify_stop(rktio_t *rktio);
static int do_inotify_fd(rktio_t *rktio);
#endif
/*========================================================================*/
/* Common type and functions */
/*========================================================================*/
struct rktio_fs_change_t {
int done;
intptr_t fd;
#if defined(HAVE_KQUEUE_SYSCALL) && !defined(FILESYSTEM_NEVER_CHANGES)
rktio_ltps_t *lt;
rktio_ltps_handle_t *lth;
#endif
};
int rktio_fs_change_properties(rktio_t *rktio)
{
int flags = 0;
#ifdef NO_FILESYSTEM_CHANGE_EVTS
#else
flags |= RKTIO_FS_CHANGE_SUPPORTED;
# if !defined(HAVE_KQUEUE_SYSCALL)
flags |= RKTIO_FS_CHANGE_SCALABLE;
# endif
# if !defined(HAVE_INOTIFY_SYSCALL)
flags |= RKTIO_FS_CHANGE_LOW_LATENCY;
# endif
# if !defined(RKTIO_SYSTEM_WINDOWS)
flags |= RKTIO_FS_CHANGE_FILE_LEVEL;
# endif
#endif
return flags;
}
rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path)
{
int ok = 0;
#ifndef NO_FILESYSTEM_CHANGE_EVTS
int errid = 0;
# if defined(HAVE_KQUEUE_SYSCALL)
rktio_ltps_t *lt;
rktio_ltps_handle_t *lth;
# endif
#endif
intptr_t fd;
rktio_fs_change_t *fc;
fd = 0;
#if defined(NO_FILESYSTEM_CHANGE_EVTS)
set_racket_error(RKTIO_ERROR_UNSUPPORTED);
ok = 0;
#elif defined(FILESYSTEM_NEVER_CHANGES)
ok = 1;
#elif defined(HAVE_KQUEUE_SYSCALL)
do {
fd = open(path, RKTIO_BINARY, 0666);
} while ((fd == -1) && (errno == EINTR));
if (fd == -1)
get_posix_error();
else {
rktio_fd_t *rfd;
rfd = rktio_system_fd(rktio, fd, 0);
lt = rktio_open_ltps(rktio);
if (lt)
lth = rktio_ltps_add(rktio, lt, rfd, RKTIO_LTPS_CREATE_VNODE);
if (!lt || !lth) {
if (lt)
rktio_ltps_close(rktio, lt);
rktio_reliably_close(fd);
} else
ok = 1;
rktio_forget(rktio, rfd);
}
#elif defined(HAVE_INOTIFY_SYSCALL)
do_inotify_init(rktio);
if (!do_inotify_ready(rktio)) {
errno = do_inotify_errid(rktio);
get_posix_error();
} else {
fd = do_inotify_add(rktio, path);
if (fd == -1)
get_posix_error();
else
ok = 1;
}
#elif defined(RKTIO_SYSTEM_WINDOWS)
{
HANDLE h;
h = FindFirstChangeNotificationW(WIDE_PATH_tmp(try_path), FALSE,
(FILE_NOTIFY_CHANGE_FILE_NAME
| FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_ATTRIBUTES));
if (h == INVALID_HANDLE_VALUE)
set_windows_error();
else {
fd = (intptr_t)h;
ok = 1;
}
}
#endif
if (!ok)
return NULL;
fc = malloc(sizeof(rktio_fs_change_t));
fc->done = 0;
fc->fd = fd;
#if defined(HAVE_KQUEUE_SYSCALL) && !defined(NO_FILESYSTEM_CHANGE_EVTS)
fc->lt = lt;
fc->lth = lth;
#endif
return fc;
}
static void fs_change_release(rktio_t *rktio, rktio_fs_change_t *fc)
{
if (fc->done)
return;
# if defined(FILESYSTEM_NEVER_CHANGES)
/* nothing to do */
# elif defined(RKTIO_SYSTEM_WINDOWS)
FindCloseChangeNotification((HANDLE)fc->fd);
# elif defined(HAVE_INOTIFY_SYSCALL)
do_inotify_remove(rktio, fc->fd);
# elif defined(HAVE_KQUEUE_SYSCALL)
rktio_ltps_close(rktio, fc->lt);
free(fc->lth);
rktio_reliably_close(fc->fd);
#endif
fc->done = 1;
}
void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc)
{
fs_change_release(rktio, fc);
free(fc);
}
int rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc)
{
#if defined(NO_FILESYSTEM_CHANGE_EVTS)
return 0;
#elif defined(RKTIO_SYSTEM_WINDOWS)
if (!fc->done) {
if (WaitForSingleObject((HANDLE)fc->fd, 0) == WAIT_OBJECT_0)
fs_change_release(rktio, fc);
}
return (fc->done ? RKTIO_POLL_READY : 0);
#elif defined(HAVE_INOTIFY_SYSCALL)
if (!fc->done) {
int r = do_inotify_poll(rktio, fc->fd);
if (r < 0)
return RKTIO_POLL_ERROR;
if (r)
fs_change_release(rktio, fc);
}
return (fc->done ? RKTIO_POLL_READY : 0);
#elif defined(FILESYSTEM_NEVER_CHANGES)
return 0;
#elif defined(HAVE_KQUEUE_SYSCALL)
if (!fc->done) {
if (rktio_ltps_poll(rktio, fc->lt))
if (rktio_ltps_get_signaled_handle(rktio, fc->lt) == fc->lth)
fs_change_release(rktio, fc);
}
return (fc->done ? RKTIO_POLL_READY : 0);
#endif
}
void rktio_poll_add_fs_change(rktio_t *rktio, rktio_fs_change_t *fc, rktio_poll_set_t *fds)
{
if (fc->done) {
rktio_poll_set_add_nosleep(rktio, fds);
return;
}
#if defined(NO_FILESYSTEM_CHANGE_EVTS)
#elif defined(RKTIO_SYSTEM_WINDOWS)
rktio_poll_set_add_handle(rktio, (HANDLE)fc->fd, fds, 0);
#elif defined(HAVE_INOTIFY_SYSCALL)
int fd;
fd = do_inotify_fd(rktio);
if (fd >= 0) {
rktio_poll_set_t *fds2;
RKTIO_FD_SET(fd, fds);
fds2 = RKTIO_GET_FDSET(fds, 2);
RKTIO_FD_SET(fd, fds2);
} else if (fd == -2) {
rktio_poll_set_add_nosleep(rktio, fds);
}
#elif defined(FILESYSTEM_NEVER_CHANGES)
#elif defined(HAVE_KQUEUE_SYSCALL)
{
int fd = rktio_ltps_get_fd(fc->lt);
rktio_poll_set_t *fds2;
RKTIO_FD_SET(fd, fds);
fds2 = RKTIO_GET_FDSET(fds, 2);
RKTIO_FD_SET(fd, fds2);
}
#endif
}
void rktio_stop_fs_change(rktio_t *rktio)
{
#ifdef HAVE_INOTIFY_SYSCALL
do_inotify_stop(rktio);
#endif
}
/*========================================================================*/
/* inotify */
/*========================================================================*/
/* Multiplex multiple filesystem change events onto a single
inotify connection. That's almost as easy as using watch
descriptors in place of file descriptors, but using the
same filesystem path multiple times produces the same
watch descriptors, so reference-count it. Also, each watch
can be removed as soon as it fires, since filesystem
change events are single-shot.
The values returned by do_inotify_add() are indices into an array
of watch descriptors. There's room for a better data structure if
the watch-descriptor-to-index mapping becomes too slow. */
#ifdef HAVE_INOTIFY_SYSCALL
typedef struct rin_wd_t {
int wd;
int refcount;
int val;
} rin_wd_t;
typedef struct rin_inotify_state_t {
int ready, errid, fd;
rin_wd_t *wds;
int size, count;
int got;
} rin_inotify_state_t;
static int rin_find_wd(int wd, rin_wd_t *wds, int size)
{
int i;
for (i = 0; i < size; i++) {
if (wds[i].wd == wd) return i;
}
return -1;
}
static int rin_add_wd(int wd, rin_wd_t *wds, int size)
{
int i;
for (i = 0; i < size; i++) {
if (wds[i].wd == wd) {
wds[i].refcount++;
return i;
}
}
for (i = 0; i < size; i++) {
if (!wds[i].refcount) {
wds[i].wd = wd;
wds[i].refcount = 1;
wds[i].val = 0;
return i;
}
}
abort();
return -1;
}
static int rin_pull_events(rktio_t *rktio, int fd, rin_wd_t *wds, int size)
{
struct inotify_event _ev, *ev;
void *b = NULL;
int rc, p, got = 0;
int bsize;
struct pollfd pfd[1];
ev = &_ev;
bsize = sizeof(_ev);
pfd[0].fd = fd;
pfd[0].events = POLLIN;
while (poll(pfd, 1, 0)) {
rc = read(fd, ev, bsize);
if (rc > 0) {
p = rin_find_wd(ev->wd, wds, size);
if (p != -1) {
got = 1;
wds[p].val = 1;
wds[p].wd = -1;
inotify_rm_watch(fd, ev->wd);
}
} else if (rc == -1) {
if (errno == EAGAIN)
break;
else if (errno == EINTR) {
/* try again */
} else if (errno == EINVAL) {
bsize *= 2;
if (b) free(b);
b = malloc(bsize);
ev = (struct inotify_event *)b;
} else {
get_posix_error();
return -1;
}
} else
break;
}
if (b)
free (b);
return got;
}
static void rin_inotify_start(rin_inotify_state_t *s)
{
int fd;
fd = inotify_init();
if (fd == -1) {
s->errid = errno;
} else {
s->errid = 0;
s->ready = 1;
s->fd = fd;
}
}
static void rin_inotify_end(rin_inotify_state_t *s)
{
int rc;
if (s->ready) {
do {
rc = close(s->fd);
} while (rc == -1 && errno == EINTR);
}
if (s->wds) free(s->wds);
free(s);
}
static void do_inotify_init(rktio_t *rktio)
{
rin_inotify_state_t *s = rktio->inotify_server;
if (!s) {
s = (rin_inotify_state_t *)malloc(sizeof(rin_inotify_state_t));
memset(s, 0, sizeof(rin_inotify_state_t));
rktio->inotify_server = s;
}
if (!s->ready)
rin_inotify_start(s);
}
static int do_inotify_ready(rktio_t *rktio)
{
rin_inotify_state_t *s = rktio->inotify_server;
return s->ready;
}
static int do_inotify_errid(rktio_t *rktio)
{
rin_inotify_state_t *s = rktio->inotify_server;
return s->errid;
}
/* Other functions are called only if do_inotify_ready() returns 1. */
static int do_inotify_add(rktio_t *rktio, char *filename)
{
rin_inotify_state_t *s = rktio->inotify_server;
int wd;
if (s->count == s->size) {
int new_size = (s->size ? (2 * s->size) : 32);
rin_wd_t *new_wds;
int i;
new_wds = (rin_wd_t *)malloc(sizeof(rin_wd_t) * new_size);
memcpy(new_wds, s->wds, s->size * sizeof(rin_wd_t));
if (s->wds) free(s->wds);
s->wds = new_wds;
s->size = new_size;
for (i = s->count; i < s->size; i++)
{
s->wds[i].wd = -1;
s->wds[i].refcount = 0;
}
}
wd = inotify_add_watch(s->fd, filename,
(IN_CREATE | IN_DELETE | IN_DELETE_SELF
| IN_MODIFY | IN_MOVE_SELF | IN_MOVED_TO
| IN_ATTRIB | IN_ONESHOT));
if (wd == -1)
return -1;
else {
int p;
p = rin_add_wd(wd, s->wds, s->size);
if (s->wds[p].refcount == 1)
s->count++;
return p+1;
}
}
static void do_inotify_remove(rktio_t *rktio, int p2)
{
rin_inotify_state_t *s = rktio->inotify_server;
int p = p2 - 1;
if (s->wds[p].refcount == 1) {
if (s->wds[p].wd != -1) {
inotify_rm_watch(s->fd, s->wds[p].wd);
s->wds[p].wd = -1;
/* in case the wd gets reused: */
if (rin_pull_events(rktio, s->fd, s->wds, s->size) > 0)
s->got = 1;
}
--s->count;
}
s->wds[p].refcount -= 1;
}
static int do_inotify_poll(rktio_t *rktio, int p2)
{
rin_inotify_state_t *s = rktio->inotify_server;
int p = p2 - 1, r;
r = rin_pull_events(rktio, s->fd, s->wds, s->size);
if (r > 0)
s->got = 1;
if (r < 0)
return -1;
else if (s->wds[p].val)
return 1;
else
return 0;
}
static void do_inotify_stop(rktio_t *rktio)
{
rin_inotify_state_t *s = rktio->inotify_server;
if (s) {
rin_inotify_end(s);
rktio->inotify_server = NULL;
}
}
static int do_inotify_fd(rktio_t *rktio)
{
rin_inotify_state_t *s = rktio->inotify_server;
if (s->got) {
/* In case we received something for Y in a poll for X */
s->got = 0;
return -2;
}
return s->fd;
}
#endif

View File

@ -29,6 +29,7 @@ void rktio_destroy(rktio_t *rktio)
rktio_process_deinit(rktio);
rktio_free_ghbn(rktio);
rktio_free_global_poll_set(rktio);
rktio_stop_fs_change(rktio);
free(rktio);
}

View File

@ -26,15 +26,8 @@
typedef intptr_t rktio_socket_t;
# define INVALID_SOCKET (-1)
static void reliably_close(intptr_t s) {
int cr;
do {
cr = close(s);
} while ((cr == -1) && (errno == EINTR));
}
static void closesocket(rktio_socket_t s) {
reliably_close(s);
rktio_reliably_close(s);
}
typedef struct sockaddr_in rktio_unspec_address;
@ -430,7 +423,7 @@ static intptr_t getaddrinfo_in_thread(void *_data)
do {
err = write(lookup->done_fd[1], &v, sizeof(v));
} while ((err == -1) && (errno == EINTR));
reliably_close(lookup->done_fd[1]);
rktio_reliably_close(lookup->done_fd[1]);
}
# endif
@ -438,7 +431,7 @@ static intptr_t getaddrinfo_in_thread(void *_data)
# ifdef RKTIO_SYSTEM_WINDOWS
CloseHandle(data->ready_sema);
# else
reliably_close(lookup->done_fd[0]);
rktio_reliably_close(lookup->done_fd[0]);
# endif
free_lookup(lookup);
}
@ -582,7 +575,7 @@ int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lo
cr = read(lookup->done_fd[0], &v, sizeof(long));
} while ((cr == -1) && (errno == EINTR));
if (cr > 0) {
reliably_close(lookup->done_fd[0]);
rktio_reliably_close(lookup->done_fd[0]);
done = 1;
}
}
@ -633,7 +626,7 @@ void rktio_addrinfo_lookup_stop(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup)
# ifdef RKTIO_SYSTEM_WINDOWS
CloseHandle(lookup->done_sema);
# else
reliably_close(lookup->done_fd[0]);
rktio_reliably_close(lookup->done_fd[0]);
# endif
free_lookup(lookup);
}

View File

@ -82,6 +82,10 @@ struct rktio_t {
#ifdef RKTIO_SYSTEM_WINDOWS
uintptr_t process_children_msecs;
#endif
#ifdef HAVE_INOTIFY_SYSCALL
struct rin_inotify_state_t *inotify_server;
#endif
};
/*========================================================================*/
@ -214,4 +218,14 @@ void rktio_get_windows_error(rktio_t *rktio);
# define RKTIO_NONBLOCKING FNDELAY
#endif
#ifndef RKTIO_BINARY
# define RKTIO_BINARY 0
#endif
#ifdef RKTIO_SYSTEM_UNIX
void rktio_reliably_close(intptr_t s);
#endif
void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars);
void rktio_stop_fs_change(rktio_t *rktio);

View File

@ -1221,13 +1221,6 @@ static void CloseFileHandleForSubprocess(intptr_t *hs, int pos)
#ifdef RKTIO_SYSTEM_UNIX
# define RKTIO_COPY_FOR_SUBPROCESS(array, pos) /* empty */
# define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) /* empty */
static void reliably_close(intptr_t s) {
int cr;
do {
cr = close(s);
} while ((cr == -1) && (errno == EINTR));
}
#endif
/*========================================================================*/
@ -1430,21 +1423,21 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
case -1:
/* Close all created descriptors */
if (!stdin_fd) {
reliably_close(to_subprocess[0]);
reliably_close(to_subprocess[1]);
rktio_reliably_close(to_subprocess[0]);
rktio_reliably_close(to_subprocess[1]);
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(to_subprocess, 0);
}
if (!stdout_fd) {
reliably_close(from_subprocess[0]);
reliably_close(from_subprocess[1]);
rktio_reliably_close(from_subprocess[0]);
rktio_reliably_close(from_subprocess[1]);
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(from_subprocess, 1);
}
if (!stderr_fd) {
if (!stderr_is_stdout) {
reliably_close(err_subprocess[0]);
reliably_close(err_subprocess[1]);
rktio_reliably_close(err_subprocess[0]);
rktio_reliably_close(err_subprocess[1]);
}
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(err_subprocess, 1);
@ -1467,17 +1460,17 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
/* Close unwanted descriptors */
if (!stdin_fd) {
reliably_close(to_subprocess[0]);
reliably_close(to_subprocess[1]);
rktio_reliably_close(to_subprocess[0]);
rktio_reliably_close(to_subprocess[1]);
}
if (!stdout_fd) {
reliably_close(from_subprocess[0]);
reliably_close(from_subprocess[1]);
rktio_reliably_close(from_subprocess[0]);
rktio_reliably_close(from_subprocess[1]);
}
if (!stderr_fd) {
if (!stderr_is_stdout) {
reliably_close(err_subprocess[0]);
reliably_close(err_subprocess[1]);
rktio_reliably_close(err_subprocess[0]);
rktio_reliably_close(err_subprocess[1]);
}
}
@ -1531,18 +1524,18 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
free(env);
if (!stdin_fd) {
reliably_close(to_subprocess[0]);
rktio_reliably_close(to_subprocess[0]);
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(to_subprocess, 0);
}
if (!stdout_fd) {
reliably_close(from_subprocess[1]);
rktio_reliably_close(from_subprocess[1]);
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(from_subprocess, 1);
}
if (!stderr_fd) {
if (!stderr_is_stdout)
reliably_close(err_subprocess[1]);
rktio_reliably_close(err_subprocess[1]);
} else {
RKTIO_CLOSE_SUBPROCESS_COPY(err_subprocess, 1);
}