From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 3883 invoked from network); 26 Mar 2021 09:46:15 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 26 Mar 2021 09:46:15 -0000 Received: (qmail 1866 invoked by uid 550); 26 Mar 2021 05:46:06 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 1836 invoked from network); 26 Mar 2021 05:46:05 -0000 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=uBq/5uDUREu98ZRVCrMwwh9NrULMebiIDOgbEcrTnfA=; b=T2xqsWgCKUKDIW01IcNFgCtIpT0CXmLtLa5er/YWhL3OFpwa/UGzzF3amV0clKVWD3 moisWDl3RgLvhmSOvJ8P+zGVSremWd5vv4FwCTHhNZlgQUOm0NtyacAjX4+AV7jZcrnm yU/Lz41FVlAaUxYTA8Ox5Ri1j5mDpU4SFo/TmbBdQCWBp6/PQ6LDTbOUecbyz6a/6uLd CHvFWbwNxAP/JhvqLVP95FzS39SWuiq5V3OSTczLeucq/X+xz4OELnJMEWIUSmUQ9vEI wHxAPrFXTLyrWry2f0wHMt25bT/iPe1VSvXfX6t+G5O8Kzju+5Poa9E+6HkmalM35HI+ dtcA== X-Gm-Message-State: AOAM5325teAHvhAdEnjqepuZQ/lv4cf3L1+QwbDiHK/mrsD8Tgbf3GBG GoGTXXFymHhT0KYbEGVTwhNm+S2IjG5mF+aazA9phJsGGehMejPMJqPiEih/wMZT0c6Ed/0dwC6 l6HzjwzlHVbZ6m5IgieB3bA== X-Received: by 2002:a17:902:d694:b029:e6:bc94:4931 with SMTP id v20-20020a170902d694b02900e6bc944931mr13716006ply.6.1616737551735; Thu, 25 Mar 2021 22:45:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzr1G/gyYM8vJlgq9E5sXtgpjd97ahLCbSpMFi2fmXo6SB+IA3q+qoWNjh/GaeDH0JBGVU97g== X-Received: by 2002:a17:902:d694:b029:e6:bc94:4931 with SMTP id v20-20020a170902d694b02900e6bc944931mr13715989ply.6.1616737551398; Thu, 25 Mar 2021 22:45:51 -0700 (PDT) From: Dominique Martinet To: musl@lists.openwall.com Cc: Dominique Martinet Date: Fri, 26 Mar 2021 14:44:56 +0900 Message-Id: <20210326054456.899700-1-dominique.martinet@atmark-techno.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [musl] [PATCH] nftw: implement FTW_ACTIONRETVAL 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 #include #include 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 #include +#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