summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c23
-rw-r--r--txr.137
2 files changed, 57 insertions, 3 deletions
diff --git a/sysif.c b/sysif.c
index 6af1aca2..2ac7ad29 100644
--- a/sysif.c
+++ b/sysif.c
@@ -2231,7 +2231,10 @@ struct dir {
static void opendir_free(val obj)
{
struct dir *d = coerce(struct dir *, obj->co.handle);
- closedir(d->dir);
+ if (d->dir != 0) {
+ closedir(d->dir);
+ d->dir = 0;
+ }
free(d);
}
@@ -2262,14 +2265,29 @@ static val opendir_wrap(val path, val prefix_p)
}
}
+static val closedir_wrap(val dirobj)
+{
+ val self = lit("closedir");
+ struct dir *d = coerce(struct dir *, cobj_handle(self, dirobj, dir_s));
+
+ if (d->dir != 0) {
+ closedir(d->dir);
+ d->dir = 0;
+ return t;
+ }
+
+ return nil;
+}
+
static val readdir_wrap(val dirobj, val dirent_in)
{
val self = lit("readdir");
struct dir *d = coerce(struct dir *, cobj_handle(self, dirobj, dir_s));
- struct dirent *dent = readdir(d->dir);
+ struct dirent *dent = if3(d->dir != 0, readdir(d->dir), 0);
for (;;) {
if (dent == 0) {
+ closedir_wrap(dirobj);
return nil;
} else if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
dent = readdir(d->dir);
@@ -2864,6 +2882,7 @@ void sysif_init(void)
list(name_s, ino_s, type_s, nao),
nil, nil, nil, nil);
reg_fun(intern(lit("opendir"), user_package), func_n2o(opendir_wrap, 1));
+ reg_fun(intern(lit("closedir"), user_package), func_n1(closedir_wrap));
reg_fun(intern(lit("readdir"), user_package), func_n2o(readdir_wrap, 1));
#ifdef DT_BLK
diff --git a/txr.1 b/txr.1
index a86d5e6c..4fd20484 100644
--- a/txr.1
+++ b/txr.1
@@ -62862,6 +62862,10 @@ If no more directory entries remain, then
.code readdir
returns
.codn nil .
+In this situation, the
+.meta dir-handle
+is also closed, as if by a call to
+.codn closedir .
Otherwise, the next available directory entry is returned as a
structure object of type
@@ -62869,7 +62873,7 @@ structure object of type
The
.code readdir
-function intenally skips and does not report the
+function internally skips and does not report the
.str .
(dot)
and
@@ -62891,6 +62895,37 @@ allocates a fresh
.code dirent
structure.
+.coNP Function @ closedir
+.synb
+.mets (opendir << dir-handle )
+.syne
+.desc
+The
+.code closedir
+function terminates the directory traversal managed by
+.metn dir-handle ,
+releasing its resources.
+
+If this has already been done before,
+.code closedir
+returns
+.codn nil ,
+otherwise it returns
+.codn t .
+
+Further
+.code readdir
+calls on the same
+.meta dir-handle
+return
+.codn nil .
+
+Note: the
+.code readdir
+function implicitly closes
+.meta dir-handle
+when the handle indicates that no more directory entries remain to be traversed.
+
.SS* Unix Sockets
On platforms where the underlying system interface is available, \*(TX provides