rmdir.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. //applet:IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir))
  15. //kbuild:lib-$(CONFIG_RMDIR) += rmdir.o
  16. /* BB_AUDIT SUSv3 compliant */
  17. /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
  18. //usage:#define rmdir_trivial_usage
  19. //usage: "[-p] DIRECTORY..."
  20. //usage:#define rmdir_full_usage "\n\n"
  21. //usage: "Remove DIRECTORY if it is empty\n"
  22. //usage: "\n -p Include parents"
  23. //usage: IF_LONG_OPTS(
  24. //usage: "\n --ignore-fail-on-non-empty"
  25. //usage: )
  26. //usage:
  27. //usage:#define rmdir_example_usage
  28. //usage: "# rmdir /tmp/foo\n"
  29. #include "libbb.h"
  30. /* This is a NOFORK applet. Be very careful! */
  31. #define PARENTS (1 << 0)
  32. #define VERBOSE ((1 << 1) * ENABLE_FEATURE_VERBOSE)
  33. #define IGNORE_NON_EMPTY ((1 << 2) * ENABLE_LONG_OPTS)
  34. int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  35. int rmdir_main(int argc UNUSED_PARAM, char **argv)
  36. {
  37. int status = EXIT_SUCCESS;
  38. int flags;
  39. char *path;
  40. flags = getopt32long(argv, "pv",
  41. "parents\0" No_argument "p"
  42. /* Debian etch: many packages fail to be purged or installed
  43. * because they desperately want this option: */
  44. "ignore-fail-on-non-empty\0" No_argument "\xff"
  45. IF_FEATURE_VERBOSE(
  46. "verbose\0" No_argument "v"
  47. )
  48. );
  49. argv += optind;
  50. if (!*argv) {
  51. bb_show_usage();
  52. }
  53. do {
  54. path = *argv;
  55. while (1) {
  56. if (flags & VERBOSE) {
  57. printf("rmdir: removing directory, '%s'\n", path);
  58. }
  59. if (rmdir(path) < 0) {
  60. #if ENABLE_LONG_OPTS
  61. if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY)
  62. break;
  63. #endif
  64. bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */
  65. status = EXIT_FAILURE;
  66. } else if (flags & PARENTS) {
  67. /* Note: path was not "" since rmdir succeeded. */
  68. path = dirname(path);
  69. /* Path is now just the parent component. Dirname
  70. * returns "." if there are no parents.
  71. */
  72. if (NOT_LONE_CHAR(path, '.')) {
  73. continue;
  74. }
  75. }
  76. break;
  77. }
  78. } while (*++argv);
  79. return status;
  80. }