From 6e1e0d66771523593a130e7657eaf06037a9d4e3 Mon Sep 17 00:00:00 2001 From: ru Date: Mon, 28 May 2001 15:31:11 +0000 Subject: [PATCH] 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) --- bin/chmod/chmod.1 | 18 +++++------------- bin/chmod/chmod.c | 24 +++++++++++++++++------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/bin/chmod/chmod.1 b/bin/chmod/chmod.1 index ce6c0383a60a..fe0a640136c0 100644 --- a/bin/chmod/chmod.1 +++ b/bin/chmod/chmod.1 @@ -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 diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c index 7a843c755bf7..97c9c02f0729 100644 --- a/bin/chmod/chmod.c +++ b/bin/chmod/chmod.c @@ -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); }