diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-07-09 20:41:52 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-07-09 20:41:52 -0700 |
commit | 812e63ca8f42637f6a856e66f57678cbb0472821 (patch) | |
tree | 26209ed43872cafcf598cd7f62f50f298e50c1a7 /sysif.c | |
parent | 1d8d2214495fa29931948e08041cc8a1159fdd19 (diff) | |
download | txr-812e63ca8f42637f6a856e66f57678cbb0472821.tar.gz txr-812e63ca8f42637f6a856e66f57678cbb0472821.tar.bz2 txr-812e63ca8f42637f6a856e66f57678cbb0472821.zip |
Add dirstat function.
This function back-fills the missing d-type information in a
dirent on platforms that don't provide d_type in the native
dirent.
* sysif.c (DT_FIFO, DT_CHR, DT_DIR, DT_BLK, DT_REG, DT_LNK,
DT_SOCK): Define all these preprocessor symbols to their Linux
values on platforms where DT_DIR is not defined.
(DT_UNKNOWN): Make sure this symbol is #undef-d if DT_DIR
is not defined, so the corresponding dt-unknown variable does
not exist.
(dirstat): New static function.
(sysif_init): Register dirstat intrinsic. Register dt-fifo and
the rest unconditionally now. Changing their order to
increasing numeric.
* txr.1: Documented.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 65 |
1 files changed, 46 insertions, 19 deletions
@@ -102,6 +102,17 @@ #include "txr.h" #include "sysif.h" +#ifndef DT_DIR +#undef DT_UNKNOWN +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#endif + val stat_s; val dev_k, ino_k, mode_k, nlink_k, uid_k; val gid_k, rdev_k, size_k, blksize_k, blocks_k; @@ -2311,6 +2322,35 @@ static val readdir_wrap(val dirobj, val dirent_in) } } +static val dirstat(val dirent, val dir_path) +{ + val self = lit("dirstat"); + val name = slot(dirent, name_s); + val path = if3(null_or_missing_p(dir_path), name, path_cat(dir_path, name)); + val stat = stat_wrap(path); + val mode = slot(stat, mode_s); + + if (mode) { + cnum mod = c_num(mode, self); + val type = nil; + + switch (mod & S_IFMT) { + case S_IFBLK: type = num_fast(DT_BLK); break; + case S_IFCHR: type = num_fast(DT_CHR); break; + case S_IFDIR: type = num_fast(DT_DIR); break; + case S_IFIFO: type = num_fast(DT_FIFO); break; + case S_IFLNK: type = num_fast(DT_LNK); break; + case S_IFREG: type = num_fast(DT_REG); break; + case S_IFSOCK: type = num_fast(DT_SOCK); break; + } + + if (type) + slotset(dirent, type_s, type); + } + + return stat; +} + void sysif_init(void) { prot1(&at_exit_list); @@ -2884,29 +2924,16 @@ void sysif_init(void) 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)); + reg_fun(intern(lit("dirstat"), user_package), func_n2o(dirstat, 1)); -#ifdef DT_BLK - reg_varl(intern(lit("dt-blk"), user_package), num_fast(DT_BLK)); +#ifdef DT_UNKNOWN + reg_varl(intern(lit("dt-unknown"), user_package), num_fast(DT_UNKNOWN)); #endif -#ifdef DT_CHR + reg_varl(intern(lit("dt-fifo"), user_package), num_fast(DT_FIFO)); reg_varl(intern(lit("dt-chr"), user_package), num_fast(DT_CHR)); -#endif -#ifdef DT_DIR reg_varl(intern(lit("dt-dir"), user_package), num_fast(DT_DIR)); -#endif -#ifdef DT_FIFO - reg_varl(intern(lit("dt-fifo"), user_package), num_fast(DT_FIFO)); -#endif -#ifdef DT_LNK - reg_varl(intern(lit("dt-lnk"), user_package), num_fast(DT_LNK)); -#endif -#ifdef DT_REG + reg_varl(intern(lit("dt-blk"), user_package), num_fast(DT_BLK)); reg_varl(intern(lit("dt-reg"), user_package), num_fast(DT_REG)); -#endif -#ifdef DT_SOCK + reg_varl(intern(lit("dt-lnk"), user_package), num_fast(DT_LNK)); reg_varl(intern(lit("dt-sock"), user_package), num_fast(DT_SOCK)); -#endif -#ifdef DT_UNKNOWN - reg_varl(intern(lit("dt-unknown"), user_package), num_fast(DT_UNKNOWN)); -#endif } |