mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Dominique Martinet <dominique.martinet@atmark-techno.com>
To: musl@lists.openwall.com
Cc: Dominique Martinet <dominique.martinet@atmark-techno.com>
Subject: [musl] [PATCH] nftw: implement FTW_ACTIONRETVAL
Date: Fri, 26 Mar 2021 14:44:56 +0900	[thread overview]
Message-ID: <20210326054456.899700-1-dominique.martinet@atmark-techno.com> (raw)

nftw is sometimes used with e.g. FTW_SKIP_SUBTREE on linux which
requires special handling.

A similar patch was sent in 2018[1] and general feedbacks for nftw
seemed positive, but the original work's license was not clear so this
implementation was made without using it, looking at the linux man page
and comparing with glibc's behaviour through test programs.

[1] https://www.openwall.com/lists/musl/2018/12/16/1
---
A few notes:
 - After checking there doesn't seem to be *that* many users, but there
still are quite a few, which can be found through debian code search:
https://codesearch.debian.net/search?q=FTW_SKIP_SUBTREE&literal=1&perpkg=1
I'm personally interested in this for bpftool (in linux's source tree,
tools/bpf/bpftool/perf.c ) which uses it to run through /proc/*/fd/*
skipping unrelated directories, on alpine linux.
If this is refused I'll try to push a workaround there but doing it in
musl would allow dropping other compat patches (e.g. aufs-tools) with
a similar problem.

 - I'm not happy that I had to copy the defines over, but I don't think
we can just define _GNU_SOURCE in nftw.c to get the values; if you have
any recommendation for this I would be happy to rework and test again

 - the man page isn't clear on what to do with SKIP_SUBTREE if the entry
is not a directory, but testing shows it is just ignored on glibc 2.31
so I didn't add any check. The code is simpler that way.

 - I looked into doing/modifying some test suite, but the only I could
find related to musl (libc-test) does not perform any runtime check on
nftw, so all my tests were just manually adjusting values and comparing.

Here is a trivial test program if that helps anyone:
---
#define _GNU_SOURCE
#include <ftw.h>
#include <string.h>
#include <stdio.h>

int cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
	printf("got %s\n", path);
	if (strcmp(path, "./src") == 0)
		return FTW_SKIP_SUBTREE;
	if (strcmp(path, "./.git/description") == 0) {
		return FTW_SKIP_SIBLINGS;
	}
	return 0;
}

int main() {
	int rc = nftw(".", cb, 10, FTW_ACTIONRETVAL);
	printf("rc %d\n", rc);
	return 0;
}
---

 include/ftw.h   |  8 ++++++++
 src/misc/nftw.c | 13 +++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/ftw.h b/include/ftw.h
index b15c062a8389..5b07855fefcc 100644
--- a/include/ftw.h
+++ b/include/ftw.h
@@ -21,6 +21,14 @@ extern "C" {
 #define FTW_CHDIR 4
 #define FTW_DEPTH 8
 
+#ifdef _GNU_SOURCE
+#define FTW_ACTIONRETVAL 0x10
+#define FTW_CONTINUE 0
+#define FTW_STOP 1
+#define FTW_SKIP_SUBTREE 2
+#define FTW_SKIP_SIBLINGS 3
+#endif
+
 struct FTW {
 	int base;
 	int level;
diff --git a/src/misc/nftw.c b/src/misc/nftw.c
index 8dcff7fefd2a..2994968dcbbe 100644
--- a/src/misc/nftw.c
+++ b/src/misc/nftw.c
@@ -8,6 +8,10 @@
 #include <limits.h>
 #include <pthread.h>
 
+#define FTW_ACTIONRETVAL 0x10
+#define FTW_SKIP_SUBTREE 2
+#define FTW_SKIP_SIBLINGS 3
+
 struct history
 {
 	struct history *chain;
@@ -100,6 +104,12 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,
 				path[j]='/';
 				strcpy(path+j+1, de->d_name);
 				if ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {
+					if (flags & FTW_ACTIONRETVAL) {
+						if (r == FTW_SKIP_SIBLINGS)
+							break;
+						if (r == FTW_SKIP_SUBTREE)
+							continue;
+					}
 					closedir(d);
 					return r;
 				}
@@ -136,6 +146,9 @@ int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, str
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 	r = do_nftw(pathbuf, fn, fd_limit, flags, NULL);
 	pthread_setcancelstate(cs, 0);
+	if ((flags & FTW_ACTIONRETVAL)
+	 && (r == FTW_SKIP_SIBLINGS || r == FTW_SKIP_SUBTREE))
+		r = 0;
 	return r;
 }
 
-- 
2.30.2


             reply	other threads:[~2021-03-26  9:46 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-26  5:44 Dominique Martinet [this message]
2021-04-12  5:53 ` [musl] " Dominique Martinet
2021-04-12  6:09 ` [musl] " Ariadne Conill
2021-04-12  6:45   ` Dominique Martinet
2021-04-12 14:17 ` Rich Felker
2021-04-12 23:25   ` Dominique Martinet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210326054456.899700-1-dominique.martinet@atmark-techno.com \
    --to=dominique.martinet@atmark-techno.com \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).