* Alan Post <[email protected]> [110928 19:32]:
> I can't see buffer2 being deallocated.  Is there a free() missing
> here?

Thanks Alan, I have missed this indeed. As this is only for the
situations where the name of the file exceeds our famous buffer,
this would just have sometimes leaked memory, hence we also only
free it if buffer2 differs from buffer after that part. Does this
make sense?

Also can someone confirm that access is part of the POSIX standard
that windows supports? Mr. Cowan maybe?

Please find the updated patch attached.

Thank you!

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 f6959aaa960078b05bb273cba554ebd95648555f 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 4cf975c..5cb1f85 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..e3511e9 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, "stat");
+  }
+  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.3.5

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

Reply via email to