added file-exists? and delete-file operations to libposix.ss and ikarus-runtime.c
This commit is contained in:
parent
e97b39a39a
commit
9eaaf3c438
BIN
runtime/ikarus
BIN
runtime/ikarus
Binary file not shown.
|
@ -11,7 +11,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define forward_ptr ((ikp)-1)
|
#define forward_ptr ((ikp)-1)
|
||||||
#define DEBUG_STACK 0
|
//#define DEBUG_STACK 0
|
||||||
#define minimum_heap_size (pagesize * 1024 * 4)
|
#define minimum_heap_size (pagesize * 1024 * 4)
|
||||||
#define maximum_heap_size (pagesize * 1024 * 8)
|
#define maximum_heap_size (pagesize * 1024 * 8)
|
||||||
#define minimum_stack_size (pagesize * 128)
|
#define minimum_stack_size (pagesize * 128)
|
||||||
|
@ -231,7 +231,7 @@ gc_tconc_push(gc_t* gc, ikp tcbucket){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ikp add_object(gc_t* gc, ikp x);
|
static ikp add_object(gc_t* gc, ikp x, char* caller);
|
||||||
static void collect_stack(gc_t*, ikp top, ikp base);
|
static void collect_stack(gc_t*, ikp top, ikp base);
|
||||||
static void collect_loop(gc_t*);
|
static void collect_loop(gc_t*);
|
||||||
static void fix_weak_pointers(gc_t*);
|
static void fix_weak_pointers(gc_t*);
|
||||||
|
@ -306,8 +306,8 @@ ik_collect(int req, ikpcb* pcb){
|
||||||
*/
|
*/
|
||||||
scan_dirty_pages(&gc);
|
scan_dirty_pages(&gc);
|
||||||
collect_stack(&gc, pcb->frame_pointer, pcb->frame_base - wordsize);
|
collect_stack(&gc, pcb->frame_pointer, pcb->frame_base - wordsize);
|
||||||
pcb->next_k = add_object(&gc, pcb->next_k);
|
pcb->next_k = add_object(&gc, pcb->next_k, "main");
|
||||||
pcb->oblist = add_object(&gc, pcb->oblist);
|
pcb->oblist = add_object(&gc, pcb->oblist, "main");
|
||||||
/* now we trace all live objects */
|
/* now we trace all live objects */
|
||||||
collect_loop(&gc);
|
collect_loop(&gc);
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ static void collect_stack(gc_t* gc, ikp top, ikp end){
|
||||||
}
|
}
|
||||||
ikp base = top + framesize - wordsize;
|
ikp base = top + framesize - wordsize;
|
||||||
while(base > top){
|
while(base > top){
|
||||||
ikp new_obj = add_object(gc,ref(base,0));
|
ikp new_obj = add_object(gc,ref(base,0), "frame");
|
||||||
ref(base,0) = new_obj;
|
ref(base,0) = new_obj;
|
||||||
base -= wordsize;
|
base -= wordsize;
|
||||||
}
|
}
|
||||||
|
@ -552,14 +552,17 @@ static void collect_stack(gc_t* gc, ikp top, ikp end){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<bytes_in_mask; i++, fp-=8){
|
for(i=0; i<bytes_in_mask; i++, fp-=8){
|
||||||
unsigned char m = mask[i];
|
unsigned char m = mask[i];
|
||||||
if(m & 0x01) { fp[-0] = add_object(gc, fp[-0]); }
|
#if DEBUG_STACK
|
||||||
if(m & 0x02) { fp[-1] = add_object(gc, fp[-1]); }
|
fprintf(stderr, "m=0x%x\n", m);
|
||||||
if(m & 0x04) { fp[-2] = add_object(gc, fp[-2]); }
|
#endif
|
||||||
if(m & 0x08) { fp[-3] = add_object(gc, fp[-3]); }
|
if(m & 0x01) { fp[-0] = add_object(gc, fp[-0], "frame2"); }
|
||||||
if(m & 0x10) { fp[-4] = add_object(gc, fp[-4]); }
|
if(m & 0x02) { fp[-1] = add_object(gc, fp[-1], "frame3"); }
|
||||||
if(m & 0x20) { fp[-5] = add_object(gc, fp[-5]); }
|
if(m & 0x04) { fp[-2] = add_object(gc, fp[-2], "frame4"); }
|
||||||
if(m & 0x40) { fp[-6] = add_object(gc, fp[-6]); }
|
if(m & 0x08) { fp[-3] = add_object(gc, fp[-3], "frame5"); }
|
||||||
if(m & 0x80) { fp[-7] = add_object(gc, fp[-7]); }
|
if(m & 0x10) { fp[-4] = add_object(gc, fp[-4], "frame6"); }
|
||||||
|
if(m & 0x20) { fp[-5] = add_object(gc, fp[-5], "frame7"); }
|
||||||
|
if(m & 0x40) { fp[-6] = add_object(gc, fp[-6], "framea"); }
|
||||||
|
if(m & 0x80) { fp[-7] = add_object(gc, fp[-7], "frameb"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
top += framesize;
|
top += framesize;
|
||||||
|
@ -621,7 +624,7 @@ add_list(gc_t* gc, unsigned int t, int gen, ikp x, ikp* loc){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ref(y, off_cdr) = add_object(gc, snd);
|
ref(y, off_cdr) = add_object(gc, snd, "add_list");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,7 +632,7 @@ add_list(gc_t* gc, unsigned int t, int gen, ikp x, ikp* loc){
|
||||||
|
|
||||||
|
|
||||||
static ikp
|
static ikp
|
||||||
add_object(gc_t* gc, ikp x){
|
add_object(gc_t* gc, ikp x, char* caller){
|
||||||
if(is_fixnum(x)){
|
if(is_fixnum(x)){
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
@ -825,7 +828,7 @@ add_object(gc_t* gc, ikp x){
|
||||||
static void
|
static void
|
||||||
relocate_new_code(ikp x, gc_t* gc){
|
relocate_new_code(ikp x, gc_t* gc){
|
||||||
ikp relocvector = ref(x, disp_code_reloc_vector);
|
ikp relocvector = ref(x, disp_code_reloc_vector);
|
||||||
relocvector = add_object(gc, relocvector);
|
relocvector = add_object(gc, relocvector, "reloc");
|
||||||
ref(x, disp_code_reloc_vector) = relocvector;
|
ref(x, disp_code_reloc_vector) = relocvector;
|
||||||
int relocsize = (int)ref(relocvector, off_vector_length);
|
int relocsize = (int)ref(relocvector, off_vector_length);
|
||||||
ikp p = relocvector + off_vector_data;
|
ikp p = relocvector + off_vector_data;
|
||||||
|
@ -838,7 +841,7 @@ relocate_new_code(ikp x, gc_t* gc){
|
||||||
if(tag == 0){
|
if(tag == 0){
|
||||||
/* undisplaced pointer */
|
/* undisplaced pointer */
|
||||||
ikp old_object = ref(p, wordsize);
|
ikp old_object = ref(p, wordsize);
|
||||||
ikp new_object = add_object(gc, old_object);
|
ikp new_object = add_object(gc, old_object, "reloc");
|
||||||
ref(code, code_off) = new_object;
|
ref(code, code_off) = new_object;
|
||||||
p += (2*wordsize);
|
p += (2*wordsize);
|
||||||
}
|
}
|
||||||
|
@ -846,14 +849,14 @@ relocate_new_code(ikp x, gc_t* gc){
|
||||||
/* displaced pointer */
|
/* displaced pointer */
|
||||||
int obj_off = unfix(ref(p, wordsize));
|
int obj_off = unfix(ref(p, wordsize));
|
||||||
ikp old_object = ref(p, 2*wordsize);
|
ikp old_object = ref(p, 2*wordsize);
|
||||||
ikp new_object = add_object(gc, old_object);
|
ikp new_object = add_object(gc, old_object, "reloc");
|
||||||
ref(code, code_off) = new_object + obj_off;
|
ref(code, code_off) = new_object + obj_off;
|
||||||
p += (3 * wordsize);
|
p += (3 * wordsize);
|
||||||
}
|
}
|
||||||
else if(tag == 3){
|
else if(tag == 3){
|
||||||
/* displaced relative pointer */
|
/* displaced relative pointer */
|
||||||
int obj_off = unfix(ref(p, wordsize));
|
int obj_off = unfix(ref(p, wordsize));
|
||||||
ikp obj = add_object(gc, ref(p, 2*wordsize));
|
ikp obj = add_object(gc, ref(p, 2*wordsize), "reloc");
|
||||||
ikp displaced_object = obj + obj_off;
|
ikp displaced_object = obj + obj_off;
|
||||||
ikp next_word = code + code_off + wordsize;
|
ikp next_word = code + code_off + wordsize;
|
||||||
ikp relative_distance = displaced_object - (int)next_word;
|
ikp relative_distance = displaced_object - (int)next_word;
|
||||||
|
@ -876,7 +879,6 @@ relocate_new_code(ikp x, gc_t* gc){
|
||||||
static void
|
static void
|
||||||
collect_loop(gc_t* gc){
|
collect_loop(gc_t* gc){
|
||||||
int done;
|
int done;
|
||||||
int scan_ptr_count = 0;
|
|
||||||
do{
|
do{
|
||||||
done = 1;
|
done = 1;
|
||||||
{ /* scan the pending pairs pages */
|
{ /* scan the pending pairs pages */
|
||||||
|
@ -888,7 +890,7 @@ collect_loop(gc_t* gc){
|
||||||
ikp p = qu->p;
|
ikp p = qu->p;
|
||||||
ikp q = qu->q;
|
ikp q = qu->q;
|
||||||
while(p < q){
|
while(p < q){
|
||||||
ref(p,0) = add_object(gc, ref(p,0));
|
ref(p,0) = add_object(gc, ref(p,0), "loop");
|
||||||
p += (2*wordsize);
|
p += (2*wordsize);
|
||||||
}
|
}
|
||||||
qupages_t* next = qu->next;
|
qupages_t* next = qu->next;
|
||||||
|
@ -907,7 +909,7 @@ collect_loop(gc_t* gc){
|
||||||
ikp p = qu->p;
|
ikp p = qu->p;
|
||||||
ikp q = qu->q;
|
ikp q = qu->q;
|
||||||
while(p < q){
|
while(p < q){
|
||||||
ref(p,0) = add_object(gc, ref(p,0));
|
ref(p,0) = add_object(gc, ref(p,0), "pending");
|
||||||
p += wordsize;
|
p += wordsize;
|
||||||
}
|
}
|
||||||
qupages_t* next = qu->next;
|
qupages_t* next = qu->next;
|
||||||
|
@ -946,7 +948,7 @@ collect_loop(gc_t* gc){
|
||||||
do{
|
do{
|
||||||
meta->aq = q;
|
meta->aq = q;
|
||||||
while(p < q){
|
while(p < q){
|
||||||
ref(p,0) = add_object(gc, ref(p,0));
|
ref(p,0) = add_object(gc, ref(p,0), "rem");
|
||||||
p += (2*wordsize);
|
p += (2*wordsize);
|
||||||
}
|
}
|
||||||
p = meta->aq;
|
p = meta->aq;
|
||||||
|
@ -963,7 +965,7 @@ collect_loop(gc_t* gc){
|
||||||
do{
|
do{
|
||||||
meta->aq = q;
|
meta->aq = q;
|
||||||
while(p < q){
|
while(p < q){
|
||||||
ref(p,0) = add_object(gc, ref(p,0));
|
ref(p,0) = add_object(gc, ref(p,0), "rem2");
|
||||||
p += wordsize;
|
p += wordsize;
|
||||||
}
|
}
|
||||||
p = meta->aq;
|
p = meta->aq;
|
||||||
|
@ -1102,7 +1104,7 @@ scan_dirty_pointers_page(gc_t* gc, int page_idx, int mask){
|
||||||
if(is_fixnum(x) || (tagof(x) == immediate_tag)){
|
if(is_fixnum(x) || (tagof(x) == immediate_tag)){
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
} else {
|
} else {
|
||||||
ikp y = add_object(gc, x);
|
ikp y = add_object(gc, x, "nothing");
|
||||||
segment_vec = gc->segment_vector;
|
segment_vec = gc->segment_vector;
|
||||||
ref(p, 0) = y;
|
ref(p, 0) = y;
|
||||||
card_d = card_d | segment_vec[page_index(y)];
|
card_d = card_d | segment_vec[page_index(y)];
|
||||||
|
@ -1151,7 +1153,7 @@ scan_dirty_code_page(gc_t* gc, int page_idx, unsigned int mask){
|
||||||
if(is_fixnum(r) || (tagof(r) == immediate_tag)){
|
if(is_fixnum(r) || (tagof(r) == immediate_tag)){
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
} else {
|
} else {
|
||||||
r = add_object(gc, r);
|
r = add_object(gc, r, "nothing2");
|
||||||
segment_vec = gc->segment_vector;
|
segment_vec = gc->segment_vector;
|
||||||
code_d = code_d | segment_vec[page_index(r)];
|
code_d = code_d | segment_vec[page_index(r)];
|
||||||
}
|
}
|
||||||
|
@ -1186,7 +1188,7 @@ scan_dirty_weak_pointers_page(gc_t* gc, int page_idx, int mask){
|
||||||
if(is_fixnum(x) || tagof(x) == immediate_tag){
|
if(is_fixnum(x) || tagof(x) == immediate_tag){
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
} else {
|
} else {
|
||||||
ikp y = add_object(gc, x);
|
ikp y = add_object(gc, x, "nothing3");
|
||||||
ref(p, wordsize) = y;
|
ref(p, wordsize) = y;
|
||||||
}
|
}
|
||||||
p += (2*wordsize);
|
p += (2*wordsize);
|
||||||
|
|
|
@ -488,6 +488,115 @@ ikp ik_open_file(ikp str, ikp flagptr){
|
||||||
return fix(fd);
|
return fix(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
int
|
||||||
|
stat(const char *path, struct stat *sb);
|
||||||
|
ERRORS
|
||||||
|
Stat() and lstat() will fail if:
|
||||||
|
[ENOTDIR] A component of the path prefix is not a directory.
|
||||||
|
[ENAMETOOLONG] A component of a pathname exceeded {NAME_MAX} charac-
|
||||||
|
ters, or an entire path name exceeded {PATH_MAX} char-
|
||||||
|
acters.
|
||||||
|
[ENOENT] The named file does not exist.
|
||||||
|
[EACCES] Search permission is denied for a component of the
|
||||||
|
path prefix.
|
||||||
|
[ELOOP] Too many symbolic links were encountered in translat-
|
||||||
|
ing the pathname.
|
||||||
|
[EFAULT] Sb or name points to an invalid address.
|
||||||
|
[EIO] An I/O error occurred while reading from or writing to
|
||||||
|
the file system.
|
||||||
|
*/
|
||||||
|
ikp
|
||||||
|
ikrt_file_exists(ikp filename){
|
||||||
|
char* str = string_data(filename);
|
||||||
|
struct stat sb;
|
||||||
|
int st = stat(str, &sb);
|
||||||
|
if(st == 0){
|
||||||
|
/* success */
|
||||||
|
return true_object;
|
||||||
|
} else {
|
||||||
|
int err = errno;
|
||||||
|
if(err == ENOENT){
|
||||||
|
return false_object;
|
||||||
|
}
|
||||||
|
else if(err == ENOTDIR){
|
||||||
|
return fix(1);
|
||||||
|
}
|
||||||
|
else if(err == ENAMETOOLONG){
|
||||||
|
return fix(2);
|
||||||
|
}
|
||||||
|
else if(err == EACCES){
|
||||||
|
return fix(3);
|
||||||
|
}
|
||||||
|
else if(err == ELOOP){
|
||||||
|
return fix(4);
|
||||||
|
}
|
||||||
|
else if(err == EFAULT){
|
||||||
|
return fix(5);
|
||||||
|
}
|
||||||
|
else if(err == EIO){
|
||||||
|
return fix(6);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return fix(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
[ENOTDIR] A component of the path prefix is not a directory.
|
||||||
|
[ENAMETOOLONG] A component of a pathname exceeded {NAME_MAX} charac-
|
||||||
|
ters, or an entire path name exceeded {PATH_MAX} char-
|
||||||
|
acters.
|
||||||
|
[ENOENT] The named file does not exist.
|
||||||
|
[EACCES] Search permission is denied for a component of the
|
||||||
|
path prefix.
|
||||||
|
[EACCES] Write permission is denied on the directory containing
|
||||||
|
the link to be removed.
|
||||||
|
[ELOOP] Too many symbolic links were encountered in translat-
|
||||||
|
ing the pathname.
|
||||||
|
[EPERM] The named file is a directory and the effective user
|
||||||
|
ID of the process is not the super-user.
|
||||||
|
[EPERM] The directory containing the file is marked sticky,
|
||||||
|
and neither the containing directory nor the file to
|
||||||
|
be removed are owned by the effective user ID.
|
||||||
|
[EBUSY] The entry to be unlinked is the mount point for a
|
||||||
|
mounted file system.
|
||||||
|
[EIO] An I/O error occurred while deleting the directory
|
||||||
|
entry or deallocating the inode.
|
||||||
|
[EROFS] The named file resides on a read-only file system.
|
||||||
|
[EFAULT] Path points outside the process's allocated address
|
||||||
|
space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
ikp
|
||||||
|
ikrt_delete_file(ikp filename){
|
||||||
|
char* str = string_data(filename);
|
||||||
|
int err = unlink(str);
|
||||||
|
if(err == 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch (err){
|
||||||
|
case ENOTDIR: return fix(1);
|
||||||
|
case ENAMETOOLONG: return fix(2);
|
||||||
|
case ENOENT: return fix(3);
|
||||||
|
case EACCES: return fix(4);
|
||||||
|
case ELOOP: return fix(5);
|
||||||
|
case EPERM: return fix(6);
|
||||||
|
case EBUSY: return fix(7);
|
||||||
|
case EIO: return fix(8);
|
||||||
|
case EROFS: return fix(9);
|
||||||
|
case EFAULT: return fix(10);
|
||||||
|
}
|
||||||
|
return fix(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ikp ik_close(ikp fd){
|
ikp ik_close(ikp fd){
|
||||||
int err = close(unfix(fd));
|
int err = close(unfix(fd));
|
||||||
if(err != 0){
|
if(err != 0){
|
||||||
|
|
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
Binary file not shown.
|
@ -21,3 +21,48 @@
|
||||||
(error 'system "failed")
|
(error 'system "failed")
|
||||||
rv))))
|
rv))))
|
||||||
|
|
||||||
|
(primitive-set! 'file-exists?
|
||||||
|
(lambda (x)
|
||||||
|
(unless (string? x)
|
||||||
|
(error 'file-exists? "filename ~s is not a string" x))
|
||||||
|
(let ([v (foreign-call "ikrt_file_exists" x)])
|
||||||
|
(cond
|
||||||
|
[(boolean? v) v]
|
||||||
|
[else
|
||||||
|
(error 'file-exists?
|
||||||
|
(case v
|
||||||
|
[(1) "the path ~s contains a non-directory"]
|
||||||
|
[(2) "the path ~s is too long"]
|
||||||
|
[(3) "the path ~s is not accessible"]
|
||||||
|
[(4) "the path ~s contains too many symbolic links"]
|
||||||
|
[(5) "internal access error while accessing ~s"]
|
||||||
|
[(6) "IO error encountered while accessing ~s"]
|
||||||
|
[else "Unknown error in ~s"])
|
||||||
|
x)]))))
|
||||||
|
|
||||||
|
(primitive-set! 'delete-file
|
||||||
|
(lambda (x)
|
||||||
|
(unless (string? x)
|
||||||
|
(error 'delete-file "filename ~s is not a string" x))
|
||||||
|
(let ([v (foreign-call "ikrt_delete_file" x)])
|
||||||
|
(case v
|
||||||
|
[(0) (void)]
|
||||||
|
[else
|
||||||
|
(error 'delete-file
|
||||||
|
(case v
|
||||||
|
[(1) "the path ~s contains a non-directory"]
|
||||||
|
[(2) "the path ~s is too long"]
|
||||||
|
[(3) "the file ~s does not exist"]
|
||||||
|
[(4) "the path ~s is not accessible"]
|
||||||
|
[(5) "the path ~s contains too many symbolic links"]
|
||||||
|
[(6) "you do not have permissions to delete ~s"]
|
||||||
|
[(7) "device ~s is busy"]
|
||||||
|
[(8) "IO error encountered while deleting ~s"]
|
||||||
|
[(9) "~s is in a read-only file system"]
|
||||||
|
[(10) "internal access error while deleting ~s"]
|
||||||
|
[else "Unknown error while deleting ~s"])
|
||||||
|
x)]))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
with-output-to-file call-with-output-file
|
with-output-to-file call-with-output-file
|
||||||
with-input-from-file call-with-input-file
|
with-input-from-file call-with-input-file
|
||||||
date-string
|
date-string
|
||||||
|
file-exists? delete-file
|
||||||
|
|
||||||
+ - add1 sub1 * expt number? positive? negative? zero? number->string
|
+ - add1 sub1 * expt number? positive? negative? zero? number->string
|
||||||
logand
|
logand
|
||||||
|
|
Loading…
Reference in New Issue