rktio: compiles for Windows using MinGW
This commit is contained in:
parent
9bfaaf3ab3
commit
a929c58712
|
@ -27,15 +27,15 @@ OBJS = rktio_fs.@LTO@ \
|
|||
rktio_wide.@LTO@ \
|
||||
rktio_main.@LTO@
|
||||
|
||||
librktio.@LIBSFX@: $(OBJS)
|
||||
$(NICEAR) $(AR) $(ARFLAGS) librktio.@LIBSFX@ $(OBJS)
|
||||
$(RANLIB) librktio.@LIBSFX@
|
||||
librktio.@LTA@: $(OBJS)
|
||||
$(NICEAR) $(AR) $(ARFLAGS) librktio.@LTA@ $(OBJS)
|
||||
$(RANLIB) librktio.@LTA@
|
||||
|
||||
demo: rktio_demo
|
||||
./rktio_demo
|
||||
./rktio_demo $(ARGS)
|
||||
|
||||
rktio_demo: librktio.@LIBSFX@ demo.@LTO@ demo_fifo
|
||||
$(RKTLINKER) -o rktio_demo $(CFLAGS) $(LDFLAGS) demo.@LTO@ librktio.@LIBSFX@ $(LIBS)
|
||||
rktio_demo: librktio.@LTA@ demo.@LTO@ demo_fifo
|
||||
$(RKTLINKER) -o rktio_demo $(CFLAGS) $(LDFLAGS) demo.@LTO@ librktio.@LTA@ $(LIBS)
|
||||
|
||||
demo_fifo:
|
||||
mkfifo demo_fifo
|
||||
|
@ -80,4 +80,4 @@ demo.@LTO@: $(srcdir)/demo.c $(RKTIO_HEADERS)
|
|||
$(CC) $(CFLAGS) -I$(srcdir) -I. -o demo.@LTO@ -c $(srcdir)/demo.c
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) librktio.@LIBSFX@ rktio_demo demo_fifo
|
||||
rm -f $(OBJS) librktio.@LTA@ rktio_demo demo_fifo
|
||||
|
|
|
@ -456,8 +456,14 @@ int main(int argc, char **argv)
|
|||
else if (!strcmp(argv[i], "--sleep-blocks-sigchld")) {
|
||||
/* Seems useful for Valgrind on MacOS */
|
||||
dont_rely_on_sigchild = 1;
|
||||
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
printf("Recognized flags:\n");
|
||||
printf(" -v : verbose\n");
|
||||
printf(" --sleep-blocks-sigchld : Valgrind workaround\n");
|
||||
printf(" -h, --help : this help\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf(" unrecognized flag %s\n", argv[i]);
|
||||
printf(" unrecognized flag: %s\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -877,7 +883,7 @@ int main(int argc, char **argv)
|
|||
free(result);
|
||||
}
|
||||
|
||||
rktio_ennvars_free(rktio, envvars);
|
||||
rktio_envvars_free(rktio, envvars);
|
||||
|
||||
rktio_forget(rktio, err_fd);
|
||||
}
|
||||
|
@ -902,13 +908,18 @@ int main(int argc, char **argv)
|
|||
rktio_poll_add_fs_change(rktio, fc, ps);
|
||||
|
||||
rktio_sleep(rktio, 0.1, ps, NULL);
|
||||
rktio_poll_set_close(rktio, ps);
|
||||
/* FIXME: check that at least 0.1 seconds have passed */
|
||||
|
||||
ps = rktio_make_poll_set(rktio);
|
||||
check_valid(ps);
|
||||
rktio_poll_add_fs_change(rktio, fc, ps);
|
||||
|
||||
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);
|
||||
|
|
|
@ -43,6 +43,8 @@ int rktio_fd_is_regular_file(rktio_t *rktio, rktio_fd_t *rfd);
|
|||
int rktio_fd_is_socket(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
|
||||
int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);
|
||||
|
||||
rktio_fd_t *rktio_open(rktio_t *rktio, char *src, int modes);
|
||||
int rktio_close(rktio_t *rktio, rktio_fd_t *fd);
|
||||
|
||||
|
@ -151,7 +153,7 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val);
|
|||
rktio_envvars_t *rktio_envvars(rktio_t *rktio);
|
||||
rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio);
|
||||
rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
void rktio_ennvars_free(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
void rktio_envvars_free(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
|
||||
char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name);
|
||||
void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value);
|
||||
|
@ -219,8 +221,8 @@ int rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
|
|||
/*************************************************/
|
||||
/* File-descriptor sets for polling */
|
||||
|
||||
/* A poll set is intended for a single use or few uses, as opposed to
|
||||
"long-term" poll sets. */
|
||||
/* A poll set works for a single use via rktio_sleep(), as opposed to
|
||||
"long-term" poll sets that can be used multiple times. */
|
||||
|
||||
typedef struct rktio_poll_set_t rktio_poll_set_t;
|
||||
|
||||
|
|
|
@ -25,3 +25,6 @@ typedef unsigned long uintptr_t;
|
|||
|
||||
/* Whether getaddrinfo() is available: */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* In case you want to avoid dynamic sizing of `fd_set` arrays: */
|
||||
#undef RKTIO_STATIC_FDSET_SIZE
|
||||
|
|
|
@ -80,14 +80,14 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val)
|
|||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
int rc;
|
||||
char *val_w;
|
||||
wchar_t *val_w;
|
||||
|
||||
if (val)
|
||||
val_w = WIDE_PATH_copy(val);
|
||||
else
|
||||
val_w = NULL;
|
||||
|
||||
rc = SetEnvironmentVariableW(WIDE_PATH_temp(var), val_w);
|
||||
rc = SetEnvironmentVariableW(WIDE_PATH_temp(name), val_w);
|
||||
|
||||
if (val_w)
|
||||
free(val_w);
|
||||
|
@ -123,7 +123,7 @@ rktio_envvars_t *rktio_envvars(rktio_t *rktio)
|
|||
i++;
|
||||
}
|
||||
|
||||
ennvars = malloc(sizeof(rktio_envvars_t));
|
||||
envvars = malloc(sizeof(rktio_envvars_t));
|
||||
envvars->size = count;
|
||||
envvars->count = count;
|
||||
envvars->names = malloc(count * sizeof(char *));
|
||||
|
@ -209,7 +209,7 @@ rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars)
|
|||
return new_envvars;
|
||||
}
|
||||
|
||||
void rktio_ennvars_free(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
void rktio_envvars_free(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -353,12 +353,12 @@ for (i = 0; i < envvars->count; i++) {
|
|||
for (i = 0; i < envvars->count; i++) {
|
||||
s = WIDE_PATH_temp(envvars->names[i]);
|
||||
slen = wc_strlen(s);
|
||||
memcpy(r XFORM_OK_PLUS len, s, slen * sizeof(wchar_t));
|
||||
memcpy(r + len, s, slen * sizeof(wchar_t));
|
||||
len += slen;
|
||||
r[len++] = '=';
|
||||
s = WIDE_PATH(envvars->vals[i]);
|
||||
s = WIDE_PATH_temp(envvars->vals[i]);
|
||||
slen = wc_strlen(s);
|
||||
memcpy(r XFORM_OK_PLUS len, s, slen * sizeof(wchar_t));
|
||||
memcpy(r + len, s, slen * sizeof(wchar_t));
|
||||
len += slen;
|
||||
r[len++] = 0;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ struct rktio_fd_t {
|
|||
};
|
||||
struct Win_FD_Input_Thread *th; /* input mode */
|
||||
struct Win_FD_Output_Thread *oth; /* output mode */
|
||||
char *buffer;
|
||||
int unblocked; /* whether non-blocking mode is installed */
|
||||
char *buffer; /* shared with reading thread */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -86,6 +87,31 @@ typedef struct Win_FD_Output_Thread {
|
|||
|
||||
# define RKTIO_FD_BUFFSIZE 4096
|
||||
|
||||
static long WINAPI WindowsFDReader(Win_FD_Input_Thread *th);
|
||||
static void WindowsFDICleanup(Win_FD_Input_Thread *th);
|
||||
|
||||
static long WINAPI WindowsFDWriter(Win_FD_Output_Thread *oth);
|
||||
static void WindowsFDOCleanup(Win_FD_Output_Thread *oth);
|
||||
|
||||
typedef BOOL (WINAPI* CSI_proc)(HANDLE);
|
||||
|
||||
static CSI_proc get_csi(void)
|
||||
{
|
||||
static int tried_csi = 0;
|
||||
static CSI_proc csi;
|
||||
|
||||
if (!tried_csi) {
|
||||
HMODULE hm;
|
||||
hm = LoadLibrary("kernel32.dll");
|
||||
if (hm)
|
||||
csi = (CSI_proc)GetProcAddress(hm, "CancelSynchronousIo");
|
||||
else
|
||||
csi = NULL;
|
||||
tried_csi = 1;
|
||||
}
|
||||
return csi;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*========================================================================*/
|
||||
|
@ -135,7 +161,6 @@ static void init_read_fd(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
th->ready_sema = sm;
|
||||
sm = CreateSemaphore(NULL, 1, 1, NULL);
|
||||
th->you_clean_up_sema = sm;
|
||||
th->refcount = refcount;
|
||||
|
||||
h = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)WindowsFDReader, th, 0, &id);
|
||||
|
||||
|
@ -166,7 +191,7 @@ rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes)
|
|||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
if (modes & RKTIO_OPEN_SOCKET)
|
||||
rfd->s = system_fd;
|
||||
rfd->sock = system_fd;
|
||||
else
|
||||
rfd->fd = (HANDLE)system_fd;
|
||||
if (!(modes & (RKTIO_OPEN_REGFILE | RKTIO_OPEN_NOT_REGFILE | RKTIO_OPEN_SOCKET))) {
|
||||
|
@ -320,7 +345,7 @@ int rktio_close(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
WindowsFDOCleanup(rfd->oth);
|
||||
} /* otherwise, thread is responsible for clean-up */
|
||||
}
|
||||
if (!rfp->th && !rfp->oth) {
|
||||
if (!rfd->th && !rfd->oth) {
|
||||
CloseHandle(rfd->fd);
|
||||
}
|
||||
#endif
|
||||
|
@ -434,7 +459,7 @@ int rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
if (rfd->modes & RKTIO_OPEN_SOCKET)
|
||||
return rktio_socket_poll_read_ready(rktio, rfd->sock);
|
||||
return rktio_socket_poll_read_ready(rktio, rfd);
|
||||
|
||||
if (!rfd->th) {
|
||||
/* No thread -- so wait works. This case isn't actually used
|
||||
|
@ -511,7 +536,7 @@ int poll_write_ready_or_flushed(rktio_t *rktio, rktio_fd_t *rfd, int check_flush
|
|||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
if (rfd->modes & RKTIO_OPEN_SOCKET)
|
||||
return rktio_socket_poll_write_ready(rktio, rfd->sock);
|
||||
return rktio_socket_poll_write_ready(rktio, rfd);
|
||||
|
||||
if (rfd->oth) {
|
||||
/* Pipe output that can block... */
|
||||
|
@ -606,10 +631,10 @@ void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int
|
|||
}
|
||||
|
||||
if (modes & RKTIO_POLL_WRITE) {
|
||||
if (rfp->oth && !fd_write_ready(port))
|
||||
rktio_fdset_add_handle(rfp->oth->ready_sema, fds, 1);
|
||||
if (rfd->oth && !rktio_poll_write_ready(rktio, rfd))
|
||||
rktio_poll_set_add_handle(rfd->oth->ready_sema, fds, 1);
|
||||
else
|
||||
rktio_fdset_nosleep(fds);
|
||||
rktio_poll_set_nosleep(fds);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -707,7 +732,7 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
|
|||
} else {
|
||||
intptr_t bc = rfd->th->avail;
|
||||
rfd->th->avail = 0;
|
||||
FIXME read the data;
|
||||
memcpy(buffer, rfd->buffer, bc);
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
|
@ -779,7 +804,6 @@ static void WindowsFDICleanup(Win_FD_Input_Thread *th)
|
|||
CloseHandle(th->ready_sema);
|
||||
CloseHandle(th->you_clean_up_sema);
|
||||
|
||||
rc = adj_refcount(th->refcount, -1);
|
||||
if (!rc) CloseHandle(th->fd);
|
||||
|
||||
free(th->buffer);
|
||||
|
@ -849,13 +873,14 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len
|
|||
is ERROR_NOT_ENOUGH_MEMORY (as opposed to a partial write). */
|
||||
int ok;
|
||||
intptr_t towrite = len;
|
||||
int err;
|
||||
|
||||
while (1) {
|
||||
ok = WriteFile((HANDLE)rfd->fd, buffer, towrite, &winwrote, NULL);
|
||||
if (!ok)
|
||||
errsaved = GetLastError();
|
||||
err = GetLastError();
|
||||
|
||||
if (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY)) {
|
||||
if (!ok && (err == ERROR_NOT_ENOUGH_MEMORY)) {
|
||||
towrite = towrite >> 1;
|
||||
if (!towrite)
|
||||
break;
|
||||
|
@ -1000,7 +1025,6 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len
|
|||
oth->ready_sema = sm;
|
||||
sm = CreateSemaphore(NULL, 1, 1, NULL);
|
||||
oth->you_clean_up_sema = sm;
|
||||
oth->refcount = rfd->refcount;
|
||||
|
||||
h = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)WindowsFDWriter, oth, 0, &id);
|
||||
|
||||
|
@ -1100,55 +1124,84 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len
|
|||
#endif
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* refcounts for Windows fd threads */
|
||||
/*========================================================================*/
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
|
||||
#if defined(WINDOWS_FILE_HANDLES) || defined(MZ_USE_PLACES)
|
||||
# define MZ_LOCK_REFCOUNTS
|
||||
static mzrt_mutex *refcount_mutex;
|
||||
#endif
|
||||
|
||||
static int *malloc_refcount(int val, int free_on_zero)
|
||||
static long WINAPI WindowsFDWriter(Win_FD_Output_Thread *oth)
|
||||
{
|
||||
int *rc;
|
||||
DWORD towrite, wrote, start;
|
||||
int ok, more_work = 0, err_no;
|
||||
|
||||
#ifdef MZ_LOCK_REFCOUNTS
|
||||
if (!refcount_mutex)
|
||||
mzrt_mutex_create(&refcount_mutex);
|
||||
#endif
|
||||
if (oth->nonblocking) {
|
||||
/* Non-blocking mode (Win NT pipes). Just flush. */
|
||||
while (!oth->done) {
|
||||
WaitForSingleObject(oth->work_sema, INFINITE);
|
||||
|
||||
rc = (int *)malloc(2 * sizeof(int));
|
||||
*rc = val;
|
||||
rc[1] = free_on_zero;
|
||||
FlushFileBuffers(oth->fd);
|
||||
|
||||
return rc;
|
||||
WaitForSingleObject(oth->lock_sema, INFINITE);
|
||||
oth->flushed = 1;
|
||||
ReleaseSemaphore(oth->ready_sema, 1, NULL);
|
||||
ReleaseSemaphore(oth->lock_sema, 1, NULL);
|
||||
}
|
||||
} else {
|
||||
/* Blocking mode. We do the writing work. This case is for
|
||||
Win 95/98/Me anonymous pipes and character devices (such
|
||||
as LPT1). */
|
||||
while (!oth->err_no) {
|
||||
if (!more_work)
|
||||
WaitForSingleObject(oth->work_sema, INFINITE);
|
||||
|
||||
if (oth->done)
|
||||
break;
|
||||
|
||||
WaitForSingleObject(oth->lock_sema, INFINITE);
|
||||
towrite = oth->buflen;
|
||||
if (towrite > (RKTIO_FD_BUFFSIZE - oth->bufstart))
|
||||
towrite = RKTIO_FD_BUFFSIZE - oth->bufstart;
|
||||
start = oth->bufstart;
|
||||
ReleaseSemaphore(oth->lock_sema, 1, NULL);
|
||||
|
||||
ok = WriteFile(oth->fd, oth->buffer + start, towrite, &wrote, NULL);
|
||||
if (!ok)
|
||||
err_no = GetLastError();
|
||||
else
|
||||
err_no = 0;
|
||||
|
||||
WaitForSingleObject(oth->lock_sema, INFINITE);
|
||||
if (!ok)
|
||||
oth->err_no = err_no;
|
||||
else {
|
||||
oth->bufstart += wrote;
|
||||
oth->buflen -= wrote;
|
||||
if (oth->bufstart == RKTIO_FD_BUFFSIZE)
|
||||
oth->bufstart = 0;
|
||||
more_work = oth->buflen > 0;
|
||||
}
|
||||
if ((oth->buflen < RKTIO_FD_BUFFSIZE) || oth->err_no)
|
||||
ReleaseSemaphore(oth->ready_sema, 1, NULL);
|
||||
ReleaseSemaphore(oth->lock_sema, 1, NULL);
|
||||
}
|
||||
}
|
||||
if (WaitForSingleObject(oth->you_clean_up_sema, 0) != WAIT_OBJECT_0) {
|
||||
WindowsFDOCleanup(oth);
|
||||
} /* otherwise, main thread is responsible for clean-up */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adj_refcount(int *refcount, int amt)
|
||||
XFORM_SKIP_PROC
|
||||
static void WindowsFDOCleanup(Win_FD_Output_Thread *oth)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!refcount)
|
||||
return 0;
|
||||
CloseHandle(oth->lock_sema);
|
||||
CloseHandle(oth->work_sema);
|
||||
CloseHandle(oth->you_clean_up_sema);
|
||||
|
||||
if (!rc) CloseHandle(oth->fd);
|
||||
|
||||
#ifdef MZ_LOCK_REFCOUNTS
|
||||
mzrt_mutex_lock(refcount_mutex);
|
||||
#endif
|
||||
if (amt > 0) {
|
||||
/* don't increment up from 0 */
|
||||
if (*refcount)
|
||||
*refcount += amt;
|
||||
} else
|
||||
*refcount += amt;
|
||||
rc = *refcount;
|
||||
#ifdef MZ_LOCK_REFCOUNTS
|
||||
mzrt_mutex_unlock(refcount_mutex);
|
||||
#endif
|
||||
|
||||
if (!rc && refcount[1])
|
||||
free(refcount);
|
||||
|
||||
return rc;
|
||||
if (oth->buffer)
|
||||
free(oth->buffer);
|
||||
free(oth);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,7 +61,7 @@ static rktio_fd_t *open_read(rktio_t *rktio, char *filename)
|
|||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
HANDLE fd;
|
||||
|
||||
fd = CreateFileW(WIDE_PATH(filename),
|
||||
fd = CreateFileW(WIDE_PATH_temp(filename),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
|
@ -163,7 +163,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes)
|
|||
rktio_fd_t *rfd;
|
||||
|
||||
if (modes & RKTIO_OPEN_MUST_EXIST) {
|
||||
if (modes & RKTIO_OPEN_TRUNNCATE)
|
||||
if (modes & RKTIO_OPEN_TRUNCATE)
|
||||
hmode = TRUNCATE_EXISTING;
|
||||
else
|
||||
hmode = OPEN_EXISTING;
|
||||
|
@ -183,7 +183,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes)
|
|||
if (fd == INVALID_HANDLE_VALUE) {
|
||||
int errv;
|
||||
errv = GetLastError();
|
||||
if ((errv == ERROR_ACCESS_DENIED) && (existsok < -1)) {
|
||||
if ((errv == ERROR_ACCESS_DENIED) && (modes & RKTIO_OPEN_REPLACE)) {
|
||||
/* Delete and try again... */
|
||||
if (DeleteFileW(WIDE_PATH_temp(filename))) {
|
||||
fd = CreateFileW(WIDE_PATH_temp(filename),
|
||||
|
@ -220,7 +220,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes)
|
|||
}
|
||||
}
|
||||
|
||||
rfd = rktio_system_fd(rktio, fd, modes);
|
||||
rfd = rktio_system_fd(rktio, (intptr_t)fd, modes);
|
||||
|
||||
if ((modes & RKTIO_OPEN_APPEND) && rktio_fd_is_regular_file(rktio, rfd)) {
|
||||
SetFilePointer(fd, 0, NULL, FILE_END);
|
||||
|
|
|
@ -121,7 +121,7 @@ rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path)
|
|||
{
|
||||
HANDLE h;
|
||||
|
||||
h = FindFirstChangeNotificationW(WIDE_PATH_tmp(try_path), FALSE,
|
||||
h = FindFirstChangeNotificationW(WIDE_PATH_temp(path), FALSE,
|
||||
(FILE_NOTIFY_CHANGE_FILE_NAME
|
||||
| FILE_NOTIFY_CHANGE_DIR_NAME
|
||||
| FILE_NOTIFY_CHANGE_SIZE
|
||||
|
|
|
@ -21,6 +21,8 @@ rktio_t *rktio_init(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
rktio_useless_wide();
|
||||
|
||||
return rktio;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
# define TCP_SOCKSENDBUF_SIZE 32768
|
||||
# define NOT_WINSOCK(x) x
|
||||
# define NOT_WINSOCK(x) (x)
|
||||
# define SOCK_ERRNO() errno
|
||||
# define WAS_EAGAIN(e) ((e == EWOULDBLOCK) || (e == EAGAIN) || (e == EINPROGRESS) || (e == EALREADY))
|
||||
# define WAS_ECONNREFUSED(e) (e == ECONNREFUSED)
|
||||
|
@ -133,7 +133,7 @@ struct rktio_udp_t {
|
|||
};
|
||||
|
||||
|
||||
#if RKTIO_SYSTEM_WINDOWS
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
# define DECL_SOCK_FDSET(n) fd_set n[1]
|
||||
# define INIT_DECL_SOCK_FDSET(r, w, e) /* empty */
|
||||
# define INIT_DECL_SOCK_RD_FDSET(r) /* empty */
|
||||
|
@ -344,7 +344,7 @@ static void ghbn_lock(rktio_t *rktio)
|
|||
|
||||
static void ghbn_unlock(rktio_t *rktio)
|
||||
{
|
||||
ReleaseSemaphore(data->ghbn_lock, 1, NULL);
|
||||
ReleaseSemaphore(rktio->ghbn_lock, 1, NULL);
|
||||
}
|
||||
|
||||
static void ghbn_wait(rktio_t *rktio)
|
||||
|
@ -356,12 +356,12 @@ static void ghbn_wait(rktio_t *rktio)
|
|||
|
||||
static void ghbn_signal(rktio_t *rktio)
|
||||
{
|
||||
ReleaseSemaphore(data->ghbn_ready, 1, NULL);
|
||||
ReleaseSemaphore(rktio->ghbn_start, 1, NULL);
|
||||
}
|
||||
|
||||
static void ghbn_wait_exit(rktio_t *rktio)
|
||||
{
|
||||
WaitForSingleObject(rktio->th, INFINITE);
|
||||
WaitForSingleObject(rktio->ghbn_th, INFINITE);
|
||||
}
|
||||
|
||||
# else
|
||||
|
@ -416,7 +416,7 @@ static intptr_t getaddrinfo_in_thread(void *_data)
|
|||
ghbn_lock(rktio);
|
||||
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
ReleaseSemaphore(data->ready_sema, 1, NULL);
|
||||
ReleaseSemaphore(lookup->done_sema, 1, NULL);
|
||||
# else
|
||||
{
|
||||
long v = 1;
|
||||
|
@ -429,7 +429,7 @@ static intptr_t getaddrinfo_in_thread(void *_data)
|
|||
|
||||
if (lookup->mode == GHBN_ABANDONED) {
|
||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||
CloseHandle(data->ready_sema);
|
||||
CloseHandle(lookup->done_sema);
|
||||
# else
|
||||
rktio_reliably_close(lookup->done_fd[0]);
|
||||
# endif
|
||||
|
@ -464,10 +464,10 @@ static int ghbn_init(rktio_t *rktio)
|
|||
get_windows_error();
|
||||
return 0;
|
||||
}
|
||||
rktio->th = (HANDLE)_beginthreadex(NULL, 5000,
|
||||
win_getaddrinfo_in_thread,
|
||||
rktio, 0, &id);
|
||||
if (rktio->th == INVALID_HANDLE) {
|
||||
rktio->ghbn_th = (HANDLE)_beginthreadex(NULL, 5000,
|
||||
win_getaddrinfo_in_thread,
|
||||
rktio, 0, NULL);
|
||||
if (rktio->ghbn_th == INVALID_HANDLE_VALUE) {
|
||||
get_posix_error();
|
||||
return 0;
|
||||
}
|
||||
|
@ -881,8 +881,9 @@ int rktio_socket_close(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
return rktio_close(rktio, rfd);
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
UNREGISTER_SOCKET(rfd->sock);
|
||||
closesocket(rfd->sock);
|
||||
rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
|
||||
UNREGISTER_SOCKET(s);
|
||||
closesocket(s);
|
||||
free(rfd);
|
||||
|
||||
return 1;
|
||||
|
@ -895,8 +896,9 @@ void rktio_socket_forget(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
rktio_forget(rktio, rfd);
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
UNREGISTER_SOCKET(rfd->sock);
|
||||
closesocket(rfd->sock);
|
||||
rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
|
||||
UNREGISTER_SOCKET(s);
|
||||
closesocket(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -955,7 +957,7 @@ int rktio_socket_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
RKTIO_SOCK_FD_ZERO(exnfds);
|
||||
RKTIO_SOCK_FD_SET(s, exnfds);
|
||||
|
||||
sr = select(s + 1, readfdsfds, NULL, exnfds, &time);
|
||||
sr = select(s + 1, readfds, NULL, exnfds, &time);
|
||||
|
||||
if (sr == -1) {
|
||||
get_socket_error();
|
||||
|
@ -987,10 +989,11 @@ rktio_fd_t *rktio_socket_dup(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
return rktio_dup(rktio, rfd);
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
intptr_t nsocket;
|
||||
rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
|
||||
rktio_socket_t nsocket;
|
||||
intptr_t rc;
|
||||
WSAPROTOCOL_INFO protocolInfo;
|
||||
rc = WSADuplicateSocket(rfd->sock, GetCurrentProcessId(), &protocolInfo);
|
||||
rc = WSADuplicateSocket(s, GetCurrentProcessId(), &protocolInfo);
|
||||
if (rc) {
|
||||
get_socket_error();
|
||||
return NULL;
|
||||
|
@ -1001,7 +1004,7 @@ rktio_fd_t *rktio_socket_dup(rktio_t *rktio, rktio_fd_t *rfd)
|
|||
return NULL;
|
||||
}
|
||||
REGISTER_SOCKET(nsocket);
|
||||
return rktio_system_fd(nsocket, rfd->modes);
|
||||
return rktio_system_fd(rktio, nsocket, rktio_fd_modes(rktio, rfd));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1015,7 @@ intptr_t rktio_socket_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr
|
|||
|
||||
do {
|
||||
rn = recv(s, buffer, len, 0);
|
||||
} while ((rn == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||
} while ((rn == -1) && NOT_WINSOCK(errno == EINTR));
|
||||
|
||||
if (rn > 0)
|
||||
return rn;
|
||||
|
@ -1054,7 +1057,7 @@ static intptr_t do_socket_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, i
|
|||
do {
|
||||
sent = sendto(s, buffer, len, 0,
|
||||
RKTIO_AS_ADDRINFO(addr)->ai_addr, RKTIO_AS_ADDRINFO(addr)->ai_addrlen);
|
||||
} while ((sent == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||
} while ((sent == -1) && NOT_WINSOCK(errno == EINTR));
|
||||
if (sent >= 0)
|
||||
break;
|
||||
errid = SOCK_ERRNO();
|
||||
|
@ -1064,7 +1067,7 @@ static intptr_t do_socket_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, i
|
|||
} else {
|
||||
do {
|
||||
sent = send(s, buffer, len, 0);
|
||||
} while ((sent == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||
} while ((sent == -1) && NOT_WINSOCK(errno == EINTR));
|
||||
|
||||
if (sent == -1)
|
||||
errid = SOCK_ERRNO();
|
||||
|
@ -1206,7 +1209,7 @@ rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn)
|
|||
if (!rktio->windows_nt_or_later && !errid) {
|
||||
/* getsockopt() seems not to work in Windows 95, so use the
|
||||
result from select(), which seems to reliably detect an error condition */
|
||||
if (rktio_poll_connect_ready() == RKTIO_POLL_ERROR) {
|
||||
if (rktio_poll_connect_ready(rktio, conn) == RKTIO_POLL_ERROR) {
|
||||
errid = WSAECONNREFUSED; /* guess! */
|
||||
}
|
||||
}
|
||||
|
@ -1517,7 +1520,7 @@ static int do_poll_accept_ready(rktio_t *rktio, rktio_listener_t *listener, int
|
|||
|
||||
do {
|
||||
sr = select(mx + 1, RKTIO_SOCK_FDS(readfds), NULL, RKTIO_SOCK_FDS(exnfds), &time);
|
||||
} while ((sr == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||
} while ((sr == -1) && NOT_WINSOCK(errno == EINTR));
|
||||
|
||||
if (sr > 0) {
|
||||
if (report_which) {
|
||||
|
@ -1578,7 +1581,7 @@ rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener)
|
|||
|
||||
do {
|
||||
s = accept(ls, (struct sockaddr *)tcp_accept_addr, &l);
|
||||
} while ((s == -1) && (NOT_WINSOCK(errno) == EINTR));
|
||||
} while ((s == -1) && NOT_WINSOCK(errno == EINTR));
|
||||
|
||||
if (s != INVALID_SOCKET) {
|
||||
# ifdef RKTIO_SYSTEM_UNIX
|
||||
|
@ -1805,7 +1808,7 @@ rktio_length_and_addrinfo_t *rktio_udp_recvfrom(rktio_t *rktio, rktio_fd_t *rfd,
|
|||
/* => data truncated on Windows, which counts as success on Unix */
|
||||
rn = len;
|
||||
break;
|
||||
} else if (NOT_WINSOCK(errno) == EINTR) {
|
||||
} else if (NOT_WINSOCK(errno == EINTR)) {
|
||||
/* try again */
|
||||
} else if (WAS_EAGAIN(errno)) {
|
||||
/* no data available */
|
||||
|
|
|
@ -323,9 +323,7 @@ static rktio_poll_set_t *alloc_fdset_arrays()
|
|||
"max" fd counter, and 1 extra intger used to record "no
|
||||
sleeping" */
|
||||
|
||||
p = malloc((3 * (dynamic_fd_size + sizeof(intptr_t))) + sizeof(int));
|
||||
|
||||
*(int *)((char *)p + (3 * (dynamic_fd_size + sizeof(intptr_t)))) = 0;
|
||||
p = malloc(3 * (dynamic_fd_size + sizeof(intptr_t) + sizeof(int)));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -337,7 +335,7 @@ static void free_fdset_arrays(rktio_poll_set_t *fds)
|
|||
|
||||
rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos)
|
||||
{
|
||||
return (rktio_poll_set_t *)(((char *)fdarray) + (pos * (dynamic_fd_size + sizeof(intptr_t))));
|
||||
return (rktio_poll_set_t *)(((char *)fdarray) + (pos * (dynamic_fd_size + sizeof(intptr_t) + sizeof(int))));
|
||||
}
|
||||
|
||||
void rktio_fdzero(rktio_poll_set_t *fd)
|
||||
|
@ -347,12 +345,12 @@ void rktio_fdzero(rktio_poll_set_t *fd)
|
|||
|
||||
void rktio_poll_set_add_nosleep(rktio_t *rktio, rktio_poll_set_t *fds)
|
||||
{
|
||||
*(int *)((char *)fds + (3 * (dynamic_fd_size + sizeof(intptr_t)))) = 1;
|
||||
*(int *)((char *)fds + dynamic_fd_size + sizeof(intptr_t)) = 1;
|
||||
}
|
||||
|
||||
static int fdset_has_nosleep(rktio_poll_set_t *fds)
|
||||
{
|
||||
return *(int *)((char *)fds + (3 * (dynamic_fd_size + sizeof(intptr_t))));
|
||||
return *(int *)((char *)fds + dynamic_fd_size + sizeof(intptr_t));
|
||||
}
|
||||
|
||||
/* Continues below: */
|
||||
|
@ -364,13 +362,13 @@ static int fdset_has_nosleep(rktio_poll_set_t *fds)
|
|||
/* Windows variant */
|
||||
/*========================================================================*/
|
||||
|
||||
typedef struct {
|
||||
struct rktio_poll_set_t {
|
||||
SOCKET *sockets;
|
||||
|
||||
intptr_t added, alloc, last_alloc;
|
||||
|
||||
intptr_t num_handles, alloc_handles, last_alloc_handles;
|
||||
OS_SEMAPHORE_TYPE *handles;
|
||||
HANDLE *handles;
|
||||
|
||||
int *repost_sema;
|
||||
|
||||
|
@ -382,7 +380,9 @@ typedef struct {
|
|||
|
||||
HANDLE *combined_wait_array;
|
||||
intptr_t combined_len;
|
||||
} rktio_poll_set_t;
|
||||
};
|
||||
|
||||
static void reset_wait_array(rktio_poll_set_t *efd);
|
||||
|
||||
static void init_fdset_array(rktio_poll_set_t *fdarray, int count)
|
||||
{
|
||||
|
@ -421,18 +421,26 @@ static void init_fdset_array(rktio_poll_set_t *fdarray, int count)
|
|||
static rktio_poll_set_t *alloc_fdset_arrays()
|
||||
{
|
||||
rktio_poll_set_t *fdarray;
|
||||
if (count) {
|
||||
fdarray = calloc(3, sizeof(rktio_poll_set_t));
|
||||
init_fdset_array(fdarray, 3);
|
||||
} else
|
||||
fdarray = NULL;
|
||||
|
||||
fdarray = calloc(3, sizeof(rktio_poll_set_t));
|
||||
init_fdset_array(fdarray, 3);
|
||||
|
||||
return fdarray;
|
||||
}
|
||||
|
||||
static void free_fdset_arrays(rktio_poll_set_t *fds)
|
||||
{
|
||||
FIXME;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (fds[i].handles)
|
||||
free(fds[i].handles);
|
||||
if (fds[i].repost_sema)
|
||||
free(fds[i].repost_sema);
|
||||
if (fds[i].wait_array)
|
||||
free(fds[i].wait_array);
|
||||
}
|
||||
free(fds);
|
||||
}
|
||||
|
||||
static void reset_wait_array(rktio_poll_set_t *efd)
|
||||
|
@ -473,7 +481,7 @@ void rktio_fdset(rktio_poll_set_t *fd, int n)
|
|||
if (fd->added >= fd->last_alloc) {
|
||||
int na;
|
||||
na = next_size(fd->last_alloc);
|
||||
efd->last_alloc = na;
|
||||
fd->last_alloc = na;
|
||||
}
|
||||
if (fd->added >= fd->alloc) {
|
||||
SOCKET *naya;
|
||||
|
@ -502,9 +510,9 @@ int rktio_fdisset(rktio_poll_set_t *fd, int n)
|
|||
void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds)
|
||||
{
|
||||
int i;
|
||||
for (i = src_fd->added; i--; ) {
|
||||
if (stv_fd->sockets[i] != INVALID_SOCKET)
|
||||
rktio_fdset(fds, src_fd->sockets[i]);
|
||||
for (i = src_fds->added; i--; ) {
|
||||
if (src_fds->sockets[i] != INVALID_SOCKET)
|
||||
rktio_fdset(fds, src_fds->sockets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,7 +528,7 @@ int rktio_get_fd_limit(rktio_poll_set_t *fds)
|
|||
void rktio_poll_set_add_handle(HANDLE h, rktio_poll_set_t *fds, int repost)
|
||||
{
|
||||
rktio_poll_set_t *efd = fds;
|
||||
OS_SEMAPHORE_TYPE *hs;
|
||||
HANDLE *hs;
|
||||
int i, new_i, *rps;
|
||||
|
||||
if (efd->num_handles == efd->last_alloc_handles) {
|
||||
|
@ -733,10 +741,7 @@ void rktio_collapse_win_fd(rktio_poll_set_t *fds)
|
|||
|
||||
static rktio_poll_set_t *alloc_fdset_arrays()
|
||||
{
|
||||
void *p;
|
||||
p = malloc((3 * sizeof(fd_set)) + sizeof(int));
|
||||
*(int *)((char *)p + (3 * sizeof(fd_set))) = 0;
|
||||
return p;
|
||||
return malloc(3 * sizeof(rktio_poll_set_t));
|
||||
}
|
||||
|
||||
static void free_fdset_arrays(rktio_poll_set_t *fds)
|
||||
|
@ -752,16 +757,17 @@ rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos)
|
|||
void rktio_fdzero(rktio_poll_set_t *fd)
|
||||
{
|
||||
FD_ZERO(&(fd)->data);
|
||||
fd->nosleep = 0;
|
||||
}
|
||||
|
||||
void rktio_poll_set_add_nosleep(rktio_t *rktio, rktio_poll_set_t *fds)
|
||||
{
|
||||
*(int *)((char *)fds + (3 * sizeof(fd_set))) = 1;
|
||||
fds->nosleep = 1;
|
||||
}
|
||||
|
||||
static int fdset_has_nosleep(rktio_poll_set_t *fds)
|
||||
{
|
||||
return *(int *)((char *)fds + (3 * sizeof(fd_set)));
|
||||
return fds->nosleep;
|
||||
}
|
||||
|
||||
#define USE_PLAIN_FDS_SET_OPS
|
||||
|
@ -813,6 +819,8 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds)
|
|||
*p |= *sp;
|
||||
}
|
||||
}
|
||||
if (fdset_has_nosleep(src_fds))
|
||||
rktio_poll_set_add_nosleep(NULL, fds);
|
||||
}
|
||||
|
||||
void rktio_clean_fd_set(rktio_poll_set_t *fds)
|
||||
|
@ -1000,9 +1008,10 @@ void rktio_wait_until_signal_received(rktio_t *rktio)
|
|||
|
||||
/****************** Windows cleanup *****************/
|
||||
|
||||
#if RKTIO_SYSTEM_WINDOWS
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
|
||||
static void clean_up_wait(intptr_t result, OS_SEMAPHORE_TYPE *array,
|
||||
static void clean_up_wait(rktio_t *rktio,
|
||||
intptr_t result, HANDLE *array,
|
||||
int *rps, int count)
|
||||
{
|
||||
if ((result >= (intptr_t)WAIT_OBJECT_0) && (result < (intptr_t)WAIT_OBJECT_0 + count)) {
|
||||
|
@ -1012,7 +1021,7 @@ static void clean_up_wait(intptr_t result, OS_SEMAPHORE_TYPE *array,
|
|||
}
|
||||
|
||||
/* Clear out break semaphore */
|
||||
WaitForSingleObject((HANDLE)scheme_break_semaphore, 0);
|
||||
WaitForSingleObject(rktio->break_semaphore, 0);
|
||||
}
|
||||
|
||||
static int made_progress;
|
||||
|
@ -1214,8 +1223,7 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_
|
|||
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 (fds->wait_event_mask && GetQueueStatus(fds->wait_event_mask)) {
|
||||
if (!made_progress) {
|
||||
/* Ok, we've gone around at least once. */
|
||||
if (max_sleep_time < 0x20000000)
|
||||
|
@ -1248,10 +1256,9 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_
|
|||
msec = INFINITE;
|
||||
}
|
||||
|
||||
result = MsgWaitForMultipleObjects(count, array, FALSE, msec,
|
||||
SCHEME_INT_VAL(((win_extended_fd_set *)fds)->wait_event_mask));
|
||||
result = MsgWaitForMultipleObjects(count, array, FALSE, msec, fds->wait_event_mask);
|
||||
}
|
||||
clean_up_wait(result, array, rps, rcount);
|
||||
clean_up_wait(rktio, result, array, rps, rcount);
|
||||
scheme_collapse_win_fd(fds); /* cleans up */
|
||||
|
||||
return;
|
||||
|
|
|
@ -10,16 +10,14 @@
|
|||
#endif
|
||||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef RKTIO_USE_PTHREADS
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(OS_X) || defined(__NetBSD__) \
|
||||
|| defined(__NetBSD__) || defined(__OpenBSD__) \
|
||||
|| defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
|
||||
|| defined(__DragonFly__) || defined(__QNX__)
|
||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(RKTIO_STATIC_FDSET_SIZE)
|
||||
# define USE_DYNAMIC_FDSET_SIZE
|
||||
#endif
|
||||
|
||||
|
@ -81,6 +79,7 @@ struct rktio_t {
|
|||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
uintptr_t process_children_msecs;
|
||||
HANDLE process_job_object;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY_SYSCALL
|
||||
|
@ -134,7 +133,10 @@ int rktio_fdisset(rktio_poll_set_t *fd, int n);
|
|||
#else
|
||||
|
||||
#include <sys/select.h>
|
||||
struct rktio_poll_set_t { fd_set data; };
|
||||
struct rktio_poll_set_t { fd_set data; int nosleep; };
|
||||
|
||||
/* Need "far" call to fdzero to deal with `nosleep`: */
|
||||
void rktio_fdzero(rktio_poll_set_t *fd);
|
||||
|
||||
# define DECL_FDSET(n, c) rktio_poll_set_t n[c]
|
||||
# define INIT_DECL_FDSET(r, w, e) /* empty */
|
||||
|
@ -145,7 +147,7 @@ struct rktio_poll_set_t { fd_set data; };
|
|||
# define RKTIO_FDS(p) (&(p)->data)
|
||||
|
||||
# define RKTIO_GET_FDSET(p, n) ((p)+(n))
|
||||
# define RKTIO_FD_ZERO(p) FD_ZERO(RKTIO_FDS(p))
|
||||
# define RKTIO_FD_ZERO(p) rktio_fdzero(p)
|
||||
# define RKTIO_FD_SET(n, p) FD_SET(n, RKTIO_FDS(p))
|
||||
# define RKTIO_FD_CLR(n, p) FD_CLR(n, RKTIO_FDS(p))
|
||||
# define RKTIO_FD_ISSET(n, p) FD_ISSET(n, RKTIO_FDS(p))
|
||||
|
@ -251,3 +253,7 @@ void rktio_reliably_close(intptr_t s);
|
|||
void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
|
||||
void rktio_stop_fs_change(rktio_t *rktio);
|
||||
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
void rktio_useless_wide();
|
||||
#endif
|
||||
|
|
|
@ -520,8 +520,8 @@ static void do_group_signal_fds()
|
|||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
# ifndef USE_CYGWIN_PIPES
|
||||
# define _EXTRA_PIPE_ARGS
|
||||
static int MyPipe(intptr_t *ph, int near_index)
|
||||
# define _EXTRA_PIPE_ARGS , rktio
|
||||
static int MyPipe(intptr_t *ph, int near_index, rktio_t *rktio)
|
||||
{
|
||||
HANDLE r, w;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
|
@ -756,10 +756,10 @@ static void collect_process_time(rktio_t *rktio, DWORD w, rktio_process_t *sp)
|
|||
if ((w != STILL_ACTIVE) && !sp->got_time) {
|
||||
FILETIME cr, ex, kr, us;
|
||||
if (GetProcessTimes(sp->handle, &cr, &ex, &kr, &us)) {
|
||||
_int64 v;
|
||||
__int64 v;
|
||||
uintptr_t msecs;
|
||||
v = ((((_int64)kr.dwHighDateTime << 32) + kr.dwLowDateTime)
|
||||
+ (((_int65)us.dwHighDateTime << 32) + us.dwLowDateTime));
|
||||
v = ((((__int64)kr.dwHighDateTime << 32) + kr.dwLowDateTime)
|
||||
+ (((__int64)us.dwHighDateTime << 32) + us.dwLowDateTime));
|
||||
msecs = (uintptr_t)(v / 10000);
|
||||
|
||||
rktio->process_children_msecs += msecs;
|
||||
|
@ -830,8 +830,7 @@ void rktio_poll_add_process(rktio_t *rktio, rktio_process_t *sp, rktio_poll_set_
|
|||
}
|
||||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
HANDLE sci = sp->handle;
|
||||
rktio_poll_set_add_handle(rktio, handle, fds, 0);
|
||||
rktio_poll_set_add_handle(rktio, sp->handle, fds, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1005,7 +1004,7 @@ void rktio_process_forget(rktio_t *rktio, rktio_process_t *sp)
|
|||
#endif
|
||||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
CloseHandle(subproc->handle);
|
||||
CloseHandle(sp->handle);
|
||||
#endif
|
||||
|
||||
free(sp);
|
||||
|
@ -1023,10 +1022,10 @@ int rktio_process_init(rktio_t *rktio)
|
|||
void rktio_process_deinit(rktio_t *rktio)
|
||||
{
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
if (process_job_object) {
|
||||
TerminateJobObject((HANDLE)process_job_object, 1);
|
||||
CloseHandle((HANDLE)process_job_object);
|
||||
process_job_object = NULL;
|
||||
if (rktio->process_job_object) {
|
||||
TerminateJobObject(rktio->process_job_object, 1);
|
||||
CloseHandle(rktio->process_job_object);
|
||||
rktio->process_job_object = NULL;
|
||||
}
|
||||
#endif
|
||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(CENTRALIZED_SIGCHILD)
|
||||
|
@ -1096,15 +1095,16 @@ static char *cmdline_protect(char *s)
|
|||
return strdup(s);
|
||||
}
|
||||
|
||||
static intptr_t do_spawnv(char *command, const char * const *argv,
|
||||
static intptr_t do_spawnv(rktio_t *rktio,
|
||||
const char *command, const char * const *argv,
|
||||
int exact_cmdline, intptr_t sin, intptr_t sout, intptr_t serr, int *pid,
|
||||
int new_process_group, int chain_termination_here_to_child,
|
||||
void *env, char *wd)
|
||||
void *env, const char *wd)
|
||||
{
|
||||
int i, l, len = 0, use_jo;
|
||||
intptr_t cr_flag;
|
||||
char *cmdline;
|
||||
wchar_t *cmdline_w;
|
||||
wchar_t *cmdline_w, *wd_w;
|
||||
STARTUPINFOW startup;
|
||||
PROCESS_INFORMATION info;
|
||||
|
||||
|
@ -1151,14 +1151,14 @@ static intptr_t do_spawnv(char *command, const char * const *argv,
|
|||
if (use_jo) {
|
||||
/* Use a job object to ensure that the new process will be terminated
|
||||
if this process ends for any reason (including a crash) */
|
||||
if (!process_job_object) {
|
||||
GC_CAN_IGNORE JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
|
||||
if (!rktio->process_job_object) {
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
|
||||
|
||||
process_job_object = (void*)CreateJobObject(NULL, NULL);
|
||||
rktio->process_job_object = CreateJobObject(NULL, NULL);
|
||||
|
||||
memset(&jeli, 0, sizeof(jeli));
|
||||
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
SetInformationJobObject((HANDLE)process_job_object,
|
||||
SetInformationJobObject(rktio->process_job_object,
|
||||
JobObjectExtendedLimitInformation,
|
||||
&jeli,
|
||||
sizeof(jeli));
|
||||
|
@ -1169,19 +1169,22 @@ static intptr_t do_spawnv(char *command, const char * const *argv,
|
|||
cmdline_w = WIDE_PATH_copy(cmdline);
|
||||
if (!exact_cmdline)
|
||||
free(cmdline);
|
||||
wd_w = WIDE_PATH_copy(wd);
|
||||
|
||||
if (CreateProcessW(WIDE_PATH_temp(command), cmdline_w,
|
||||
NULL, NULL, 1 /*inherit*/,
|
||||
cr_flag, env, WIDE_PATH_COPY(wd),
|
||||
cr_flag, env, wd_w,
|
||||
&startup, &info)) {
|
||||
if (use_jo)
|
||||
AssignProcessToJobObject((HANDLE)process_job_object, info.hProcess);
|
||||
AssignProcessToJobObject(rktio->process_job_object, info.hProcess);
|
||||
CloseHandle(info.hThread);
|
||||
*pid = info.dwProcessId;
|
||||
free(cmdline_w);
|
||||
free(wd_w);
|
||||
return (intptr_t)info.hProcess;
|
||||
} else {
|
||||
free(cmdline_w);
|
||||
free(wd_w);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1242,10 +1245,10 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
System_Child *sc;
|
||||
# endif
|
||||
int fork_errno = 0;
|
||||
void *env;
|
||||
#else
|
||||
void *sc = 0;
|
||||
#endif
|
||||
void *env;
|
||||
rktio_process_t *subproc;
|
||||
#if defined(RKTIO_SYSTEM_WINDOWS)
|
||||
intptr_t spawn_status;
|
||||
|
@ -1295,7 +1298,6 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
}
|
||||
|
||||
env = rktio_envvars_to_block(rktio, envvars);
|
||||
|
||||
|
||||
#if defined(RKTIO_SYSTEM_WINDOWS)
|
||||
|
||||
|
@ -1311,7 +1313,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
{
|
||||
char **new_argv;
|
||||
|
||||
if (!exact_cmdline) {
|
||||
if (!windows_exact_cmdline) {
|
||||
/* protect spaces, etc. in the arguments: */
|
||||
new_argv = malloc(sizeof(char *) * argc);
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
@ -1320,8 +1322,9 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
argv = new_argv;
|
||||
}
|
||||
|
||||
spawn_status = do_spawnv(command, (const char * const *)new_argv,
|
||||
exact_cmdline,
|
||||
spawn_status = do_spawnv(rktio,
|
||||
command, (const char * const *)new_argv,
|
||||
windows_exact_cmdline,
|
||||
to_subprocess[0],
|
||||
from_subprocess[1],
|
||||
err_subprocess[1],
|
||||
|
@ -1330,7 +1333,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
windows_chain_termination_to_child,
|
||||
env, current_directory);
|
||||
|
||||
if (!exact_cmdline) {
|
||||
if (!windows_exact_cmdline) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
free(argv[i]);
|
||||
}
|
||||
|
@ -1576,6 +1579,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
static void close_fds_after_fork(int skip1, int skip2, int skip3)
|
||||
{
|
||||
int i;
|
||||
|
@ -1596,4 +1600,4 @@ static void close_fds_after_fork(int skip1, int skip2, int skip3)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
/* For converting byte strings to and from "wide" strings on Windows. */
|
||||
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
/* To avoid complaints about an empty object file */
|
||||
void rktio_useless_wide() { }
|
||||
#endif
|
||||
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
|
||||
#include <inttypes.h>
|
||||
|
|
Loading…
Reference in New Issue
Block a user