diff --git a/bin/rmdir/rmdir.1 b/bin/rmdir/rmdir.1 index 87ca1f1547f0..eb23c605050c 100644 --- a/bin/rmdir/rmdir.1 +++ b/bin/rmdir/rmdir.1 @@ -1,110 +1,111 @@ .\"- .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" the Institute of Electrical and Electronics Engineers, Inc. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd March 15, 2013 .Dt RMDIR 1 .Os .Sh NAME .Nm rmdir .Nd remove directories .Sh SYNOPSIS .Nm .Op Fl pv .Ar directory ... .Sh DESCRIPTION The .Nm utility removes the directory entry specified by each .Ar directory argument, provided it is empty. .Pp Arguments are processed in the order given. In order to remove both a parent directory and a subdirectory of that parent, the subdirectory must be specified first so the parent directory is empty when .Nm tries to remove it. .Pp The following option is available: .Bl -tag -width indent .It Fl p Each .Ar directory argument is treated as a pathname of which all components will be removed, if they are empty, starting with the last most component. (See .Xr rm 1 for fully non-discriminant recursive removal.) .It Fl v Be verbose, listing each directory as it is removed. .El .Sh EXIT STATUS The .Nm utility exits with one of the following values: .Bl -tag -width indent -.It Li 0 -Each directory entry specified by a +.It Er 0 +Each .Ar directory -operand -referred to an empty directory and was removed -successfully. -.It Li >0 -An error occurred. +referred to an empty directory and was removed successfully. +.It Er 1 +An error occurred while attempting to remove one or more directories. +.It Er 2 +Invalid arguments. .El .Sh EXAMPLES Remove the directory .Pa foobar , if it is empty: .Pp .Dl $ rmdir foobar .Pp Remove all directories up to and including .Pa cow , stopping at the first non-empty directory (if any): .Pp .Dl $ rmdir -p cow/horse/monkey .Sh SEE ALSO .Xr rm 1 +.Xr rmdir 2 .Sh STANDARDS The .Nm utility is expected to be .St -p1003.2 compatible. .Sh HISTORY A .Nm command appeared in .At v1 . diff --git a/bin/rmdir/rmdir.c b/bin/rmdir/rmdir.c index c5d3db831309..0a495018495c 100644 --- a/bin/rmdir/rmdir.c +++ b/bin/rmdir/rmdir.c @@ -1,116 +1,116 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include static int rm_path(char *); static void usage(void) __dead2; static int pflag; static int vflag; int main(int argc, char *argv[]) { int ch, errors; while ((ch = getopt(argc, argv, "pv")) != -1) switch(ch) { case 'p': pflag = 1; break; case 'v': vflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc == 0) usage(); for (errors = 0; *argv; argv++) { if (rmdir(*argv) < 0) { warn("%s", *argv); errors = 1; } else { if (vflag) printf("%s\n", *argv); if (pflag) errors |= rm_path(*argv); } } exit(errors); } static int rm_path(char *path) { char *p; p = path + strlen(path); while (--p > path && *p == '/') ; *++p = '\0'; while ((p = strrchr(path, '/')) != NULL) { /* Delete trailing slashes. */ while (--p >= path && *p == '/') ; *++p = '\0'; if (p == path) break; if (rmdir(path) < 0) { warn("%s", path); return (1); } if (vflag) printf("%s\n", path); } return (0); } static void usage(void) { (void)fprintf(stderr, "usage: rmdir [-pv] directory ...\n"); - exit(1); + exit(2); } diff --git a/bin/rmdir/tests/rmdir_test.sh b/bin/rmdir/tests/rmdir_test.sh index d443849258b6..ba80ac6204be 100644 --- a/bin/rmdir/tests/rmdir_test.sh +++ b/bin/rmdir/tests/rmdir_test.sh @@ -1,57 +1,57 @@ # # Copyright 2017 Shivansh Rai # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # usage_output='usage: rmdir' atf_test_case invalid_usage invalid_usage_head() { atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message" } invalid_usage_body() { - atf_check -s not-exit:0 -e match:"$usage_output" rmdir -p - atf_check -s not-exit:0 -e match:"$usage_output" rmdir -v + atf_check -s exit:2 -e match:"$usage_output" rmdir -p + atf_check -s exit:2 -e match:"$usage_output" rmdir -v } atf_test_case no_arguments no_arguments_head() { atf_set "descr" "Verify that rmdir(1) fails and generates a valid usage message when no arguments are supplied" } no_arguments_body() { - atf_check -s not-exit:0 -e match:"$usage_output" rmdir + atf_check -s exit:2 -e match:"$usage_output" rmdir } atf_init_test_cases() { atf_add_test_case invalid_usage atf_add_test_case no_arguments }