commit 3e160b616a183798e3dba34b93651a27851b1886
parent 4fcb31c6e00bf201836b0b0baf2ce60051f3db51
Author: Michael Forney <mforney@mforney.org>
Date: Sat, 21 Dec 2019 21:47:55 -0800
chmod: Remove -HLP flags, and ignore symlinks during traversal
These flags are non-POSIX and not useful since the mode of symlinks
is not used for anything.
This prevents a failure when a dangling symlink is encountered
during a recursive chmod.
Diffstat:
2 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/chmod.1 b/chmod.1
@@ -1,4 +1,4 @@
-.Dd 2015-10-08
+.Dd 2019-12-21
.Dt CHMOD 1
.Os sbase
.Sh NAME
@@ -6,10 +6,7 @@
.Nd change file modes
.Sh SYNOPSIS
.Nm
-.Oo
-.Fl R
-.Op Fl H | L | P
-.Oc
+.Op Fl R
.Ar mode
.Ar file ...
.Sh DESCRIPTION
@@ -58,19 +55,13 @@ read | write | execute | setuid and setgid | sticky
.It X
execute, if directory or at least one execute bit is already set
.El
+.Pp
+Symbolic links are followed if they are passed as operands, and ignored
+if they are encountered during directory traversal.
.Sh OPTIONS
.Bl -tag -width Ds
.It Fl R
Change modes recursively.
-.It Fl H
-Dereference
-.Ar file
-if it is a symbolic link.
-.It Fl L
-Dereference all symbolic links.
-.It Fl P
-Preserve symbolic links.
-This is the default.
.El
.Sh SEE ALSO
.Xr chgrp 1 ,
diff --git a/chmod.c b/chmod.c
@@ -14,7 +14,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r)
mode_t m;
m = parsemode(modestr, st->st_mode, mask);
- if (chmod(path, m) < 0) {
+ if (!S_ISLNK(st->st_mode) && chmod(path, m) < 0) {
weprintf("chmod %s:", path);
ret = 1;
} else if (S_ISDIR(st->st_mode)) {
@@ -25,14 +25,14 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r)
static void
usage(void)
{
- eprintf("usage: %s [-R [-H | -L | -P]] mode file ...\n", argv0);
+ eprintf("usage: %s [-R] mode file ...\n", argv0);
}
int
main(int argc, char *argv[])
{
struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .maxdepth = 1,
- .follow = 'P', .flags = DIRFIRST };
+ .follow = 'H', .flags = DIRFIRST };
size_t i;
argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
@@ -45,11 +45,6 @@ main(int argc, char *argv[])
case 'R':
r.maxdepth = 0;
break;
- case 'H':
- case 'L':
- case 'P':
- r.follow = (*argv)[i];
- break;
case 'r': case 'w': case 'x': case 'X': case 's': case 't':
/* -[rwxXst] are valid modes, so we're done */
if (i == 1)