Skip to content

Commit 92a852f

Browse files
committed
Add ev/to-stream.
This function is symmetrical to ev/to-file and can convert a blocking file to a stream (with caveats).
1 parent 647e218 commit 92a852f

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
All notable changes to this project will be documented in this file.
33

44
## Unreleased - ???
5+
- Add `ev/to-stream`
56
- Make `ffi/write` append to a buffer instead of insert at 0 by default.
67
- Add `os/getpid` to get the current process id.
78
- Add `:out` option to `os/spawn` to be able to redirect stderr to stdout with pipes.

src/core/ev.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,21 +353,22 @@ JanetStream *janet_stream(JanetHandle handle, uint32_t flags, const JanetMethod
353353

354354
static void janet_stream_close_impl(JanetStream *stream) {
355355
stream->flags |= JANET_STREAM_CLOSED;
356+
int canclose = !(stream->flags & JANET_STREAM_NOT_CLOSEABLE);
356357
#ifdef JANET_WINDOWS
357358
if (stream->handle != INVALID_HANDLE_VALUE) {
358359
#ifdef JANET_NET
359360
if (stream->flags & JANET_STREAM_SOCKET) {
360-
closesocket((SOCKET) stream->handle);
361+
if (canclose) closesocket((SOCKET) stream->handle);
361362
} else
362363
#endif
363364
{
364-
CloseHandle(stream->handle);
365+
if (canclose) CloseHandle(stream->handle);
365366
}
366367
stream->handle = INVALID_HANDLE_VALUE;
367368
}
368369
#else
369370
if (stream->handle != -1) {
370-
close(stream->handle);
371+
if (canclose) close(stream->handle);
371372
stream->handle = -1;
372373
#ifdef JANET_EV_POLL
373374
uint32_t i = stream->index;
@@ -3486,6 +3487,36 @@ JANET_CORE_FN(janet_cfun_ev_all_tasks,
34863487
return janet_wrap_array(array);
34873488
}
34883489

3490+
JANET_CORE_FN(janet_cfun_to_stream,
3491+
"(ev/to-stream file)",
3492+
"Convert a core/file to a core/stream. On POSIX operating systems, this will mark "
3493+
"the underlying open file description as non-blocking.") {
3494+
janet_fixarity(argc, 1);
3495+
int32_t flags = 0;
3496+
int32_t stream_flags = 0;
3497+
FILE *file = janet_getfile(argv, 0, &flags);
3498+
if (flags & JANET_FILE_READ) stream_flags |= JANET_STREAM_READABLE;
3499+
if (flags & JANET_FILE_WRITE) stream_flags |= JANET_STREAM_WRITABLE;
3500+
if (flags & JANET_FILE_NOT_CLOSEABLE) stream_flags |= JANET_STREAM_NOT_CLOSEABLE;
3501+
if (flags & JANET_FILE_CLOSED) janet_panic("file is closed");
3502+
#ifdef JANET_WINDOWS
3503+
int fno = _fileno(file);
3504+
int dupped_fno = _dup(fno);
3505+
if (dupped_fno == -1) janet_panic(janet_strerror(errno));
3506+
JanetStream *stream = janet_stream(_get_osfhandle(dupped_fno), stream_flags, NULL);
3507+
#else
3508+
int handle = fileno(file);
3509+
int dupped_handle = 0;
3510+
int status = 0;
3511+
RETRY_EINTR(dupped_handle, dup(handle));
3512+
if (status == -1) janet_panic(janet_strerror(errno));
3513+
RETRY_EINTR(status, fcntl(dupped_handle, F_SETFL, O_NONBLOCK));
3514+
if (status == -1) janet_panic(janet_strerror(errno));
3515+
JanetStream *stream = janet_stream(dupped_handle, stream_flags, NULL);
3516+
#endif
3517+
return janet_wrap_abstract(stream);
3518+
}
3519+
34893520
void janet_lib_ev(JanetTable *env) {
34903521
JanetRegExt ev_cfuns_ext[] = {
34913522
JANET_CORE_REG("ev/give", cfun_channel_push),
@@ -3517,6 +3548,7 @@ void janet_lib_ev(JanetTable *env) {
35173548
JANET_CORE_REG("ev/release-rlock", janet_cfun_rwlock_read_release),
35183549
JANET_CORE_REG("ev/release-wlock", janet_cfun_rwlock_write_release),
35193550
JANET_CORE_REG("ev/to-file", janet_cfun_to_file),
3551+
JANET_CORE_REG("ev/to-stream", janet_cfun_to_stream),
35203552
JANET_CORE_REG("ev/all-tasks", janet_cfun_ev_all_tasks),
35213553
JANET_REG_END
35223554
};

src/include/janet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ typedef void *JanetAbstract;
596596
#define JANET_STREAM_WRITABLE 0x400
597597
#define JANET_STREAM_ACCEPTABLE 0x800
598598
#define JANET_STREAM_UDPSERVER 0x1000
599+
#define JANET_STREAM_NOT_CLOSEABLE 0x2000
599600
#define JANET_STREAM_TOCLOSE 0x10000
600601

601602
typedef enum {

0 commit comments

Comments
 (0)