* Alan Post <[email protected]> [110928 22:49]:
> On Wed, Sep 28, 2011 at 10:10:14PM +0200, Christian Kellermann wrote:
> I now notice that barf says "stat" on an OOM error.  Excuse my
> nitpicking, but should that be "access"?

It should. To complete this patch if only for the archives, I have
attached an updated version.

Thanks Alan,

Christian

-- 
Who can (make) the muddy water (clear)? Let it be still, and it will
gradually become clear. Who can secure the condition of rest? Let
movement go on, and the condition of rest will gradually arise.
 -- Lao Tse. 
>From f8a17b5ec8c6a792c52dd3853f928be9c67e2811 Mon Sep 17 00:00:00 2001
From: Christian Kellermann <[email protected]>
Date: Wed, 28 Sep 2011 17:23:57 +0200
Subject: [PATCH] Replace ##sys#file-info with ##sys#file-exists in file-exists?

This also introduces a simpler runtime function that calls access to
test for file accessability.

This fixes bug #706 reported by Sven Hartrumpf.

The old version  returned false whenever fstat failed.  In Sven's case
the size parameter overflowed, and file-exists? returns #f.

Thanks to Thomas Chust for the suggestion.
---
 chicken.h   |    3 ++-
 library.scm |    3 ++-
 runtime.c   |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/chicken.h b/chicken.h
index 8c6eff3..47b12f7 100644
--- a/chicken.h
+++ b/chicken.h
@@ -572,7 +572,7 @@ static inline int isinf_ld (long double x)
 #define C_CIRCULAR_DATA_ERROR                         36
 #define C_BAD_ARGUMENT_TYPE_NO_BOOLEAN_ERROR          37
 #define C_BAD_ARGUMENT_TYPE_NO_LOCATIVE_ERROR         38
-
+#define C_SYSCALL_ERROR                               39
 
 /* Platform information */
 #if defined(C_BIG_ENDIAN)
@@ -1674,6 +1674,7 @@ C_fctexport void C_ccall C_make_tagged_pointer(C_word c, 
C_word closure, C_word
 C_fctexport void C_ccall C_ensure_heap_reserve(C_word c, C_word closure, 
C_word k, C_word n) C_noret;
 C_fctexport void C_ccall C_return_to_host(C_word c, C_word closure, C_word k) 
C_noret;
 C_fctexport void C_ccall C_file_info(C_word c, C_word closure, C_word k, 
C_word port) C_noret;
+C_fctexport void C_ccall C_file_exists(C_word c, C_word closure, C_word k, 
C_word port) C_noret;
 C_fctexport void C_ccall C_get_environment_variable(C_word c, C_word closure, 
C_word k, C_word name) C_noret;
 C_fctexport void C_ccall C_get_symbol_table_info(C_word c, C_word closure, 
C_word k) C_noret;
 C_fctexport void C_ccall C_get_memory_info(C_word c, C_word closure, C_word k) 
C_noret;
diff --git a/library.scm b/library.scm
index e07e9c4..5fef68e 100644
--- a/library.scm
+++ b/library.scm
@@ -191,6 +191,7 @@ EOF
 (define ##sys#call-host (##core#primitive "C_return_to_host"))
 (define return-to-host ##sys#call-host)
 (define ##sys#file-info (##core#primitive "C_file_info"))
+(define ##sys#file-exists (##core#primitive "C_file_exists"))
 (define ##sys#symbol-table-info (##core#primitive "C_get_symbol_table_info"))
 (define ##sys#memory-info (##core#primitive "C_get_memory_info"))
 (define (current-milliseconds) (##core#inline_allocate 
("C_a_i_current_milliseconds" 4) #f))
@@ -1979,7 +1980,7 @@ EOF
   (##sys#pathname-resolution
     name
     (lambda (name)
-      (and (##sys#file-info (##sys#platform-fixup-pathname name)) name) )
+      (and (##sys#file-exists (##sys#platform-fixup-pathname name)) name) )
     #:exists?) )
 
 (define (directory-exists? name)
diff --git a/runtime.c b/runtime.c
index c0c91bc..ff9ff0a 100644
--- a/runtime.c
+++ b/runtime.c
@@ -737,6 +737,7 @@ static C_PTABLE_ENTRY *create_initial_ptable()
   C_pte(C_ensure_heap_reserve);
   C_pte(C_return_to_host);
   C_pte(C_file_info);
+  C_pte(C_file_exists);
   C_pte(C_get_symbol_table_info);
   C_pte(C_get_memory_info);
   C_pte(C_decode_seconds);
@@ -1616,6 +1617,11 @@ void barf(int code, char *loc, ...)
     c = 0;
     break;
 
+  case C_SYSCALL_ERROR:
+    msg = C_text("Underlying syscall error");
+    c = 1;
+    break;
+
   default: panic(C_text("illegal internal error code"));
   }
   
@@ -7776,6 +7782,36 @@ void C_ccall C_file_info(C_word c, C_word closure, 
C_word k, C_word name)
   file_info_2(NULL);
 }
 
+void C_ccall C_file_exists(C_word c, C_word closure, C_word k, C_word name)
+{
+  C_word v = C_SCHEME_FALSE;
+  int call_res = 0;
+
+  int len = C_header_size(name);
+  char *buffer2;
+  int res = 0;
+
+  buffer2 = buffer;
+  if(len >= sizeof(buffer)) {
+    if((buffer2 = (char *)C_malloc(len + 1)) == NULL)
+      barf(C_OUT_OF_MEMORY_ERROR, "access");
+  }
+  C_strncpy(buffer2, C_c_string(name), len);
+  buffer2[ len ] = '\0';
+
+  call_res=access(buffer2, F_OK);
+
+  if (buffer2 != buffer)
+         free(buffer2);
+
+  if (call_res == 0) {
+    v = C_SCHEME_TRUE;
+  } else if (errno != ENOENT) {
+    barf(C_SYSCALL_ERROR, "access");
+  }
+
+  C_kontinue(k, v);
+}
 
 void file_info_2(void *dummy)
 {
-- 
1.7.4.1

_______________________________________________
Chicken-hackers mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/chicken-hackers

Reply via email to