From nobody Wed Jul 9 17:09:55 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bckxJ1713z60hPZ; Wed, 09 Jul 2025 17:09:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bckxH5TKSz4HH3; Wed, 09 Jul 2025 17:09:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1752080995; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/lEYsV2Job5WQNm3Q9hGohjEAzWOBGeBx2XkWCBiBlQ=; b=gGdhs8yx/p41G3mijMLdQUxDGFstVUse3bD7mhuJ2ozYzVYmDhFBUpBUIDbNbpdq+2+Hzz HFAZQpgKh5oRu57Dl0eP09x6dERj9XZmqLzx2dBv2qfvY/msZPU90LkmD889LPcMXSLjZz NIwL6gHVkcUHz5gKWClkXStxyeNVn24N/88t/w2F4Le3s9QZ15EGL72g7nmYOK3X5wrwh3 i308qBsYj9gDS1CPs9CS+Jb6wC8YzbPV/DhYNyRv/s4EAk5WGwTzzoIyJHb2zzvPXJTZGF VsX8UbEe0qDx/qBCZWpChfVJ7h55PXgJa6d43hYTxmNt2T/NViD4KpvR4py5tA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1752080995; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/lEYsV2Job5WQNm3Q9hGohjEAzWOBGeBx2XkWCBiBlQ=; b=R0fJwV9yEgh4sYy//ENBVHOCURtrmDQt54PrAQl1NcMu86TE5rXwT3CVRmCPZG5Mqm05Re 0zmOUsq3a3HvtDbYeyc/m7/r78GCgDMUWKNVKlUJDEka08qRjgVYN/iQNxxvgnIAEkefzc mbKYZvGSmWLcckc8QB9BfrOSSokhV1RSXAkfrYMmt17exBCtYPf12JkgStAy65ttMN+bL6 PXU5HWHyRoZAqHJjpBVGw2gXlzhNS6FpMp/SE6Map+EFrUBziMH31ygzJdk8qmyPFrV5GC 2awA+eDWPU8itQ6un7E/RSmxbTrOHyOkJG45GcN5fZKZnOI1IaghCYLM+E37Eg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1752080995; a=rsa-sha256; cv=none; b=IT7jX6M8vKWElLv9EJATlV6/St6vT9zw6armpD89VXNUMelCFRpq2I/IkbKJCibN0siftk W0ACPvl0j71601OS6TfW97I6jiYf7bWbiXLVDPTjZlcgmfu/wWdkY/MZA4EvUcnhs4Rgwj 4KzSKaDQhnepTNED5BZbx+BUIw6wBMrRMqQomp6V1UWqOZBPdtEttVH2C4r7iNLIv+OGx+ iRbdjQyie/ZmKrf6WAKEadtZ6wJWwSCvTF1TH4/0dcHVfwrnHv9ym/jhk7Ej0hJDnkjQj5 lNseUc945UbHZ0UIxQcilRYIplkQ6nOgbg2GE1Q+SkKJKIdt3j1xL1YkiTwlWA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bckxH4w3vzWqj; Wed, 09 Jul 2025 17:09:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 569H9tLb072781; Wed, 9 Jul 2025 17:09:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 569H9tFk072778; Wed, 9 Jul 2025 17:09:55 GMT (envelope-from git) Date: Wed, 9 Jul 2025 17:09:55 GMT Message-Id: <202507091709.569H9tFk072778@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 2d6b33f801d5 - main - cp: Add an option to visit sources in order. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2d6b33f801d5352b8e078db83f6c90f6fe8291bb Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=2d6b33f801d5352b8e078db83f6c90f6fe8291bb commit 2d6b33f801d5352b8e078db83f6c90f6fe8291bb Author: Dag-Erling Smørgrav AuthorDate: 2025-07-09 17:06:07 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2025-07-09 17:07:13 +0000 cp: Add an option to visit sources in order. This adds a --sort option which makes cp pass a comparison function to FTS, ensuring that sources are visited and traversed in a predictable order. This will help make certain test cases more reliable. Sponsored by: Klara, Inc. Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D51214 --- bin/cp/cp.1 | 12 ++++++++++++ bin/cp/cp.c | 14 ++++++++++++-- bin/cp/tests/cp_test.sh | 4 ++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/bin/cp/cp.1 b/bin/cp/cp.1 index 6edc8e403acd..5231fa72621c 100644 --- a/bin/cp/cp.1 +++ b/bin/cp/cp.1 @@ -184,6 +184,18 @@ If the source file has both its set-user-ID and set-group-ID bits on, and either the user ID or group ID cannot be preserved, neither the set-user-ID nor set-group-ID bits are preserved in the copy's permissions. +.It Fl -sort +Visit and traverse sources in (non-localized) lexicographical order. +Normally, +.Nm +visits the sources in the order they were listed on the command line, +and if recursing, traverses their contents in whichever order they +were returned in by the kernel, which may be the order in which they +were created, lexicographical order, or something else entirely. +With +.Fl -sort , +the sources are both visited and traversed in lexicographical order. +This is mostly useful for testing. .It Fl s , Fl -symbolic-link Create symbolic links to regular files in a hierarchy instead of copying. .It Fl v , Fl -verbose diff --git a/bin/cp/cp.c b/bin/cp/cp.c index a1b62084a790..38fe65399d06 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -71,7 +71,7 @@ static char dot[] = "."; #define END(buf) (buf + sizeof(buf)) PATH_T to = { .dir = -1, .end = to.path }; bool Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag; -static bool Hflag, Lflag, Pflag, Rflag, rflag; +static bool Hflag, Lflag, Pflag, Rflag, rflag, Sflag; volatile sig_atomic_t info; enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; @@ -96,6 +96,7 @@ static const struct option long_opts[] = { "symbolic-link", no_argument, NULL, 's' }, { "verbose", no_argument, NULL, 'v' }, { "one-file-system", no_argument, NULL, 'x' }, + { "sort", no_argument, NULL, SORT_OPT }, { 0 } }; @@ -167,6 +168,9 @@ main(int argc, char *argv[]) case 'x': fts_options |= FTS_XDEV; break; + case SORT_OPT: + Sflag = true; + break; default: usage(); } @@ -284,6 +288,12 @@ main(int argc, char *argv[]) &to_stat))); } +static int +ftscmp(const FTSENT * const *a, const FTSENT * const *b) +{ + return (strcmp((*a)->fts_name, (*b)->fts_name)); +} + static int copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) { @@ -327,7 +337,7 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) } level = FTS_ROOTLEVEL; - if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) + if ((ftsp = fts_open(argv, fts_options, Sflag ? ftscmp : NULL)) == NULL) err(1, "fts_open"); for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh index 6adbc45c5009..3c3dd309b9e4 100755 --- a/bin/cp/tests/cp_test.sh +++ b/bin/cp/tests/cp_test.sh @@ -657,7 +657,7 @@ unrdir_body() atf_check \ -s exit:1 \ -e match:"^cp: src/b: Permission denied" \ - cp -R src dst + cp -R --sort src dst atf_check test -d dst/a atf_check cmp src/a/f dst/a/f atf_check test -d dst/b @@ -681,7 +681,7 @@ unrfile_body() atf_check \ -s exit:1 \ -e match:"^cp: src/b: Permission denied" \ - cp -R src dst + cp -R --sort src dst atf_check test -d dst atf_check cmp src/a dst/a atf_check test ! -e dst/b