summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2009-11-15 16:55:57 +0100
committerLudovic Courtès <ludo@gnu.org>2009-11-16 09:23:45 +0100
commit64e3a89c359c9cdace782e63bb4cd6df59ff7c66 (patch)
tree918fcd98e546c9754bf524f98cb5e2d7329db884
parent4c7b997519050243fa5474b03f8164da03be04d8 (diff)
downloadguile-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.c32
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 ();