Change noop option -h to do the real work. Now mode of symbolic link

is changed if -h option is given.

Requested by:	bde
Obtained from:	NetBSD (code part)
This commit is contained in:
ru 2001-05-28 15:31:11 +00:00
parent a58618001f
commit 5e17a4447b
2 changed files with 22 additions and 20 deletions

View File

@ -43,12 +43,8 @@
.Nd change file modes
.Sh SYNOPSIS
.Nm
.Oo
.Fl f
.Fl R
.Op Fl H | Fl L | Fl P
.Fl v
.Oc
.Op Fl fhv
.Op Fl R Op Fl H | L | P
.Ar mode
.Ar
.Sh DESCRIPTION
@ -84,19 +80,15 @@ Do not display a diagnostic message if
.Nm
could not modify the mode for
.Va file .
.It Fl h
If the file is a symbolic link, change the mode of the link itself
rather than the file that the link points to.
.It Fl v
Cause
.Nm
to be verbose, showing files as the mode is modified.
.El
.Pp
Symbolic links do not have modes, so unless the
.Fl H
or
.Fl L
option is set,
.Nm
on a symbolic link always succeeds and has no effect.
The
.Fl H ,
.Fl L

View File

@ -74,11 +74,12 @@ main(argc, argv)
int vflag;
char *ep, *mode;
int newmode;
int (*change_mode) __P((const char *, mode_t));
set = NULL;
omode = 0;
Hflag = Lflag = Pflag = Rflag = fflag = hflag = vflag = 0;
while ((ch = getopt(argc, argv, "HLPRXfgorstuvwx")) != -1)
while ((ch = getopt(argc, argv, "HLPRXfghorstuvwx")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
@ -102,9 +103,10 @@ main(argc, argv)
/*
* In System V (and probably POSIX.2) the -h option
* causes chmod to change the mode of the symbolic
* link. 4.4BSD's symbolic links don't have modes,
* so it's an undocumented noop. Do syntax checking,
* though.
* link. 4.4BSD's symbolic links didn't have modes,
* so it was an undocumented noop. In FreeBSD 3.0,
* lchmod(2) is introduced and this option does real
* work.
*/
hflag = 1;
break;
@ -148,6 +150,11 @@ done: argv += optind;
} else
fts_options = FTS_LOGICAL;
if (hflag)
change_mode = lchmod;
else
change_mode = chmod;
mode = *argv;
if (*mode >= '0' && *mode <= '7') {
errno = 0;
@ -190,14 +197,17 @@ done: argv += optind;
* don't point to anything and ones that we found
* doing a physical walk.
*/
continue;
if (!hflag)
continue;
/* else */
/* FALLTHROUGH */
default:
break;
}
newmode = oct ? omode : getmode(set, p->fts_statp->st_mode);
if ((newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS))
continue;
if (chmod(p->fts_accpath, newmode) && !fflag) {
if ((*change_mode)(p->fts_accpath, newmode) && !fflag) {
warn("%s", p->fts_path);
rval = 1;
} else {
@ -215,6 +225,6 @@ void
usage()
{
(void)fprintf(stderr,
"usage: chmod [-fv] [-R [-H | -L | -P]] mode file ...\n");
"usage: chmod [-fhv] [-R [-H | -L | -P]] mode file ...\n");
exit(1);
}