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 .Nd change file modes
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Oo .Op Fl fhv
.Fl f .Op Fl R Op Fl H | L | P
.Fl R
.Op Fl H | Fl L | Fl P
.Fl v
.Oc
.Ar mode .Ar mode
.Ar .Ar
.Sh DESCRIPTION .Sh DESCRIPTION
@ -84,19 +80,15 @@ Do not display a diagnostic message if
.Nm .Nm
could not modify the mode for could not modify the mode for
.Va file . .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 .It Fl v
Cause Cause
.Nm .Nm
to be verbose, showing files as the mode is modified. to be verbose, showing files as the mode is modified.
.El .El
.Pp .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 The
.Fl H , .Fl H ,
.Fl L .Fl L

View File

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