diff --git a/eval.c b/eval.c index 721420ba..302e5c94 100644 --- a/eval.c +++ b/eval.c @@ -1009,10 +1009,19 @@ sexp sexp_exception_type_op (sexp ctx, sexp self, sexp_sint_t n, sexp exn) { sexp sexp_open_input_file_op (sexp ctx, sexp self, sexp_sint_t n, sexp path) { FILE *in; + int count = 0; sexp_assert_type(ctx, sexp_stringp, SEXP_STRING, path); + loop: in = fopen(sexp_string_data(path), "r"); - if (! in) + if (!in) { +#if SEXP_USE_GC_FILE_DESCRIPTORS + if (errno == EMFILE && !count++) { + sexp_gc(ctx, NULL); + goto loop; + } +#endif return sexp_user_exception(ctx, self, "couldn't open input file", path); + } #if SEXP_USE_GREEN_THREADS fcntl(fileno(in), F_SETFL, O_NONBLOCK); #endif @@ -1021,10 +1030,19 @@ sexp sexp_open_input_file_op (sexp ctx, sexp self, sexp_sint_t n, sexp path) { sexp sexp_open_output_file_op (sexp ctx, sexp self, sexp_sint_t n, sexp path) { FILE *out; + int count = 0; sexp_assert_type(ctx, sexp_stringp, SEXP_STRING, path); + loop: out = fopen(sexp_string_data(path), "w"); - if (! out) + if (!out) { +#if SEXP_USE_GC_FILE_DESCRIPTORS + if (errno == EMFILE && !count++) { + sexp_gc(ctx, NULL); + goto loop; + } +#endif return sexp_user_exception(ctx, self, "couldn't open output file", path); + } return sexp_make_output_port(ctx, out, path); } diff --git a/include/chibi/features.h b/include/chibi/features.h index d60a172c..1e0cf0f4 100644 --- a/include/chibi/features.h +++ b/include/chibi/features.h @@ -506,6 +506,10 @@ #define SEXP_USE_AUTOCLOSE_PORTS ! SEXP_USE_NO_FEATURES #endif +#ifndef SEXP_USE_GC_FILE_DESCRIPTORS +#define SEXP_USE_GC_FILE_DESCRIPTORS (SEXP_USE_AUTOCLOSE_PORTS &&!SEXP_USE_BOEHM) +#endif + #ifndef SEXP_USE_2010_EPOCH #define SEXP_USE_2010_EPOCH ! SEXP_USE_NO_FEATURES #endif