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.
This commit is contained in:
parent
4fcb31c6e0
commit
3e160b616a
19
chmod.1
19
chmod.1
|
@ -1,4 +1,4 @@
|
||||||
.Dd 2015-10-08
|
.Dd 2019-12-21
|
||||||
.Dt CHMOD 1
|
.Dt CHMOD 1
|
||||||
.Os sbase
|
.Os sbase
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -6,10 +6,7 @@
|
||||||
.Nd change file modes
|
.Nd change file modes
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Oo
|
.Op Fl R
|
||||||
.Fl R
|
|
||||||
.Op Fl H | L | P
|
|
||||||
.Oc
|
|
||||||
.Ar mode
|
.Ar mode
|
||||||
.Ar file ...
|
.Ar file ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
@ -58,19 +55,13 @@ read | write | execute | setuid and setgid | sticky
|
||||||
.It X
|
.It X
|
||||||
execute, if directory or at least one execute bit is already set
|
execute, if directory or at least one execute bit is already set
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
Symbolic links are followed if they are passed as operands, and ignored
|
||||||
|
if they are encountered during directory traversal.
|
||||||
.Sh OPTIONS
|
.Sh OPTIONS
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Fl R
|
.It Fl R
|
||||||
Change modes recursively.
|
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
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr chgrp 1 ,
|
.Xr chgrp 1 ,
|
||||||
|
|
11
chmod.c
11
chmod.c
|
@ -14,7 +14,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r)
|
||||||
mode_t m;
|
mode_t m;
|
||||||
|
|
||||||
m = parsemode(modestr, st->st_mode, mask);
|
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);
|
weprintf("chmod %s:", path);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
} else if (S_ISDIR(st->st_mode)) {
|
} 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
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: %s [-R [-H | -L | -P]] mode file ...\n", argv0);
|
eprintf("usage: %s [-R] mode file ...\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .maxdepth = 1,
|
struct recursor r = { .fn = chmodr, .hist = NULL, .depth = 0, .maxdepth = 1,
|
||||||
.follow = 'P', .flags = DIRFIRST };
|
.follow = 'H', .flags = DIRFIRST };
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
|
argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
|
||||||
|
@ -45,11 +45,6 @@ main(int argc, char *argv[])
|
||||||
case 'R':
|
case 'R':
|
||||||
r.maxdepth = 0;
|
r.maxdepth = 0;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
|
||||||
case 'L':
|
|
||||||
case 'P':
|
|
||||||
r.follow = (*argv)[i];
|
|
||||||
break;
|
|
||||||
case 'r': case 'w': case 'x': case 'X': case 's': case 't':
|
case 'r': case 'w': case 'x': case 'X': case 's': case 't':
|
||||||
/* -[rwxXst] are valid modes, so we're done */
|
/* -[rwxXst] are valid modes, so we're done */
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user