Print this page
4815 Want rm support for -v option
4816 rm does not print error messages when -f is used
*** 18,36 ****
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
! * rm [-fiRr] file ...
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
--- 18,40 ----
*
* CDDL HEADER END
*/
/*
+ * Copyright 2014 Andrew Stormont.
+ */
+
+ /*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
! * rm [-fiRrv] file ...
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
*** 72,83 ****
static int rm(const char *, struct dlist *);
static int confirm(FILE *, const char *, ...);
static void memerror(void);
static int checkdir(struct dlist *, struct dlist *);
! static int errcnt;
! static boolean_t silent, interactive, recursive, ontty;
static char *pathbuf;
static size_t pathbuflen = MAXPATHLEN;
static int maxfds = MAXINT;
--- 76,92 ----
static int rm(const char *, struct dlist *);
static int confirm(FILE *, const char *, ...);
static void memerror(void);
static int checkdir(struct dlist *, struct dlist *);
! static int errcnt = 0;
!
! static boolean_t force = B_FALSE;
! static boolean_t interactive = B_FALSE;
! static boolean_t recursive = B_FALSE;
! static boolean_t ontty = B_FALSE;
! static boolean_t verbose = B_FALSE;
static char *pathbuf;
static size_t pathbuflen = MAXPATHLEN;
static int maxfds = MAXINT;
*** 93,120 ****
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
#endif
(void) textdomain(TEXT_DOMAIN);
! while ((c = getopt(argc, argv, "frRi")) != EOF)
switch (c) {
case 'f':
! silent = B_TRUE;
! #ifdef XPG4
interactive = B_FALSE;
- #endif
break;
case 'i':
interactive = B_TRUE;
! #ifdef XPG4
! silent = B_FALSE;
! #endif
break;
case 'r':
case 'R':
recursive = B_TRUE;
break;
case '?':
errflg = 1;
break;
}
--- 102,128 ----
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
#endif
(void) textdomain(TEXT_DOMAIN);
! while ((c = getopt(argc, argv, "frRiv")) != EOF)
switch (c) {
case 'f':
! force = B_TRUE;
interactive = B_FALSE;
break;
case 'i':
interactive = B_TRUE;
! force = B_FALSE;
break;
case 'r':
case 'R':
recursive = B_TRUE;
break;
+ case 'v':
+ verbose = B_TRUE;
+ break;
case '?':
errflg = 1;
break;
}
*** 130,141 ****
optind++;
argc -= optind;
argv = &argv[optind];
! if ((argc < 1 && !silent) || errflg) {
! (void) fprintf(stderr, gettext("usage: rm [-fiRr] file ...\n"));
exit(2);
}
ontty = isatty(STDIN_FILENO) != 0;
--- 138,150 ----
optind++;
argc -= optind;
argv = &argv[optind];
! if ((argc < 1 && !force) || errflg) {
! (void) fprintf(stderr,
! gettext("usage: rm [-fiRrv] file ...\n"));
exit(2);
}
ontty = isatty(STDIN_FILENO) != 0;
*** 326,340 ****
* call, we use the global pathbuf instead of the entry argument.
*/
pushfilename(entry);
if (fstatat(caller->fd, entry, &temp, AT_SYMLINK_NOFOLLOW) != 0) {
- if (!silent) {
(void) fprintf(stderr, "rm: %s: %s\n", pathbuf,
strerror(errno));
errcnt++;
- }
return (0);
}
if (S_ISDIR(temp.st_mode)) {
/*
--- 335,347 ----
*** 373,396 ****
frame.dev = temp.st_dev;
frame.ino = temp.st_ino;
frame.flags = 0;
flag = AT_REMOVEDIR;
! #ifdef XPG4
/*
* XCU4 and POSIX.2: If not interactive, check to see whether
* or not directory is readable or writable and if not,
* prompt user for response.
*/
! if (ontty && !interactive && !silent &&
faccessat(caller->fd, entry, W_OK|X_OK, AT_EACCESS) != 0 &&
!confirm(stderr,
gettext("rm: examine files in directory %s (%s/%s)? "),
pathbuf, yesstr, nostr)) {
return (0);
}
#endif
if (opendirat(caller->fd, entry, &frame) == -1) {
err = errno;
if (interactive) {
/*
--- 380,404 ----
frame.dev = temp.st_dev;
frame.ino = temp.st_ino;
frame.flags = 0;
flag = AT_REMOVEDIR;
! #ifndef SUS
/*
* XCU4 and POSIX.2: If not interactive, check to see whether
* or not directory is readable or writable and if not,
* prompt user for response.
*/
! if (ontty && !interactive && !force &&
faccessat(caller->fd, entry, W_OK|X_OK, AT_EACCESS) != 0 &&
!confirm(stderr,
gettext("rm: examine files in directory %s (%s/%s)? "),
pathbuf, yesstr, nostr)) {
return (0);
}
#endif
+
if (opendirat(caller->fd, entry, &frame) == -1) {
err = errno;
if (interactive) {
/*
*** 423,434 ****
errcnt++;
return (0);
}
}
/* If it's empty we may still be able to rm it */
! if (unlinkat(caller->fd, entry, flag) == 0)
return (0);
if (interactive)
err = errno;
(void) fprintf(stderr,
interactive ?
gettext("rm: Unable to remove directory %s: %s\n") :
--- 431,446 ----
errcnt++;
return (0);
}
}
/* If it's empty we may still be able to rm it */
! if (unlinkat(caller->fd, entry, flag) == 0) {
! if (verbose)
! (void) printf(gettext("removed "
! "directory: `%s'\n"), pathbuf);
return (0);
+ }
if (interactive)
err = errno;
(void) fprintf(stderr,
interactive ?
gettext("rm: Unable to remove directory %s: %s\n") :
*** 496,508 ****
if (interactive) {
if (!confirm(stderr, gettext("rm: remove %s (%s/%s)? "),
pathbuf, yesstr, nostr)) {
return (0);
}
! } else if (!silent && flag == 0) {
/*
! * If not silent, and stdin is a terminal, and there's
* no write access, and the file isn't a symbolic link,
* ask for permission. If flag is set, then we know it's
* a directory so we skip this test as it was done above.
*
* TRANSLATION_NOTE - The following message will contain the
--- 508,520 ----
if (interactive) {
if (!confirm(stderr, gettext("rm: remove %s (%s/%s)? "),
pathbuf, yesstr, nostr)) {
return (0);
}
! } else if (!force && flag == 0) {
/*
! * If not force, and stdin is a terminal, and there's
* no write access, and the file isn't a symbolic link,
* ask for permission. If flag is set, then we know it's
* a directory so we skip this test as it was done above.
*
* TRANSLATION_NOTE - The following message will contain the
*** 521,531 ****
pathbuf, temp.st_mode & 0777, yesstr, nostr)) {
return (0);
}
}
! if (unlinkat(caller->fd, entry, flag) != 0) {
err = errno;
if (err == ENOENT)
return (0);
if (flag != 0) {
--- 533,549 ----
pathbuf, temp.st_mode & 0777, yesstr, nostr)) {
return (0);
}
}
! if (unlinkat(caller->fd, entry, flag) == 0) {
! if (verbose)
! (void) printf(S_ISDIR(temp.st_mode) ?
! gettext("removed directory: `%s'\n") :
! gettext("removed `%s'\n"), pathbuf);
! return (0);
! } else {
err = errno;
if (err == ENOENT)
return (0);
if (flag != 0) {
*** 539,558 ****
err = ENOTEMPTY;
(void) fprintf(stderr,
gettext("rm: Unable to remove directory %s:"
" %s\n"), pathbuf, strerror(err));
}
} else {
- #ifndef XPG4
- if (!silent || interactive) {
- #endif
-
(void) fprintf(stderr,
gettext("rm: %s not removed: %s\n"),
pathbuf, strerror(err));
- #ifndef XPG4
- }
#endif
}
errcnt++;
}
return (0);
--- 557,571 ----
err = ENOTEMPTY;
(void) fprintf(stderr,
gettext("rm: Unable to remove directory %s:"
" %s\n"), pathbuf, strerror(err));
}
+ #ifndef SUS
} else {
(void) fprintf(stderr,
gettext("rm: %s not removed: %s\n"),
pathbuf, strerror(err));
#endif
}
errcnt++;
}
return (0);