diff options
-rw-r--r-- | sysif.c | 23 | ||||
-rw-r--r-- | txr.1 | 37 |
2 files changed, 57 insertions, 3 deletions
@@ -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 @@ -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 |