Print this page
4815 Want rm support for -v option
4816 rm does not print error messages when -f is used

@@ -18,19 +18,23 @@
  *
  * 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 [-fiRr] file ...
+ * rm [-fiRrv] file ...
  */
 
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <dirent.h>

@@ -72,12 +76,17 @@
 
 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 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,28 +102,27 @@
 #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)
+        while ((c = getopt(argc, argv, "frRiv")) != EOF)
                 switch (c) {
                 case 'f':
-                        silent = B_TRUE;
-#ifdef XPG4
+                        force = B_TRUE;
                         interactive = B_FALSE;
-#endif
                         break;
                 case 'i':
                         interactive = B_TRUE;
-#ifdef XPG4
-                        silent = B_FALSE;
-#endif
+                        force = B_FALSE;
                         break;
                 case 'r':
                 case 'R':
                         recursive = B_TRUE;
                         break;
+                case 'v':
+                        verbose = B_TRUE;
+                        break;
                 case '?':
                         errflg = 1;
                         break;
                 }
 

@@ -130,12 +138,13 @@
                 optind++;
 
         argc -= optind;
         argv = &argv[optind];
 
-        if ((argc < 1 && !silent) || errflg) {
-                (void) fprintf(stderr, gettext("usage: rm [-fiRr] file ...\n"));
+        if ((argc < 1 && !force) || errflg) {
+                (void) fprintf(stderr,
+                    gettext("usage: rm [-fiRrv] file ...\n"));
                 exit(2);
         }
 
         ontty = isatty(STDIN_FILENO) != 0;
 

@@ -326,15 +335,13 @@
          * 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)) {
                 /*

@@ -373,24 +380,25 @@
                 frame.dev = temp.st_dev;
                 frame.ino = temp.st_ino;
                 frame.flags = 0;
                 flag = AT_REMOVEDIR;
 
-#ifdef XPG4
+#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 && !silent &&
+                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,12 +431,16 @@
                                         errcnt++;
                                         return (0);
                                 }
                         }
                         /* If it's empty we may still be able to rm it */
-                        if (unlinkat(caller->fd, entry, flag) == 0)
+                        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,13 +508,13 @@
         if (interactive) {
                 if (!confirm(stderr, gettext("rm: remove %s (%s/%s)? "),
                     pathbuf, yesstr, nostr)) {
                         return (0);
                 }
-        } else if (!silent && flag == 0) {
+        } else if (!force && flag == 0) {
                 /*
-                 * If not silent, and stdin is a terminal, and there's
+                 * 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,11 +533,17 @@
                     pathbuf, temp.st_mode & 0777, yesstr, nostr)) {
                         return (0);
                 }
         }
 
-        if (unlinkat(caller->fd, entry, flag) != 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,20 +557,15 @@
                                         err = ENOTEMPTY;
                                 (void) fprintf(stderr,
                                     gettext("rm: Unable to remove directory %s:"
                                     " %s\n"), pathbuf, strerror(err));
                         }
+#ifndef SUS
                 } 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);