diff options
Diffstat (limited to 'src/core/io.c')
| -rw-r--r-- | src/core/io.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/core/io.c b/src/core/io.c index 43996526..274f9eeb 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -109,10 +109,11 @@ static int32_t checkflags(const uint8_t *str) { return flags; } -static void *makef(FILE *f, int32_t flags) { +static void *makef(FILE *f, int32_t flags, size_t bufsize) { JanetFile *iof = (JanetFile *) janet_abstract(&janet_file_type, sizeof(JanetFile)); iof->file = f; iof->flags = flags; + iof->vbufsize = bufsize; #if !(defined(JANET_WINDOWS) || defined(JANET_PLAN9)) /* While we would like fopen to set cloexec by default (like O_CLOEXEC) with the e flag, that is * not standard. */ @@ -164,6 +165,7 @@ JANET_CORE_FN(cfun_io_fopen, flags = JANET_FILE_READ; } FILE *f = fopen((const char *)fname, (const char *)fmode); + size_t bufsize = BUFSIZ; if (f != NULL) { #if !(defined(JANET_WINDOWS) || defined(JANET_PLAN9)) struct stat st; @@ -173,7 +175,7 @@ JANET_CORE_FN(cfun_io_fopen, janet_panicf("cannot open directory: %s", fname); } #endif - size_t bufsize = janet_optsize(argv, argc, 2, BUFSIZ); + bufsize = janet_optsize(argv, argc, 2, BUFSIZ); if (bufsize != BUFSIZ) { int result = setvbuf(f, NULL, bufsize ? _IOFBF : _IONBF, bufsize); if (result) { @@ -181,7 +183,7 @@ JANET_CORE_FN(cfun_io_fopen, } } } - return f ? janet_makefile(f, flags) + return f ? janet_wrap_abstract(makef(f, flags, bufsize)) : (flags & JANET_FILE_NONIL) ? (janet_panicf("failed to open file %s: %s", fname, janet_strerror(errno)), janet_wrap_nil()) : janet_wrap_nil(); } @@ -410,12 +412,23 @@ static void io_file_marshal(void *p, JanetMarshalContext *ctx) { JanetFile *iof = (JanetFile *)p; if (ctx->flags & JANET_MARSHAL_UNSAFE) { janet_marshal_abstract(ctx, p); + int fno = -1; #ifdef JANET_WINDOWS - janet_marshal_int(ctx, _fileno(iof->file)); + if (iof->flags & JANET_FILE_NOT_CLOSEABLE) { + fno = _fileno(iof->file); + } else { + fno = _dup(_fileno(iof->file)); + } #else - janet_marshal_int(ctx, fileno(iof->file)); + if (iof->flags & JANET_FILE_NOT_CLOSEABLE) { + fno = fileno(iof->file); + } else { + fno = dup(fileno(iof->file)); + } #endif + janet_marshal_int(ctx, fno); janet_marshal_int(ctx, iof->flags); + janet_marshal_size(ctx, iof->vbufsize); } else { janet_panic("cannot marshal file in safe mode"); } @@ -444,6 +457,11 @@ static void *io_file_unmarshal(JanetMarshalContext *ctx) { } else { iof->flags = flags; } + iof->vbufsize = janet_unmarshal_size(ctx); + if (iof->vbufsize != BUFSIZ) { + int result = setvbuf(iof->file, NULL, iof->vbufsize ? _IOFBF : _IONBF, iof->vbufsize); + janet_assert(!result, "unmarshal setvbuf"); + } return iof; } else { janet_panic("cannot unmarshal file in safe mode"); @@ -785,11 +803,11 @@ FILE *janet_getfile(const Janet *argv, int32_t n, int32_t *flags) { } JanetFile *janet_makejfile(FILE *f, int32_t flags) { - return makef(f, flags); + return makef(f, flags, BUFSIZ); } Janet janet_makefile(FILE *f, int32_t flags) { - return janet_wrap_abstract(makef(f, flags)); + return janet_wrap_abstract(makef(f, flags, BUFSIZ)); } JanetAbstract janet_checkfile(Janet j) { |
