aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2012-08-31 14:51:53 +0300
committerArnold D. Robbins <arnold@skeeve.com>2012-08-31 14:51:53 +0300
commit1dcb6bf5de886c0fdefa9e68557f348e3d5ec450 (patch)
tree34fdde986790e17c1bb9053ccfe3dcb558d81911
parent9b8770d74f2e1cfd719fa0dbf21c676d1c64e8ea (diff)
downloadegawk-1dcb6bf5de886c0fdefa9e68557f348e3d5ec450.tar.gz
egawk-1dcb6bf5de886c0fdefa9e68557f348e3d5ec450.tar.bz2
egawk-1dcb6bf5de886c0fdefa9e68557f348e3d5ec450.zip
Improve readdir extension.
-rw-r--r--extension/ChangeLog6
-rw-r--r--extension/readdir.3am12
-rw-r--r--extension/readdir.c32
-rw-r--r--test/readdir.awk2
4 files changed, 42 insertions, 10 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 899f72d1..9b5affc3 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,9 @@
+2012-08-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readdir.c: Have three states, 0, 1, 2 for never, fallback, and
+ always.
+ * readdir.3am: Adjust appropriately.
+
2012-08-29 Arnold D. Robbins <arnold@skeeve.com>
Make fts work everywhere by using our own source.
diff --git a/extension/readdir.3am b/extension/readdir.3am
index 9cb4862e..e7c6ee4f 100644
--- a/extension/readdir.3am
+++ b/extension/readdir.3am
@@ -5,7 +5,7 @@ readdir \- directory input parser for gawk
.ft CW
@load "readdir"
.sp
-readdir_do_ftype(1) # or 0
+readdir_do_ftype(2) # or 0 or 1
.ft R
.SH DESCRIPTION
The
@@ -43,12 +43,16 @@ for a socket, and
(unknown) for anything else.
.PP
On systems without the file type information, calling
-.B readdir_do_ftype(1)
+.B readdir_do_ftype(2)
causes the extension to use
.IR stat (2)
to retrieve the appropriate information. This is not the default, since
.IR stat (2)
-is a potentially expensive operation.
+is a potentially expensive operation. By calling
+.B readdir_do_ftype(0)
+one can ensure that the file type
+information is never displayed, even when readily available in the
+directory entry.
.SH NOTES
On GNU/Linux systems, there are filesystems that don't support the
.B d_type
@@ -57,7 +61,7 @@ entry (see
and so the file type is always
.BR u .
Therefore, using
-.B readdir_do_ftype(1)
+.B readdir_do_ftype(2)
is advisable even on GNU/Linux systems. In this case, the
.I readdir
extension will fall back to using
diff --git a/extension/readdir.c b/extension/readdir.c
index 220d1725..14039c8b 100644
--- a/extension/readdir.c
+++ b/extension/readdir.c
@@ -62,7 +62,18 @@ static awk_bool_t (*init_func)(void) = init_readdir;
int plugin_is_GPL_compatible;
-static int do_ftype;
+/*
+ * ftype <= 0: never return file type info
+ * ftype == 1: return file type info only if it is available in dirent
+ * ftype >= 2: always return file type info, calling fstat if necessary
+ */
+static int do_ftype =
+#ifdef DT_BLK
+ 1
+#else
+ 0
+#endif
+ ;
/* ftype --- return type of file as a single character string */
@@ -91,7 +102,15 @@ ftype(struct dirent *entry)
}
#endif
- if (! do_ftype || lstat(entry->d_name, & sbuf) < 0)
+ if (do_ftype < 2)
+ /*
+ * Avoid "/u" since user did not insist on file type info,
+ * and it does not seem to be supported by dirent on this
+ * filesystem.
+ */
+ return NULL;
+
+ if (lstat(entry->d_name, & sbuf) < 0)
return "u";
switch (sbuf.st_mode & S_IFMT) {
@@ -157,8 +176,11 @@ dir_get_record(char **out, struct iobuf_public *iobuf, int *errcode,
len = sprintf(the_dir->buf, "%llu/%s",
(unsigned long long) dirent->d_ino,
dirent->d_name);
- if (do_ftype)
- len += sprintf(the_dir->buf + len, "/%s", ftype(dirent));
+ if (do_ftype > 0) {
+ const char *ftstr = ftype(dirent);
+ if (ftstr)
+ len += sprintf(the_dir->buf + len, "/%s", ftstr);
+ }
*out = the_dir->buf;
@@ -286,7 +308,7 @@ do_readdir_do_ftype(int nargs, awk_value_t *result)
goto out;
}
- do_ftype = (flag.num_value != 0.0);
+ do_ftype = flag.num_value;
out:
return result;
diff --git a/test/readdir.awk b/test/readdir.awk
index 4d35be6a..3ec664df 100644
--- a/test/readdir.awk
+++ b/test/readdir.awk
@@ -1,7 +1,7 @@
@load "readdir"
BEGIN {
- readdir_do_ftype(1)
+ readdir_do_ftype(2)
}
{ print }