aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-10-11 02:59:54 -0500
committerRob Landley <rob@landley.net>2020-10-11 02:59:54 -0500
commit67bd0be1a4ed817954c9dcededf9bd9cb8c2f431 (patch)
tree4df0aa1044af467469e77c757bbf58dffe2f6178 /lib
parent0f2658c806586190be3aca21826e77fff9e50f1b (diff)
downloadtoybox-67bd0be1a4ed817954c9dcededf9bd9cb8c2f431.tar.gz
toysh: more variable/wildcard plumbing and tests.
Diffstat (limited to 'lib')
-rw-r--r--lib/dirtree.c13
-rw-r--r--lib/lib.c19
-rw-r--r--lib/lib.h5
3 files changed, 30 insertions, 7 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c
index 2bd7c404..70b567d2 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -53,12 +53,13 @@ struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags)
// Allocate/populate return structure
dt = xmalloc((len = sizeof(struct dirtree)+len+1)+linklen);
- memset(dt, 0, statless ? offsetof(struct dirtree, again)
+ memset(dt, 0, statless ? sizeof(struct dirtree)+1
: offsetof(struct dirtree, st));
dt->parent = parent;
dt->again = statless ? 2 : 0;
if (!statless) memcpy(&dt->st, &st, sizeof(struct stat));
- strcpy(dt->name, name ? name : "");
+ if (name) strcpy(dt->name, name);
+ else dt->st.st_mode = S_IFDIR;
if (linklen) dt->symlink = memcpy(len+(char *)dt, libbuf, linklen);
return dt;
@@ -142,10 +143,12 @@ int dirtree_recurse(struct dirtree *node,
{
struct dirtree *new, **ddt = &(node->child);
struct dirent *entry;
- DIR *dir;
+ DIR *dir = 0;
- node->dirfd = dirfd;
- if (node->dirfd == -1 || !(dir = fdopendir(node->dirfd))) {
+ // Why doesn't fdopendir() support AT_FDCWD?
+ if (AT_FDCWD == (node->dirfd = dirfd)) dir = opendir(".");
+ else if (node->dirfd != -1) dir = fdopendir(node->dirfd);
+ if (!dir) {
if (!(flags & DIRTREE_SHUTUP)) {
char *path = dirtree_path(node, 0);
perror_msg_raw(path);
diff --git a/lib/lib.c b/lib/lib.c
index 752fd0a1..c4e70dfe 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -346,6 +346,25 @@ int stridx(char *haystack, char needle)
return off-haystack;
}
+// Convert wc to utf8, returning bytes written. Does not null terminate.
+int wctoutf8(char *s, unsigned wc)
+{
+ int len = (wc>0x7ff)+(wc>0xffff), mask = 12+len+!!len;
+
+ if (wc<128) {
+ *s = wc;
+ return 1;
+ } else {
+ do {
+ s[1+len] = 0x80+(wc&0x3f);
+ wc >>= 7;
+ } while (len--);
+ *s = wc|mask;
+ }
+
+ return 2+len;
+}
+
// Convert utf8 sequence to a unicode wide character
// returns bytes consumed, or -1 if err, or -2 if need more data.
int utf8towc(wchar_t *wc, char *str, unsigned len)
diff --git a/lib/lib.h b/lib/lib.h
index db851631..6851c4aa 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -74,11 +74,11 @@ void get_optflags(void);
// Don't warn about failure to stat
#define DIRTREE_SHUTUP 16
// Breadth first traversal, conserves filehandles at the expense of memory
-#define DIRTREE_BREADTH 32
+#define DIRTREE_BREADTH 32 // TODO not implemented yet
// skip non-numeric entries
#define DIRTREE_PROC 64
// Return files we can't stat
-#define DIRTREE_STATLESS 128
+#define DIRTREE_STATLESS 128
// Don't look at any more files in this directory.
#define DIRTREE_ABORT 256
@@ -229,6 +229,7 @@ long long xstrtol(char *str, char **end, int base);
long long atolx(char *c);
long long atolx_range(char *numstr, long long low, long long high);
int stridx(char *haystack, char needle);
+int wctoutf8(char *s, unsigned wc);
int utf8towc(wchar_t *wc, char *str, unsigned len);
char *strlower(char *s);
char *strafter(char *haystack, char *needle);