Hi, attached is a patch as a proposed fix for bug Ã#706.
This will need some discussion as I am not sure what I am doing here :) First of all it introduces: 1. A new primitive C_file_exists that will use access to check wether we could access a file 2. Reroutes the file-exists? procedure to use C_file_exists 3. A new error code for barf() to signal system call errors Ad 1.: Thomas Chust suggested this and the code seems a bit easier and we do not need to allocate all that memory we aren't interested in. AÃlso we dodge the overflow situation altogether for this small use case. We will signal an error if we get anything negative besides ENOENT back. I am not sure if I did the name mangling right. Also where does "buffer" come from? Please investigate! Ad 2: trivial Ad 3: To signal the error above I wanted to construct a proper condition (exn i/o) or something but I am unsure how to do this. To base the discussion upon facts, I have created a new error type for barf so at lease I get a little more helpful hint at what's going on. Looking forward hearing your opinions, 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 341ac1c69df18eac9a5ebf0cfc5553fa62bff3bd 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 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 | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 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..32804cf 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,31 @@ 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 (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
