I just fatfingered a ';' into a ',':
$ rm a.out, cc mind.c
rm: a.out,: No such file or directory
rm: cc: No such file or directory
In full POSIX-conformance I lost my mind. Coincidentally I had an idea.
What do you think?
Index: bin/rm/rm.1
===================================================================
RCS file: /cvs/src/bin/rm/rm.1,v
retrieving revision 1.37
diff -u -p -r1.37 rm.1
--- bin/rm/rm.1 25 May 2014 19:07:36 -0000 1.37
+++ bin/rm/rm.1 17 Oct 2014 18:37:18 -0000
@@ -41,7 +41,7 @@
.Nd remove directory entries
.Sh SYNOPSIS
.Nm rm
-.Op Fl dfiPRr
+.Op Fl dfxiPRr
.Ar
.Sh DESCRIPTION
The
@@ -65,6 +65,17 @@ The
.Fl f
option overrides any previous
.Fl i
+or
+.Fl x
+options.
+.It Fl x
+Exit immediately on error, instead of processing any remaining arguments.
+The
+.Fl x
+option overrides any previous
+.Fl f
+or
+.Fl i
options.
.It Fl i
Request confirmation before attempting to remove each file, regardless of
@@ -74,6 +85,8 @@ The
.Fl i
option overrides any previous
.Fl f
+or
+.Fl x
options.
.It Fl P
Overwrite regular files before deleting them.
@@ -148,7 +161,7 @@ utility is compliant with the
specification.
.Pp
The flags
-.Op Fl dP
+.Op Fl dxP
are extensions to that specification.
.Sh HISTORY
An
Index: bin/rm/rm.c
===================================================================
RCS file: /cvs/src/bin/rm/rm.c,v
retrieving revision 1.29
diff -u -p -r1.29 rm.c
--- bin/rm/rm.c 21 May 2014 06:23:02 -0000 1.29
+++ bin/rm/rm.c 17 Oct 2014 18:37:18 -0000
@@ -40,6 +40,7 @@
#include <errno.h>
#include <fcntl.h>
#include <fts.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -49,7 +50,7 @@
extern char *__progname;
-int dflag, eval, fflag, iflag, Pflag, stdin_ok;
+int dflag, eval, fflag, xflag, iflag, Pflag, stdin_ok;
int check(char *, char *, struct stat *);
void checkdot(char **);
@@ -58,6 +59,8 @@ int rm_overwrite(char *, struct stat *);
int pass(int, off_t, char *, size_t);
void rm_tree(char **);
void usage(void);
+void warnerr(const char * fmt, ...);
+void warnerrx(const char * fmt, ...);
/*
* rm --
@@ -74,7 +77,7 @@ main(int argc, char *argv[])
setlocale(LC_ALL, "");
Pflag = rflag = 0;
- while ((ch = getopt(argc, argv, "dfiPRr")) != -1)
+ while ((ch = getopt(argc, argv, "dfxiPRr")) != -1)
switch(ch) {
case 'd':
dflag = 1;
@@ -82,10 +85,17 @@ main(int argc, char *argv[])
case 'f':
fflag = 1;
iflag = 0;
+ xflag = 0;
+ break;
+ case 'x':
+ fflag = 0;
+ iflag = 0;
+ xflag = 1;
break;
case 'i':
fflag = 0;
iflag = 1;
+ xflag = 0;
break;
case 'P':
Pflag = 1;
@@ -146,7 +156,7 @@ rm_tree(char **argv)
switch (p->fts_info) {
case FTS_DNR:
if (!fflag || p->fts_errno != ENOENT) {
- warnx("%s: %s",
+ warnerrx("%s: %s",
p->fts_path, strerror(p->fts_errno));
eval = 1;
}
@@ -161,7 +171,7 @@ rm_tree(char **argv)
if (!needstat)
break;
if (!fflag || p->fts_errno != ENOENT) {
- warnx("%s: %s",
+ warnerrx("%s: %s",
p->fts_path, strerror(p->fts_errno));
eval = 1;
}
@@ -209,7 +219,7 @@ rm_tree(char **argv)
(fflag && errno == ENOENT))
continue;
}
- warn("%s", p->fts_path);
+ warnerr("%s", p->fts_path);
eval = 1;
}
if (errno)
@@ -232,14 +242,14 @@ rm_file(char **argv)
/* Assume if can't stat the file, can't unlink it. */
if (lstat(f, &sb)) {
if (!fflag || errno != ENOENT) {
- warn("%s", f);
+ warnerr("%s", f);
eval = 1;
}
continue;
}
if (S_ISDIR(sb.st_mode) && !dflag) {
- warnx("%s: is a directory", f);
+ warnerrx("%s: is a directory", f);
eval = 1;
continue;
}
@@ -253,7 +263,7 @@ rm_file(char **argv)
rval = unlink(f);
}
if (rval && (!fflag || errno != ENOENT)) {
- warn("%s", f);
+ warnerr("%s", f);
eval = 1;
}
}
@@ -289,7 +299,8 @@ rm_overwrite(char *file, struct stat *sb
if (!S_ISREG(sbp->st_mode))
return (1);
if (sbp->st_nlink > 1) {
- warnx("%s (inode %llu): not overwritten due to multiple links",
+ warnerrx(
+ "%s (inode %llu): not overwritten due to multiple links",
file, (unsigned long long)sbp->st_ino);
return (0);
}
@@ -317,7 +328,7 @@ rm_overwrite(char *file, struct stat *sb
return (1);
err:
- warn("%s", file);
+ warnerr("%s", file);
close(fd);
eval = 1;
free(buf);
@@ -401,7 +412,7 @@ checkdot(char **argv)
if (ISDOT(p)) {
if (!complained++)
- warnx("\".\" and \"..\" may not be removed");
+ warnerrx("\".\" and \"..\" may not be removed");
eval = 1;
for (save = t; (t[0] = t[1]) != NULL; ++t)
continue;
@@ -414,6 +425,32 @@ checkdot(char **argv)
void
usage(void)
{
- (void)fprintf(stderr, "usage: %s [-dfiPRr] file ...\n", __progname);
+ (void)fprintf(stderr, "usage: %s [-dfxiPRr] file ...\n", __progname);
exit(1);
+}
+
+void
+warnerr(const char * fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (xflag)
+ verr(EXIT_FAILURE, fmt, ap);
+ else
+ vwarn(fmt, ap);
+ va_end(ap);
+}
+
+void
+warnerrx(const char * fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (xflag)
+ verrx(EXIT_FAILURE, fmt, ap);
+ else
+ vwarnx(fmt, ap);
+ va_end(ap);
}