mirror of
https://github.com/janet-lang/janet
synced 2024-12-28 17:30:31 +00:00
Address #224 - Exposed file flags in janet.h
A caller can check if a file is closed with if (flags & JANET_FILE_CLOSED) ...
This commit is contained in:
parent
eca42e98f6
commit
56784a34a1
@ -36,16 +36,6 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IO_WRITE 1
|
|
||||||
#define IO_READ 2
|
|
||||||
#define IO_APPEND 4
|
|
||||||
#define IO_UPDATE 8
|
|
||||||
#define IO_NOT_CLOSEABLE 16
|
|
||||||
#define IO_CLOSED 32
|
|
||||||
#define IO_BINARY 64
|
|
||||||
#define IO_SERIALIZABLE 128
|
|
||||||
#define IO_PIPED 256
|
|
||||||
|
|
||||||
typedef struct IOFile IOFile;
|
typedef struct IOFile IOFile;
|
||||||
struct IOFile {
|
struct IOFile {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
@ -78,13 +68,13 @@ static int checkflags(const uint8_t *str) {
|
|||||||
janet_panicf("invalid flag %c, expected w, a, or r", *str);
|
janet_panicf("invalid flag %c, expected w, a, or r", *str);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
flags |= IO_WRITE;
|
flags |= JANET_FILE_WRITE;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
flags |= IO_APPEND;
|
flags |= JANET_FILE_APPEND;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
flags |= IO_READ;
|
flags |= JANET_FILE_READ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 1; i < len; i++) {
|
for (i = 1; i < len; i++) {
|
||||||
@ -93,12 +83,12 @@ static int checkflags(const uint8_t *str) {
|
|||||||
janet_panicf("invalid flag %c, expected + or b", str[i]);
|
janet_panicf("invalid flag %c, expected + or b", str[i]);
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
if (flags & IO_UPDATE) return -1;
|
if (flags & JANET_FILE_UPDATE) return -1;
|
||||||
flags |= IO_UPDATE;
|
flags |= JANET_FILE_UPDATE;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if (flags & IO_BINARY) return -1;
|
if (flags & JANET_FILE_BINARY) return -1;
|
||||||
flags |= IO_BINARY;
|
flags |= JANET_FILE_BINARY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,10 +122,10 @@ static Janet cfun_io_popen(int32_t argc, Janet *argv) {
|
|||||||
!(fmode[0] == 'r' || fmode[0] == 'w')) {
|
!(fmode[0] == 'r' || fmode[0] == 'w')) {
|
||||||
janet_panicf("invalid file mode :%S, expected :r or :w", fmode);
|
janet_panicf("invalid file mode :%S, expected :r or :w", fmode);
|
||||||
}
|
}
|
||||||
flags = IO_PIPED | (fmode[0] == 'r' ? IO_READ : IO_WRITE);
|
flags = JANET_FILE_PIPED | (fmode[0] == 'r' ? JANET_FILE_READ : JANET_FILE_WRITE);
|
||||||
} else {
|
} else {
|
||||||
fmode = (const uint8_t *)"r";
|
fmode = (const uint8_t *)"r";
|
||||||
flags = IO_PIPED | IO_READ;
|
flags = JANET_FILE_PIPED | JANET_FILE_READ;
|
||||||
}
|
}
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
@ -158,7 +148,7 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) {
|
|||||||
flags = checkflags(fmode);
|
flags = checkflags(fmode);
|
||||||
} else {
|
} else {
|
||||||
fmode = (const uint8_t *)"r";
|
fmode = (const uint8_t *)"r";
|
||||||
flags = IO_READ;
|
flags = JANET_FILE_READ;
|
||||||
}
|
}
|
||||||
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
||||||
return f ? makef(f, flags) : janet_wrap_nil();
|
return f ? makef(f, flags) : janet_wrap_nil();
|
||||||
@ -174,7 +164,7 @@ static Janet cfun_io_fdopen(int32_t argc, Janet *argv) {
|
|||||||
flags = checkflags(fmode);
|
flags = checkflags(fmode);
|
||||||
} else {
|
} else {
|
||||||
fmode = (const uint8_t *)"r";
|
fmode = (const uint8_t *)"r";
|
||||||
flags = IO_READ;
|
flags = JANET_FILE_READ;
|
||||||
}
|
}
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
#define fdopen _fdopen
|
#define fdopen _fdopen
|
||||||
@ -186,7 +176,7 @@ static Janet cfun_io_fdopen(int32_t argc, Janet *argv) {
|
|||||||
static Janet cfun_io_fileno(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fileno(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED)
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
janet_panic("file is closed");
|
janet_panic("file is closed");
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
#define fileno _fileno
|
#define fileno _fileno
|
||||||
@ -196,7 +186,7 @@ static Janet cfun_io_fileno(int32_t argc, Janet *argv) {
|
|||||||
|
|
||||||
/* Read up to n bytes into buffer. */
|
/* Read up to n bytes into buffer. */
|
||||||
static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
|
static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
|
||||||
if (!(iof->flags & (IO_READ | IO_UPDATE)))
|
if (!(iof->flags & (JANET_FILE_READ | JANET_FILE_UPDATE)))
|
||||||
janet_panic("file is not readable");
|
janet_panic("file is not readable");
|
||||||
janet_buffer_extra(buffer, nBytesMax);
|
janet_buffer_extra(buffer, nBytesMax);
|
||||||
size_t ntoread = nBytesMax;
|
size_t ntoread = nBytesMax;
|
||||||
@ -210,7 +200,7 @@ static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
|
|||||||
static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
||||||
janet_arity(argc, 2, 3);
|
janet_arity(argc, 2, 3);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED) janet_panic("file is closed");
|
if (iof->flags & JANET_FILE_CLOSED) janet_panic("file is closed");
|
||||||
JanetBuffer *buffer;
|
JanetBuffer *buffer;
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
buffer = janet_buffer(0);
|
buffer = janet_buffer(0);
|
||||||
@ -250,9 +240,9 @@ static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
|||||||
static Janet cfun_io_fwrite(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fwrite(int32_t argc, Janet *argv) {
|
||||||
janet_arity(argc, 1, -1);
|
janet_arity(argc, 1, -1);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED)
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
janet_panic("file is closed");
|
janet_panic("file is closed");
|
||||||
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
|
if (!(iof->flags & (JANET_FILE_WRITE | JANET_FILE_APPEND | JANET_FILE_UPDATE)))
|
||||||
janet_panic("file is not writeable");
|
janet_panic("file is not writeable");
|
||||||
int32_t i;
|
int32_t i;
|
||||||
/* Verify all arguments before writing to file */
|
/* Verify all arguments before writing to file */
|
||||||
@ -273,9 +263,9 @@ static Janet cfun_io_fwrite(int32_t argc, Janet *argv) {
|
|||||||
static Janet cfun_io_fflush(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fflush(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED)
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
janet_panic("file is closed");
|
janet_panic("file is closed");
|
||||||
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
|
if (!(iof->flags & (JANET_FILE_WRITE | JANET_FILE_APPEND | JANET_FILE_UPDATE)))
|
||||||
janet_panic("file is not writeable");
|
janet_panic("file is not writeable");
|
||||||
if (fflush(iof->file))
|
if (fflush(iof->file))
|
||||||
janet_panic("could not flush file");
|
janet_panic("could not flush file");
|
||||||
@ -286,7 +276,7 @@ static Janet cfun_io_fflush(int32_t argc, Janet *argv) {
|
|||||||
static int cfun_io_gc(void *p, size_t len) {
|
static int cfun_io_gc(void *p, size_t len) {
|
||||||
(void) len;
|
(void) len;
|
||||||
IOFile *iof = (IOFile *)p;
|
IOFile *iof = (IOFile *)p;
|
||||||
if (!(iof->flags & (IO_NOT_CLOSEABLE | IO_CLOSED))) {
|
if (!(iof->flags & (JANET_FILE_NOT_CLOSEABLE | JANET_FILE_CLOSED))) {
|
||||||
return fclose(iof->file);
|
return fclose(iof->file);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -296,22 +286,22 @@ static int cfun_io_gc(void *p, size_t len) {
|
|||||||
static Janet cfun_io_fclose(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fclose(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED)
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
janet_panic("file is closed");
|
janet_panic("file is closed");
|
||||||
if (iof->flags & (IO_NOT_CLOSEABLE))
|
if (iof->flags & (JANET_FILE_NOT_CLOSEABLE))
|
||||||
janet_panic("file not closable");
|
janet_panic("file not closable");
|
||||||
if (iof->flags & IO_PIPED) {
|
if (iof->flags & JANET_FILE_PIPED) {
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
#define pclose _pclose
|
#define pclose _pclose
|
||||||
#define WEXITSTATUS(x) x
|
#define WEXITSTATUS(x) x
|
||||||
#endif
|
#endif
|
||||||
int status = pclose(iof->file);
|
int status = pclose(iof->file);
|
||||||
iof->flags |= IO_CLOSED;
|
iof->flags |= JANET_FILE_CLOSED;
|
||||||
if (status == -1) janet_panic("could not close file");
|
if (status == -1) janet_panic("could not close file");
|
||||||
return janet_wrap_integer(WEXITSTATUS(status));
|
return janet_wrap_integer(WEXITSTATUS(status));
|
||||||
} else {
|
} else {
|
||||||
if (fclose(iof->file)) janet_panic("could not close file");
|
if (fclose(iof->file)) janet_panic("could not close file");
|
||||||
iof->flags |= IO_CLOSED;
|
iof->flags |= JANET_FILE_CLOSED;
|
||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +310,7 @@ static Janet cfun_io_fclose(int32_t argc, Janet *argv) {
|
|||||||
static Janet cfun_io_fseek(int32_t argc, Janet *argv) {
|
static Janet cfun_io_fseek(int32_t argc, Janet *argv) {
|
||||||
janet_arity(argc, 2, 3);
|
janet_arity(argc, 2, 3);
|
||||||
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
IOFile *iof = janet_getabstract(argv, 0, &cfun_io_filetype);
|
||||||
if (iof->flags & IO_CLOSED)
|
if (iof->flags & JANET_FILE_CLOSED)
|
||||||
janet_panic("file is closed");
|
janet_panic("file is closed");
|
||||||
long int offset = 0;
|
long int offset = 0;
|
||||||
int whence = SEEK_CUR;
|
int whence = SEEK_CUR;
|
||||||
@ -680,15 +670,15 @@ void janet_lib_io(JanetTable *env) {
|
|||||||
|
|
||||||
/* stdout */
|
/* stdout */
|
||||||
janet_core_def(env, "stdout",
|
janet_core_def(env, "stdout",
|
||||||
makef(stdout, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
|
makef(stdout, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard output file."));
|
JDOC("The standard output file."));
|
||||||
/* stderr */
|
/* stderr */
|
||||||
janet_core_def(env, "stderr",
|
janet_core_def(env, "stderr",
|
||||||
makef(stderr, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
|
makef(stderr, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard error file."));
|
JDOC("The standard error file."));
|
||||||
/* stdin */
|
/* stdin */
|
||||||
janet_core_def(env, "stdin",
|
janet_core_def(env, "stdin",
|
||||||
makef(stdin, IO_READ | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
|
makef(stdin, JANET_FILE_READ | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard input file."));
|
JDOC("The standard input file."));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1437,6 +1437,16 @@ JANET_API JanetArray *janet_optarray(const Janet *argv, int32_t argc, int32_t n,
|
|||||||
JANET_API Janet janet_dyn(const char *name);
|
JANET_API Janet janet_dyn(const char *name);
|
||||||
JANET_API void janet_setdyn(const char *name, Janet value);
|
JANET_API void janet_setdyn(const char *name, Janet value);
|
||||||
|
|
||||||
|
#define JANET_FILE_WRITE 1
|
||||||
|
#define JANET_FILE_READ 2
|
||||||
|
#define JANET_FILE_APPEND 4
|
||||||
|
#define JANET_FILE_UPDATE 8
|
||||||
|
#define JANET_FILE_NOT_CLOSEABLE 16
|
||||||
|
#define JANET_FILE_CLOSED 32
|
||||||
|
#define JANET_FILE_BINARY 64
|
||||||
|
#define JANET_FILE_SERIALIZABLE 128
|
||||||
|
#define JANET_FILE_PIPED 256
|
||||||
|
|
||||||
JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags);
|
JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags);
|
||||||
JANET_API FILE *janet_dynfile(const char *name, FILE *def);
|
JANET_API FILE *janet_dynfile(const char *name, FILE *def);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user