Added the following file system primitives
- file-readable? path -> boolean - file-writable? path -> boolean - file-executable? path -> boolean - file-size path -> integer - rename-file source dest -> void (thanks to Andreas Rottmann)
This commit is contained in:
parent
2903b7f9e0
commit
25f40fefb0
|
@ -85,6 +85,9 @@
|
|||
[file-exists? boolean]
|
||||
[file-regular? boolean]
|
||||
[file-directory? boolean]
|
||||
[file-readable? boolean]
|
||||
[file-writable? boolean]
|
||||
[file-executable? boolean]
|
||||
[file-symbolic-link? boolean]
|
||||
[record? boolean]
|
||||
[record-field-mutable? boolean]
|
||||
|
|
|
@ -15,24 +15,27 @@
|
|||
|
||||
|
||||
(library (ikarus.posix)
|
||||
(export posix-fork fork waitpid system file-exists? delete-file
|
||||
nanosleep getenv env environ file-ctime file-mtime
|
||||
current-directory
|
||||
file-regular? file-directory? file-symbolic-link? make-symbolic-link
|
||||
directory-list make-directory delete-directory change-mode
|
||||
kill strerror
|
||||
wstatus-pid wstatus-exit-status wstatus-received-signal)
|
||||
|
||||
(export
|
||||
posix-fork fork waitpid system file-exists? delete-file
|
||||
nanosleep getenv env environ file-ctime file-mtime
|
||||
current-directory file-regular? file-directory? file-readable?
|
||||
file-writable? file-executable? file-size rename-file
|
||||
file-symbolic-link? make-symbolic-link directory-list
|
||||
make-directory delete-directory change-mode kill strerror
|
||||
wstatus-pid wstatus-exit-status wstatus-received-signal)
|
||||
|
||||
(import
|
||||
(rnrs bytevectors)
|
||||
(except (ikarus)
|
||||
nanosleep
|
||||
posix-fork fork waitpid system file-exists? delete-file
|
||||
getenv env environ file-ctime file-mtime
|
||||
current-directory
|
||||
file-regular? file-directory? file-symbolic-link? make-symbolic-link
|
||||
directory-list make-directory delete-directory change-mode
|
||||
kill strerror
|
||||
wstatus-pid wstatus-exit-status wstatus-received-signal))
|
||||
nanosleep posix-fork fork waitpid system file-exists?
|
||||
delete-file getenv env environ file-ctime file-mtime
|
||||
current-directory file-regular? file-directory?
|
||||
file-readable? file-writable? file-executable? file-size
|
||||
rename-file file-symbolic-link? make-symbolic-link
|
||||
directory-list make-directory delete-directory change-mode
|
||||
kill strerror wstatus-pid wstatus-exit-status
|
||||
wstatus-received-signal))
|
||||
|
||||
(define posix-fork
|
||||
(lambda ()
|
||||
|
@ -151,6 +154,15 @@
|
|||
[(-45) #f] ;; from ikarus-errno.c: ENOENT -- path does not exist
|
||||
[else (raise/strerror who r path)]))))
|
||||
|
||||
|
||||
(define access
|
||||
(lambda (path how who)
|
||||
(unless (string? path)
|
||||
(die who "not a string" path))
|
||||
(let ([r (foreign-call "ikrt_access" (string->utf8 path) how)])
|
||||
(unless (boolean? r) (raise/strerror who r path))
|
||||
r)))
|
||||
|
||||
(define file-exists?
|
||||
(case-lambda
|
||||
[(path) (file-exists? path #t)]
|
||||
|
@ -173,6 +185,29 @@
|
|||
(lambda (path)
|
||||
(eq? 'symlink (stat path #f 'file-symbolic-link?))))
|
||||
|
||||
|
||||
(define file-readable?
|
||||
(lambda (path)
|
||||
(access path 1 'file-readable?)))
|
||||
|
||||
(define file-writable?
|
||||
(lambda (path)
|
||||
(access path 2 'file-writable?)))
|
||||
|
||||
(define file-executable?
|
||||
(lambda (path)
|
||||
(access path 4 'file-executable?)))
|
||||
|
||||
(define file-size
|
||||
(lambda (path)
|
||||
(define who 'file-size)
|
||||
(unless (string? path)
|
||||
(die who "filename is not a string" path))
|
||||
(let* ([v (foreign-call "ikrt_file_size" (string->utf8 path))])
|
||||
(if (>= v 0)
|
||||
v
|
||||
(raise/strerror who v path)))))
|
||||
|
||||
(define delete-file
|
||||
(lambda (x)
|
||||
(define who 'delete-file)
|
||||
|
@ -183,6 +218,20 @@
|
|||
(unless (eq? v #t)
|
||||
(raise/strerror who v x)))))
|
||||
|
||||
|
||||
(define rename-file
|
||||
(lambda (src dst)
|
||||
(define who 'rename-file)
|
||||
(unless (string? src)
|
||||
(die who "source file name is not a string" src))
|
||||
(unless (string? dst)
|
||||
(die who "destination file name is not a string" dst))
|
||||
(let ([v (foreign-call "ikrt_rename_file"
|
||||
(string->utf8 src)
|
||||
(string->utf8 dst))])
|
||||
(unless (eq? v #t)
|
||||
(raise/strerror who v src)))))
|
||||
|
||||
(define directory-list
|
||||
(lambda (path)
|
||||
(define who 'directory-list)
|
||||
|
|
|
@ -1 +1 @@
|
|||
1664
|
||||
1665
|
||||
|
|
|
@ -1246,9 +1246,13 @@
|
|||
[vector-sort! i r sr]
|
||||
[file-exists? i r fi]
|
||||
[delete-file i r fi]
|
||||
[rename-file i]
|
||||
[file-regular? i]
|
||||
[file-directory? i]
|
||||
[file-symbolic-link? i]
|
||||
[file-readable? i]
|
||||
[file-writable? i]
|
||||
[file-executable? i]
|
||||
[current-directory i]
|
||||
[directory-list i]
|
||||
[make-directory i]
|
||||
|
@ -1257,6 +1261,7 @@
|
|||
[make-symbolic-link i]
|
||||
[file-ctime i]
|
||||
[file-mtime i]
|
||||
[file-size i]
|
||||
[fork i]
|
||||
[define-record-type i r rs]
|
||||
[fields i r rs]
|
||||
|
|
|
@ -220,6 +220,10 @@ ikptr ik_underflow_handler(ikpcb*);
|
|||
ikptr ik_unsafe_alloc(ikpcb* pcb, int size);
|
||||
ikptr ik_safe_alloc(ikpcb* pcb, int size);
|
||||
|
||||
ikptr u_to_number(unsigned long, ikpcb*);
|
||||
ikptr ull_to_number(unsigned long long, ikpcb*);
|
||||
ikptr normalize_bignum(long int limbs, int sign, ikptr r);
|
||||
|
||||
#define IK_HEAP_EXT_SIZE (32 * 4096)
|
||||
#define IK_HEAPSIZE (1024 * ((wordsize==4)?1:2) * 4096) /* 4/8 MB */
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmp.h>
|
||||
|
||||
ikptr
|
||||
ikrt_isapointer(ikptr x, ikpcb* pcb){
|
||||
|
@ -262,6 +263,18 @@ u_to_number(unsigned long n, ikpcb* pcb) {
|
|||
return bn+vector_tag;
|
||||
}
|
||||
|
||||
|
||||
ikptr
|
||||
ull_to_number(unsigned long long n, ikpcb* pcb) {
|
||||
unsigned long long mxn = ((unsigned long)-1)>>(fx_shift+1);
|
||||
if (n <= mxn) {
|
||||
return fix(n);
|
||||
}
|
||||
ikptr bn = ik_safe_alloc(pcb, align(disp_bignum_data+sizeof(long long)));
|
||||
bcopy((char*)(&n), (char*)(bn+disp_bignum_data), sizeof(long long));
|
||||
return normalize_bignum(sizeof(long long)/sizeof(mp_limb_t), 0, bn);
|
||||
}
|
||||
|
||||
ikptr
|
||||
d_to_number(double n, ikpcb* pcb) {
|
||||
ikptr x = ik_safe_alloc(pcb, flonum_size) + vector_tag;
|
||||
|
|
|
@ -1037,3 +1037,62 @@ ikrt_debug(ikptr x){
|
|||
fprintf(stderr, "DEBUG 0x%016lx\n", (long int)x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ikptr
|
||||
ikrt_access(ikptr filename, ikptr how /*, ikpcb* pcb */){
|
||||
char* fn = (char*)(filename + off_bytevector_data);
|
||||
int r;
|
||||
int ik_how;
|
||||
int c_how;
|
||||
|
||||
ik_how = unfix(how);
|
||||
if (ik_how == 0) {
|
||||
c_how = F_OK;
|
||||
} else {
|
||||
c_how = 0;
|
||||
if (ik_how & 1) c_how |= R_OK;
|
||||
if (ik_how & 2) c_how |= W_OK;
|
||||
if (ik_how & 4) c_how |= X_OK;
|
||||
}
|
||||
|
||||
r = access(fn, c_how);
|
||||
if (r == 0) {
|
||||
return true_object;
|
||||
} else if ((errno == EACCES) ||
|
||||
(errno == EROFS) ||
|
||||
(errno == ETXTBSY)) {
|
||||
return false_object;
|
||||
} else {
|
||||
return ik_errno_to_code();
|
||||
}
|
||||
}
|
||||
|
||||
ikptr
|
||||
ikrt_file_size(ikptr filename, ikpcb* pcb){
|
||||
char* fn = (char*)(filename + off_bytevector_data);
|
||||
struct stat s;
|
||||
int r = stat(fn, &s);
|
||||
if (r == 0) {
|
||||
if (sizeof(off_t) == sizeof(long)) {
|
||||
return u_to_number(s.st_size, pcb);
|
||||
} else if (sizeof(off_t) == sizeof(long long)) {
|
||||
return ull_to_number(s.st_size, pcb);
|
||||
} else {
|
||||
fprintf(stderr, "internal error in ikarus: invalid off_t size\n");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
return ik_errno_to_code();
|
||||
}
|
||||
}
|
||||
|
||||
ikptr
|
||||
ikrt_rename_file(ikptr src, ikptr dst /* ikpcb* pcb */){
|
||||
int err = rename((char*)(src + off_bytevector_data),
|
||||
(char*)(dst + off_bytevector_data));
|
||||
if (err == 0) {
|
||||
return true_object;
|
||||
} else {
|
||||
return ik_errno_to_code();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue