summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-07-20 07:13:40 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-07-20 07:13:40 -0700
commitd9afdbb32c0dd0b693e01b4204176d333805571b (patch)
treebb515cc1144e5de5127f332ac7f5a4a811192fa0
parent9cd58d83904fc531f214c3bc2f506c80d816f415 (diff)
downloadtxr-d9afdbb32c0dd0b693e01b4204176d333805571b.tar.gz
txr-d9afdbb32c0dd0b693e01b4204176d333805571b.tar.bz2
txr-d9afdbb32c0dd0b693e01b4204176d333805571b.zip
stat, lstat and dirstat now take struct param.
* ftw.c (ftw_callback): Pass nil to new parameter of stat_to_struct, to have a new stat struct allocated as before. * sysif.c (stat_to_struct, stat_impl, stat_wrap, lstat_wrap dirstat): New optional parameter that lets caller specify an existing struct object to fill. (sysif_init): Adjust registrations of stat, fstat, lstat and dirstat for new optional parameter. * sysif.h (stat_to_struct, stat_wrap): Declarations updated. * txr.1: Documented.
-rw-r--r--ftw.c2
-rw-r--r--sysif.c26
-rw-r--r--sysif.h4
-rw-r--r--txr.132
4 files changed, 41 insertions, 23 deletions
diff --git a/ftw.c b/ftw.c
index 4e911f2f..57790b4e 100644
--- a/ftw.c
+++ b/ftw.c
@@ -65,7 +65,7 @@ static int ftw_callback(const char *c_path, const struct stat *c_sb,
{
val path = string_utf8(c_path);
val type = num(c_type);
- val sb = stat_to_struct(*c_sb, path);
+ val sb = stat_to_struct(*c_sb, path, nil);
val level = num(fb->level);
val base = num(fb->base);
val result;
diff --git a/sysif.c b/sysif.c
index c76be87b..019b66a4 100644
--- a/sysif.c
+++ b/sysif.c
@@ -1145,10 +1145,10 @@ static val stat_to_list(struct stat st)
nao);
}
-val stat_to_struct(struct stat st, val path)
+val stat_to_struct(struct stat st, val path, val stat_opt)
{
args_decl(args, ARGS_MIN);
- val strct = make_struct(stat_s, nil, args);
+ val strct = default_arg(stat_opt, make_struct(stat_s, nil, args));
slotset(strct, dev_s, num(st.st_dev));
slotset(strct, ino_s, num(st.st_ino));
slotset(strct, mode_s, num(st.st_mode));
@@ -1184,7 +1184,7 @@ val stat_to_struct(struct stat st, val path)
#endif
static val stat_impl(val obj, int (*statfn)(val, struct stat *),
- val name, val path)
+ val name, val path, val stat_opt)
{
#if HAVE_SYS_STAT
struct stat st;
@@ -1197,20 +1197,20 @@ static val stat_impl(val obj, int (*statfn)(val, struct stat *),
}
return if3(opt_compat && opt_compat <= 113,
- stat_to_list(st), stat_to_struct(st, path));
+ stat_to_list(st), stat_to_struct(st, path, stat_opt));
#else
uw_throwf(file_error_s, lit("~a is not implemented"), name, nao);
#endif
}
-val stat_wrap(val path)
+val stat_wrap(val path, val stat_opt)
{
- return stat_impl(path, do_stat, lit("stat"), path);
+ return stat_impl(path, do_stat, lit("stat"), path, stat_opt);
}
-static val lstat_wrap(val path)
+static val lstat_wrap(val path, val stat_opt)
{
- return stat_impl(path, do_lstat, lit("lstat"), path);
+ return stat_impl(path, do_lstat, lit("lstat"), path, stat_opt);
}
#if HAVE_FILE_STAMP_CHANGE
@@ -2322,12 +2322,12 @@ static val readdir_wrap(val dirobj, val dirent_in)
}
}
-static val dirstat(val dirent, val dir_path)
+static val dirstat(val dirent, val dir_path, val stat_opt)
{
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 stat = stat_wrap(path, stat_opt);
val mode = slot(stat, mode_s);
if (mode) {
@@ -2660,11 +2660,11 @@ void sysif_init(void)
#endif
{
- val fn = func_n1(stat_wrap);
+ val fn = func_n2o(stat_wrap, 1);
reg_fun(intern(lit("stat"), user_package), fn);
reg_fun(intern(lit("fstat"), user_package), fn);
}
- reg_fun(intern(lit("lstat"), user_package), func_n1(lstat_wrap));
+ reg_fun(intern(lit("lstat"), user_package), func_n2o(lstat_wrap, 1));
#if HAVE_SYS_STAT
#ifndef S_IFSOCK
@@ -2924,7 +2924,7 @@ 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));
+ reg_fun(intern(lit("dirstat"), user_package), func_n3o(dirstat, 2));
#ifdef DT_UNKNOWN
reg_varl(intern(lit("dt-unknown"), user_package), num_fast(DT_UNKNOWN));
diff --git a/sysif.h b/sysif.h
index f61ad6f4..d599c737 100644
--- a/sysif.h
+++ b/sysif.h
@@ -48,10 +48,10 @@ time_t c_time(val time, val self);
val num_time(time_t time);
#if HAVE_SYS_STAT
struct stat;
-val stat_to_struct(struct stat st, val path);
+val stat_to_struct(struct stat st, val path, val stat_opt);
val umask_wrap(val mask);
#endif
-val stat_wrap(val path);
+val stat_wrap(val path, val stat_opt);
val stdio_ftell(FILE *);
int stdio_fseek(FILE *, val, int whence);
#if HAVE_GETEUID
diff --git a/txr.1 b/txr.1
index e32cc3a9..e1c82a75 100644
--- a/txr.1
+++ b/txr.1
@@ -59755,9 +59755,9 @@ fields take on values of zero.
.coNP Functions @, stat @ lstat and @ fstat
.synb
-.mets (stat >> { path | < stream | << fd })
+.mets (stat >> { path | < stream | << fd } <> [ struct ])
.mets (lstat << path )
-.mets (fstat >> { path | stream | << fd })
+.mets (fstat >> { path | stream | << fd } <> [ struct ])
.syne
.desc
The
@@ -59780,9 +59780,22 @@ is thrown.
If the object is not found or cannot be
accessed, an exception is thrown.
-Otherwise, information is retrieved and returned, in the form
-of a structure of type
+
+Otherwise, if the
+.meta struct
+argument is missing, information is retrieved and returned, in the form of a
+new structure of type
.codn stat .
+If the
+.meta struct
+argument is present, it must be either: an instance of the
+.code struct
+structure type, or of a type derived from that type by inheritance, or
+else structure type which has all the same slots as the
+.code struct
+type. The retrieved information is stored into
+.meta struct
+and that object is returned rather than a new object.
If
.meta path
@@ -63129,7 +63142,7 @@ when the handle indicates that no more directory entries remain to be traversed.
.coNP Function @ dirstat
.synb
-.mets (dirstat < dirent-struct <> [ dir-path ])
+.mets (dirstat < dirent-struct >> [ dir-path <> [ struct ]])
.syne
.desc
The
@@ -63144,9 +63157,14 @@ sets the
.code type
slot of the
.meta dirent-struct
-accordingly, and also returns the
+accordingly, and then returns the value that
.code stat
-structure.
+returned.
+
+If the
+.meta struct
+argument is specified, it is passed to
+.codn stat .
The
.meta dir-path