Skip to content

Commit e2f61ac

Browse files
authored
Support reading script source from stdin in qjs (#947)
Replace js_load_file with something that doesn't choke on special files and don't call realpath(3) on /dev files because that doesn't work. Now `echo 'print("hello")' | qjs /dev/stdin` works. Fixes: #945
1 parent caf3005 commit e2f61ac

File tree

2 files changed

+29
-35
lines changed

2 files changed

+29
-35
lines changed

qjs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
120120
val = JS_Eval(ctx, buf, buf_len, filename,
121121
eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
122122
if (!JS_IsException(val)) {
123-
use_realpath = (*filename != '<'); // ex. "<cmdline>"
123+
// ex. "<cmdline>" pr "/dev/stdin"
124+
use_realpath =
125+
!(*filename == '<' || !strncmp(filename, "/dev/", 5));
124126
if (js_module_set_import_meta(ctx, val, use_realpath, true) < 0) {
125127
js_std_dump_error(ctx);
126128
ret = -1;

quickjs-libc.c

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -418,45 +418,37 @@ static JSValue js_printf_internal(JSContext *ctx,
418418
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
419419
{
420420
FILE *f;
421-
uint8_t *buf;
422-
size_t buf_len;
423-
long lret;
421+
size_t n, len;
422+
uint8_t *p, *buf, tmp[8192];
424423

425424
f = fopen(filename, "rb");
426425
if (!f)
427426
return NULL;
428-
if (fseek(f, 0, SEEK_END) < 0)
429-
goto fail;
430-
lret = ftell(f);
431-
if (lret < 0)
432-
goto fail;
433-
/* XXX: on Linux, ftell() return LONG_MAX for directories */
434-
if (lret == LONG_MAX) {
435-
errno = EISDIR;
436-
goto fail;
437-
}
438-
buf_len = lret;
439-
if (fseek(f, 0, SEEK_SET) < 0)
440-
goto fail;
441-
if (ctx)
442-
buf = js_malloc(ctx, buf_len + 1);
443-
else
444-
buf = malloc(buf_len + 1);
445-
if (!buf)
446-
goto fail;
447-
if (fread(buf, 1, buf_len, f) != buf_len) {
448-
errno = EIO;
449-
if (ctx)
450-
js_free(ctx, buf);
451-
else
452-
free(buf);
453-
fail:
454-
fclose(f);
455-
return NULL;
456-
}
457-
buf[buf_len] = '\0';
427+
buf = NULL;
428+
len = 0;
429+
do {
430+
n = fread(tmp, 1, sizeof(tmp), f);
431+
if (ctx) {
432+
p = js_realloc(ctx, buf, len + n + 1);
433+
} else {
434+
p = realloc(buf, len + n + 1);
435+
}
436+
if (!p) {
437+
if (ctx) {
438+
js_free(ctx, buf);
439+
} else {
440+
free(buf);
441+
}
442+
fclose(f);
443+
return NULL;
444+
}
445+
memcpy(&p[len], tmp, n);
446+
buf = p;
447+
len += n;
448+
buf[len] = '\0';
449+
} while (n == sizeof(tmp));
458450
fclose(f);
459-
*pbuf_len = buf_len;
451+
*pbuf_len = len;
460452
return buf;
461453
}
462454

0 commit comments

Comments
 (0)