aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/boot/boot.janet5
-rw-r--r--src/core/io.c32
-rw-r--r--src/include/janet.h1
-rw-r--r--test/suite-ev2.janet17
4 files changed, 45 insertions, 10 deletions
diff --git a/src/boot/boot.janet b/src/boot/boot.janet
index 370a774f..8d624e52 100644
--- a/src/boot/boot.janet
+++ b/src/boot/boot.janet
@@ -4014,7 +4014,7 @@
"handler not supported for :datagram servers")
(def s (net/listen host port type no-reuse))
(if handler
- (ev/go (fn [] (net/accept-loop s handler))))
+ (ev/go (fn :net/server-handler [] (net/accept-loop s handler))))
s))
###
@@ -4670,8 +4670,7 @@
(defn- run-main
[env subargs arg]
- (when-let [entry (in env 'main)
- main (or (get entry :value) (in (get entry :ref) 0))]
+ (when-let [main (module/value env 'main)]
(def guard (if (get env :debug) :ydt :y))
(defn wrap-main [&]
(main ;subargs))
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) {
diff --git a/src/include/janet.h b/src/include/janet.h
index e1a5c79a..ac2e3019 100644
--- a/src/include/janet.h
+++ b/src/include/janet.h
@@ -1281,6 +1281,7 @@ typedef struct JanetFile JanetFile;
struct JanetFile {
FILE *file;
int32_t flags;
+ size_t vbufsize;
};
/* For janet_try and janet_restore */
diff --git a/test/suite-ev2.janet b/test/suite-ev2.janet
index c94a2d86..caa323a4 100644
--- a/test/suite-ev2.janet
+++ b/test/suite-ev2.janet
@@ -84,4 +84,21 @@
(assert-error "cannot schedule non-new fiber"
(ev/go f))
+# IO file copying
+(os/mkdir "tmp")
+(def f-original (file/open "tmp/out.txt" :wb))
+(xprin f-original "hello\n")
+(file/flush f-original)
+(ev/do-thread
+ # Closes a COPY of the original file, otherwise we get a user-after-close file descriptor
+ (:close f-original))
+(def g-original (file/open "tmp/out2.txt" :wb))
+(xprin g-original "world1\n")
+(xprin f-original "world2\n")
+(:close f-original)
+(xprin g-original "abc\n")
+(:close g-original)
+(assert (deep= @"hello\nworld2\n" (slurp "tmp/out.txt")) "file threading 1")
+(assert (deep= @"world1\nabc\n" (slurp "tmp/out2.txt")) "file threading 2")
+
(end-suite)