rmdir.c revision 1
1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1992-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * Glenn Fowler
1N/A * AT&T Research
1N/A *
1N/A * rmdir
1N/A */
1N/A
1N/Astatic const char usage[] =
1N/A"[-?\n@(#)$Id: rmdir (AT&T Research) 2006-08-24 $\n]"
1N/AUSAGE_LICENSE
1N/A"[+NAME?rmdir - remove empty directories]"
1N/A"[+DESCRIPTION?\brmdir\b deletes each given directory. The directory "
1N/A "must be empty; containing no entries other than \b.\b or \b..\b. "
1N/A "If a directory and a subdirectory of that directory are specified "
1N/A "as operands, the subdirectory must be specified before the parent "
1N/A "so that the parent directory will be empty when \brmdir\b attempts "
1N/A "to remove it.]"
1N/A"[e:ignore-fail-on-non-empty?Ignore each non-empty directory failure.]"
1N/A"[p:parents?Remove each explicit \adirectory\a argument directory that "
1N/A "becomes empty after its child directories are removed.]"
1N/A"[s:suppress?Suppress the message printed on the standard error when "
1N/A "\b-p\b is in effect.]"
1N/A"\n"
1N/A"\ndirectory ...\n"
1N/A"\n"
1N/A"[+EXIT STATUS?]{"
1N/A "[+0?All directories deleted successfully.]"
1N/A "[+>0?One or more directories could not be deleted.]"
1N/A"}"
1N/A"[+SEE ALSO?\bmkdir\b(1), \brm\b(1), \brmdir\b(2), \bunlink\b(2)]"
1N/A;
1N/A
1N/A#include <cmd.h>
1N/A
1N/Aint
1N/Ab_rmdir(int argc, char** argv, void* context)
1N/A{
1N/A register char* dir;
1N/A register char* end;
1N/A register int n;
1N/A int eflag = 0;
1N/A int pflag = 0;
1N/A int sflag = 0;
1N/A
1N/A cmdinit(argc, argv, context, ERROR_CATALOG, 0);
1N/A for (;;)
1N/A {
1N/A switch (optget(argv, usage))
1N/A {
1N/A case 'e':
1N/A eflag = 1;
1N/A continue;
1N/A case 'p':
1N/A pflag = 1;
1N/A continue;
1N/A case 's':
1N/A sflag = 1;
1N/A continue;
1N/A case ':':
1N/A error(2, "%s", opt_info.arg);
1N/A break;
1N/A case '?':
1N/A error(ERROR_usage(2), "%s", opt_info.arg);
1N/A break;
1N/A }
1N/A break;
1N/A }
1N/A argv += opt_info.index;
1N/A if (error_info.errors || !*argv)
1N/A error(ERROR_usage(2), "%s", optusage(NiL));
1N/A if (!pflag)
1N/A sflag = 0;
1N/A while (dir = *argv++)
1N/A {
1N/A end = dir;
1N/A if (pflag) end += strlen(dir);
1N/A n = 0;
1N/A for (;;)
1N/A {
1N/A if (rmdir(dir) < 0)
1N/A {
1N/A if (!eflag || errno != EEXIST
1N/A#ifdef ENOTEMPTY
1N/A && errno != ENOTEMPTY
1N/A#endif
1N/A )
1N/A {
1N/A if (sflag)
1N/A error_info.errors++;
1N/A else
1N/A error(ERROR_system(0), "%s: cannot remove", dir);
1N/A }
1N/A break;
1N/A }
1N/A if (n) *end = '/';
1N/A else n = 1;
1N/A do if (end <= dir) goto next; while (*--end != '/');
1N/A do if (end <= dir) goto next; while (*(end - 1) == '/' && end--);
1N/A *end = 0;
1N/A }
1N/A next: ;
1N/A }
1N/A return(error_info.errors != 0);
1N/A}
1N/A