summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-09-11 20:11:40 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-09-11 20:11:40 -0700
commite9902c952b488adf7de5c2464d416810ce222955 (patch)
treea7f7ef52a4fb344c1854a8d646cd98263aef9f67 /stream.c
parent46f607ae233a8f71c09d40dd45aae5f2ec7056fc (diff)
downloadtxr-e9902c952b488adf7de5c2464d416810ce222955.tar.gz
txr-e9902c952b488adf7de5c2464d416810ce222955.tar.bz2
txr-e9902c952b488adf7de5c2464d416810ce222955.zip
* configure: Added test for <sys/stat.h>
* eval.c: New intrinsic functions "stat" and "prop". * stream.c: Include <sys/stat.h> if we have it. (w_stat, statf): New functions. (val dev_k, ino_k, mode_k, nlink_k, uid_k, val gid_k, rdev_k, size_k, blksize_k, blocks_k; val atime_k, mtime_k, ctime_k): New sybol variables. (stream_init): Intern new keywords symbols. * stream.h (statf): Declared. * txr.1: prop documented. Stub for stat created.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/stream.c b/stream.c
index 8d37bc72..e3d8d962 100644
--- a/stream.c
+++ b/stream.c
@@ -40,6 +40,9 @@
#if HAVE_SYS_WAIT
#include <sys/wait.h>
#endif
+#if HAVE_SYS_STAT
+#include <sys/stat.h>
+#endif
#include "lib.h"
#include "gc.h"
#include "unwind.h"
@@ -49,6 +52,10 @@
val std_input, std_output, std_debug, std_error;
val output_produced;
+val dev_k, ino_k, mode_k, nlink_k, uid_k;
+val gid_k, rdev_k, size_k, blksize_k, blocks_k;
+val atime_k, mtime_k, ctime_k;
+
struct strm_ops {
struct cobj_ops cobj_ops;
val (*put_string)(val, val);
@@ -1475,6 +1482,46 @@ val flush_stream(val stream)
}
}
+#if HAVE_SYS_STAT
+static int w_stat(const wchar_t *wpath, struct stat *buf)
+{
+ char *path = utf8_dup_to(wpath);
+ int res = stat(path, buf);
+ free(path);
+ return res;
+}
+#endif
+
+val statf(val path)
+{
+#if HAVE_SYS_STAT
+ struct stat st;
+ int res = w_stat(c_str(path), &st);
+
+ if (res == -1)
+ uw_throwf(file_error_s, lit("unable to stat ~a: ~a/~s"),
+ path, num(errno), string_utf8(strerror(errno)), nao);
+
+ return list(dev_k, num(st.st_dev),
+ dev_k, num(st.st_dev),
+ ino_k, num(st.st_ino),
+ mode_k, num(st.st_mode),
+ nlink_k, num(st.st_nlink),
+ uid_k, num(st.st_uid),
+ gid_k, num(st.st_gid),
+ rdev_k, num(st.st_rdev),
+ size_k, num(st.st_size),
+ blksize_k, num(st.st_blksize),
+ blocks_k, num(st.st_blocks),
+ atime_k, num(st.st_atime),
+ mtime_k, num(st.st_mtime),
+ ctime_k, num(st.st_ctime),
+ nao);
+#else
+ uw_throwf(file_error_s, lit("stat is not implemented"), nao);
+#endif
+}
+
static DIR *w_opendir(const wchar_t *wname)
{
char *name = utf8_dup_to(wname);
@@ -1483,6 +1530,7 @@ static DIR *w_opendir(const wchar_t *wname)
return d;
}
+
val open_directory(val path)
{
DIR *d = w_opendir(c_str(path));
@@ -1673,4 +1721,18 @@ void stream_init(void)
std_debug = make_stdio_stream(stdout, string(L"debug"), nil, t);
std_error = make_stdio_stream(stderr, string(L"stderr"), nil, t);
detect_format_string();
+
+ dev_k = intern(lit("dev"), keyword_package);
+ ino_k = intern(lit("ino"), keyword_package);
+ mode_k = intern(lit("mode"), keyword_package);
+ nlink_k = intern(lit("nlink"), keyword_package);
+ uid_k = intern(lit("uid"), keyword_package);
+ gid_k = intern(lit("gid"), keyword_package);
+ rdev_k = intern(lit("rdev"), keyword_package);
+ size_k = intern(lit("size"), keyword_package);
+ blksize_k = intern(lit("blksize"), keyword_package);
+ blocks_k = intern(lit("blocks"), keyword_package);
+ atime_k = intern(lit("atime"), keyword_package);
+ mtime_k = intern(lit("mtime"), keyword_package);
+ ctime_k = intern(lit("ctime"), keyword_package);
}