Added open-directory-steam, directory-stream?, read-directory-stream,

and close-directory-stream as per bug 315804.
This commit is contained in:
Abdulaziz Ghuloum 2009-04-09 12:29:50 +03:00
parent 72b86818f0
commit d63a9c1f51
4 changed files with 101 additions and 2 deletions

View File

@ -71,7 +71,10 @@
accept-connection accept-connection-nonblocking
close-tcp-server-socket
register-callback
input-socket-buffer-size output-socket-buffer-size)
input-socket-buffer-size output-socket-buffer-size
open-directory-stream directory-stream?
read-directory-stream close-directory-stream)
@ -130,6 +133,9 @@
close-tcp-server-socket
register-callback
input-socket-buffer-size output-socket-buffer-size
open-directory-stream directory-stream?
read-directory-stream close-directory-stream
))
;(define-syntax assert* (identifier-syntax assert))
@ -2569,6 +2575,63 @@
[else (die who "invalid argument" what)]))
(module (directory-stream? open-directory-stream
read-directory-stream close-directory-stream)
(define-struct directory-stream (filename pointer closed?))
(define G (make-guardian))
(define (clean-up)
(cond
[(G) =>
(lambda (x)
(close-directory-stream x #f)
(clean-up))]))
(define (open-directory-stream filename)
(define who 'open-directory-stream)
(unless (string? filename)
(die who "not a string" filename))
(clean-up)
(let ([rv (foreign-call "ikrt_opendir" (string->utf8 filename))])
(if (fixnum? rv)
(io-error who filename rv)
(let ([stream (make-directory-stream filename rv #f)])
(G stream)
stream))))
(define (read-directory-stream x)
(define who 'read-directory-stream)
(unless (directory-stream? x)
(die who "not a directory stream" x))
(when (directory-stream-closed? x)
(die who "directory stream is closed" x))
(let ([rv (foreign-call "ikrt_readdir"
(directory-stream-pointer x))])
(cond
[(eqv? rv 0) #f]
[else (utf8->string rv)])))
(define close-directory-stream
(case-lambda
[(x wanterror?)
(define who 'close-directory-stream)
(clean-up)
(unless (directory-stream? x)
(die who "not a directory stream" x))
(unless (directory-stream-closed? x)
(set-directory-stream-closed?! x #t)
(let ([rv (foreign-call "ikrt_closedir"
(directory-stream-pointer x))])
(when (and wanterror? (not (eqv? rv 0)))
(io-error who (directory-stream-filename x) rv))))]
[(x) (close-directory-stream x #t)]))
(set-rtd-printer! (type-descriptor directory-stream)
(lambda (x p wr)
(fprintf p "#<directory-stream ~a>"
(directory-stream-filename x)))))
;(set-fd-nonblocking 0 'init '*stdin*)

View File

@ -1 +1 @@
1761
1762

View File

@ -1271,6 +1271,10 @@
[directory-list i]
[make-directory i]
[delete-directory i]
[directory-stream? i]
[open-directory-stream i]
[read-directory-stream i]
[close-directory-stream i]
[change-mode i]
[make-symbolic-link i]
[make-hard-link i]

View File

@ -27,6 +27,7 @@
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <dirent.h>
#include "ikarus-data.h"
extern ikptr ik_errno_to_code();
@ -378,5 +379,36 @@ ikrt_file_mtime(ikptr filename, ikptr res){
}
ikptr
ikrt_opendir(ikptr dirname, ikpcb* pcb){
DIR* d = opendir((char*)(dirname+off_bytevector_data));
if(d == NULL){
return ik_errno_to_code();
}
return(make_pointer((long)d, pcb));
}
ikptr
ikrt_readdir(ikptr ptr, ikpcb* pcb){
DIR* d = (DIR*) ref(ptr, off_pointer_data);
struct dirent* ent = readdir(d);
if (ent == NULL){
return 0;
}
int len = ent->d_namlen;
ikptr bv = ik_safe_alloc(pcb, align(disp_bytevector_data+len+1))
+ bytevector_tag;
ref(bv, -bytevector_tag) = fix(len);
memcpy((char*)(bv+off_bytevector_data), ent->d_name, len+1);
return bv;
}
ikptr
ikrt_closedir(ikptr ptr, ikpcb* pcb){
DIR* d = (DIR*) ref(ptr, off_pointer_data);
int rv = closedir(d);
if (rv == -1){
return ik_errno_to_code();
}
return 0;
}