diff options
author | Ludovic Courtès <ludo@gnu.org> | 2009-11-15 16:55:57 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2009-11-16 09:23:45 +0100 |
commit | 64e3a89c359c9cdace782e63bb4cd6df59ff7c66 (patch) | |
tree | 918fcd98e546c9754bf524f98cb5e2d7329db884 | |
parent | 4c7b997519050243fa5474b03f8164da03be04d8 (diff) | |
download | guile-64e3a89c359c9cdace782e63bb4cd6df59ff7c66.tar.gz |
Run the GC and retry `open-file' when getting `EMFILE'.
* libguile/fports.c (scm_open_file): Run the GC and retry when getting
`EMFILE'.
-rw-r--r-- | libguile/fports.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/libguile/fports.c b/libguile/fports.c index 5d374950f..12b791803 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -318,11 +318,9 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, #define FUNC_NAME s_scm_open_file { SCM port; - int fdes; - int flags = 0; - char *file; - char *md; - char *ptr; + int fdes, flags = 0; + unsigned int retries; + char *file, *md, *ptr; scm_dynwind_begin (0); @@ -367,15 +365,27 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, } ptr++; } - SCM_SYSCALL (fdes = open_or_open64 (file, flags, 0666)); - if (fdes == -1) + + for (retries = 0, fdes = -1; + fdes < 0 && retries < 2; + retries++) { - int en = errno; + SCM_SYSCALL (fdes = open_or_open64 (file, flags, 0666)); + if (fdes == -1) + { + int en = errno; - SCM_SYSERROR_MSG ("~A: ~S", - scm_cons (scm_strerror (scm_from_int (en)), - scm_cons (filename, SCM_EOL)), en); + if (en == EMFILE && retries == 0) + /* Run the GC in case it collects open file ports that are no + longer referenced. */ + scm_i_gc (FUNC_NAME); + else + SCM_SYSERROR_MSG ("~A: ~S", + scm_cons (scm_strerror (scm_from_int (en)), + scm_cons (filename, SCM_EOL)), en); + } } + port = scm_i_fdes_to_port (fdes, scm_i_mode_bits (mode), filename); scm_dynwind_end (); |