Added open-directory-steam, directory-stream?, read-directory-stream,
and close-directory-stream as per bug 315804.
This commit is contained in:
parent
72b86818f0
commit
d63a9c1f51
|
@ -71,7 +71,10 @@
|
||||||
accept-connection accept-connection-nonblocking
|
accept-connection accept-connection-nonblocking
|
||||||
close-tcp-server-socket
|
close-tcp-server-socket
|
||||||
register-callback
|
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
|
close-tcp-server-socket
|
||||||
register-callback
|
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
|
||||||
))
|
))
|
||||||
|
|
||||||
;(define-syntax assert* (identifier-syntax assert))
|
;(define-syntax assert* (identifier-syntax assert))
|
||||||
|
@ -2569,6 +2575,63 @@
|
||||||
[else (die who "invalid argument" what)]))
|
[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*)
|
;(set-fd-nonblocking 0 'init '*stdin*)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1761
|
1762
|
||||||
|
|
|
@ -1271,6 +1271,10 @@
|
||||||
[directory-list i]
|
[directory-list i]
|
||||||
[make-directory i]
|
[make-directory i]
|
||||||
[delete-directory i]
|
[delete-directory i]
|
||||||
|
[directory-stream? i]
|
||||||
|
[open-directory-stream i]
|
||||||
|
[read-directory-stream i]
|
||||||
|
[close-directory-stream i]
|
||||||
[change-mode i]
|
[change-mode i]
|
||||||
[make-symbolic-link i]
|
[make-symbolic-link i]
|
||||||
[make-hard-link i]
|
[make-hard-link i]
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include "ikarus-data.h"
|
#include "ikarus-data.h"
|
||||||
|
|
||||||
extern ikptr ik_errno_to_code();
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue