busybox/coreutils/rmdir.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * rmdir implementation for busybox
   4 *
   5 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
   6 *
   7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   8 */
   9//config:config RMDIR
  10//config:       bool "rmdir (3.5 kb)"
  11//config:       default y
  12//config:       help
  13//config:       rmdir is used to remove empty directories.
  14
  15//applet:IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir))
  16
  17//kbuild:lib-$(CONFIG_RMDIR) += rmdir.o
  18
  19/* BB_AUDIT SUSv3 compliant */
  20/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
  21
  22//usage:#define rmdir_trivial_usage
  23//usage:       "[OPTIONS] DIRECTORY..."
  24//usage:#define rmdir_full_usage "\n\n"
  25//usage:       "Remove DIRECTORY if it is empty\n"
  26//usage:     "\n        -p      Include parents"
  27//usage:        IF_LONG_OPTS(
  28//usage:     "\n        --ignore-fail-on-non-empty"
  29//usage:        )
  30//usage:
  31//usage:#define rmdir_example_usage
  32//usage:       "# rmdir /tmp/foo\n"
  33
  34#include "libbb.h"
  35
  36/* This is a NOFORK applet. Be very careful! */
  37
  38
  39#define PARENTS          (1 << 0)
  40#define VERBOSE          ((1 << 1) * ENABLE_FEATURE_VERBOSE)
  41#define IGNORE_NON_EMPTY ((1 << 2) * ENABLE_LONG_OPTS)
  42
  43int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  44int rmdir_main(int argc UNUSED_PARAM, char **argv)
  45{
  46        int status = EXIT_SUCCESS;
  47        int flags;
  48        char *path;
  49
  50        flags = getopt32long(argv, "pv",
  51                "parents\0"                  No_argument "p"
  52                /* Debian etch: many packages fail to be purged or installed
  53                 * because they desperately want this option: */
  54                "ignore-fail-on-non-empty\0" No_argument "\xff"
  55                IF_FEATURE_VERBOSE(
  56                "verbose\0"                  No_argument "v"
  57                )
  58        );
  59        argv += optind;
  60
  61        if (!*argv) {
  62                bb_show_usage();
  63        }
  64
  65        do {
  66                path = *argv;
  67
  68                while (1) {
  69                        if (flags & VERBOSE) {
  70                                printf("rmdir: removing directory, '%s'\n", path);
  71                        }
  72
  73                        if (rmdir(path) < 0) {
  74#if ENABLE_LONG_OPTS
  75                                if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY)
  76                                        break;
  77#endif
  78                                bb_perror_msg("'%s'", path);  /* Match gnu rmdir msg. */
  79                                status = EXIT_FAILURE;
  80                        } else if (flags & PARENTS) {
  81                                /* Note: path was not "" since rmdir succeeded. */
  82                                path = dirname(path);
  83                                /* Path is now just the parent component.  Dirname
  84                                 * returns "." if there are no parents.
  85                                 */
  86                                if (NOT_LONE_CHAR(path, '.')) {
  87                                        continue;
  88                                }
  89                        }
  90                        break;
  91                }
  92        } while (*++argv);
  93
  94        return status;
  95}
  96