logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: b8bd2cabd1671d6de244fb0cefe009fd7769b20e
parent fa5fdb6f5acff7449c927c89b95e56958f420b8f
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Fri, 30 Aug 2024 09:33:07 +0200

cmd/rmdir: Add --ignore-fail-on-non-empty support

Diffstat:

Mcmd/rmdir.19+++++++--
Mcmd/rmdir.c19+++++++++++++++++--
Mtest-cmd/rmdir.t14++++++++++++++
Atest-cmd/rmdir_long.t18++++++++++++++++++
4 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/cmd/rmdir.1 b/cmd/rmdir.1 @@ -1,7 +1,7 @@ .\" utils-std: Collection of commonly available Unix tools .\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> .\" SPDX-License-Identifier: MPL-2.0 -.Dd 2024-03-26 +.Dd 2024-08-30 .Dt RMDIR 1 .Os .Sh NAME @@ -10,6 +10,7 @@ .Sh SYNOPSIS .Nm .Op Fl pv +.Op Fl -ignore-fail-on-non-empty .Ar directory... .Sh DESCRIPTION The @@ -18,6 +19,8 @@ utility removes each given .Ar directory . .Sh OPTIONS .Bl -tag -width aa +.It Fl -ignore-fail-on-non-empty +Ignore failures to remove non-empty directories .It Fl p Remove all parents directories present in the .Ar directory @@ -41,6 +44,8 @@ specification. .Pp The .Fl v -option is an extension. +and +.Fl -ignore-fail-on-non-empty +options are extensions. .Sh AUTHORS .An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me diff --git a/cmd/rmdir.c b/cmd/rmdir.c @@ -16,19 +16,26 @@ static void usage() { +#ifdef HAS_GETOPT_LONG + fprintf(stderr, "Usage: rmdir [-pv] [--ignore-fail-on-non-empty] directory...\n"); +#else fprintf(stderr, "Usage: rmdir [-pv] directory...\n"); +#endif } int main(int argc, char *argv[]) { - bool parents = false, verbose = false; + bool parents = false, verbose = false, ign_enotempty = false; int c = -1; #ifdef HAS_GETOPT_LONG - // Strictly for GNUisms compatibility so no long-only options // clang-format off + enum long_opt_vals { + IGN_ENOTEMPTY = 1 + }; static struct option opts[] = { + {"ignore-fail-on-non-empty", no_argument, 0, IGN_ENOTEMPTY}, {"parents", no_argument, 0, 'p'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}, @@ -43,6 +50,11 @@ main(int argc, char *argv[]) { switch(c) { +#ifdef HAS_GETOPT_LONG + case IGN_ENOTEMPTY: + ign_enotempty = true; + break; +#endif case 'p': parents = true; break; @@ -81,6 +93,8 @@ main(int argc, char *argv[]) char *path = argv[i]; if(rmdir(path) < 0) { + if(ign_enotempty && (errno == ENOTEMPTY || errno == EEXIST)) continue; + fprintf(stderr, "rmdir: Failed removing '%s': %s\n", path, strerror(errno)); err = 1; continue; @@ -102,6 +116,7 @@ main(int argc, char *argv[]) if(rmdir(path) < 0) { if(errno == ENOTDIR) break; + if(ign_enotempty && (errno == ENOTEMPTY || errno == EEXIST)) break; fprintf(stderr, "rmdir: Failed removing '%s': %s\n", path, strerror(errno)); err = 1; diff --git a/test-cmd/rmdir.t b/test-cmd/rmdir.t @@ -9,6 +9,7 @@ $ mkdir -p no_p/bar $ rmdir no_p/bar $ test -d no_p + $ rm -r no_p $ mkdir -p p/bar $ rmdir -p p/bar @@ -18,6 +19,7 @@ $ rmdir -v v_no_p/bar rmdir: Removed 'v_no_p/bar' $ test -d v_no_p + $ rm -r v_no_p $ mkdir -p v_p/bar $ rmdir -pv v_p/bar @@ -38,3 +40,15 @@ $ rmdir -pv file rmdir: Failed removing 'file': Not a directory [1] + $ rm file + + $ mkdir -p e_not_empty/a/b/c/d empty/a/b/c + $ rmdir -p e_not_empty/a/b/c empty/a/b/c + rmdir: Failed removing 'e_not_empty/a/b/c': Directory not empty + [1] + $ test -d e_not_empty/a/b/c + $ test ! -e empty + $ rm -r e_not_empty + + $ find . + . diff --git a/test-cmd/rmdir_long.t b/test-cmd/rmdir_long.t @@ -0,0 +1,18 @@ +#!/usr/bin/env cram +# SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +# SPDX-License-Identifier: MPL-2.0 + + $ export PATH="$TESTDIR/../cmd:$PATH" + + $ test "$(command -v rmdir)" = "$TESTDIR/../cmd/rmdir" + + $ grep -q HAS_GETOPT_LONG "${TESTDIR}/../config.mk" || return 80 + + $ mkdir -p e_not_empty-ign/a/b/c/d empty-ign/a/b/c + $ rmdir -p --ignore-fail-on-non-empty e_not_empty-ign/a/b/c empty-ign/a/b/c + $ test -d e_not_empty-ign/a/b/c + $ test ! -e empty-ign + $ rm -r e_not_empty-ign + + $ find . + .