1
0
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:
Calvin Rose 2019-12-14 09:03:56 -06:00
parent eca42e98f6
commit 56784a34a1
2 changed files with 38 additions and 38 deletions

View File

@ -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."));
} }

View 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);