File chmod_nofollow_symlinks_option.patch of Package coreutils

Index: coreutils-9.4/src/chmod.c
===================================================================
--- coreutils-9.4.orig/src/chmod.c
+++ coreutils-9.4/src/chmod.c
@@ -74,6 +74,9 @@ static mode_t umask_value;
 /* If true, change the modes of directories recursively. */
 static bool recurse;
 
+/* If true, don't follow symlinks */
+static bool nofollow_symlinks;
+
 /* If true, force silence (suppress most of error messages). */
 static bool force_silent;
 
@@ -100,6 +103,7 @@ enum
 
 static struct option const long_options[] =
 {
+  {"no-dereference", no_argument, nullptr, 'h'},
   {"changes", no_argument, nullptr, 'c'},
   {"recursive", no_argument, nullptr, 'R'},
   {"no-preserve-root", no_argument, nullptr, NO_PRESERVE_ROOT},
@@ -207,6 +211,7 @@ process_file (FTS *fts, FTSENT *ent)
   const struct stat *file_stats = ent->fts_statp;
   struct change_status ch = { 0, };
   ch.status = CH_NO_STAT;
+  int retval = -1;
 
   switch (ent->fts_info)
     {
@@ -277,7 +282,12 @@ process_file (FTS *fts, FTSENT *ent)
       ch.old_mode = file_stats->st_mode;
       ch.new_mode = mode_adjust (ch.old_mode, S_ISDIR (ch.old_mode) != 0,
                                  umask_value, change, nullptr);
-      if (chmodat (fts->fts_cwd_fd, file, ch.new_mode) == 0)
+      if (nofollow_symlinks) {
+        retval = fchmodat (fts->fts_cwd_fd, file, ch.new_mode, AT_SYMLINK_NOFOLLOW);
+      } else {
+        retval = chmodat (fts->fts_cwd_fd, file, ch.new_mode);
+      }
+      if (retval == 0)
         ch.status = CH_SUCCEEDED;
       else
         {
@@ -399,6 +409,10 @@ With --reference, change the mode of eac
       fputs (_("\
   -R, --recursive        change files and directories recursively\n\
 "), stdout);
+      fputs (_("\
+  -h, --no-dereference   affect symbolic links instead of any referenced file\n\
+"), stdout);
+
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
       fputs (_("\
@@ -435,7 +449,7 @@ main (int argc, char **argv)
   recurse = force_silent = diagnose_surprises = false;
 
   while ((c = getopt_long (argc, argv,
-                           ("Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
+                           ("hRcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
                             "0::1::2::3::4::5::6::7::"),
                            long_options, nullptr))
          != -1)
@@ -491,6 +505,9 @@ main (int argc, char **argv)
         case REFERENCE_FILE_OPTION:
           reference_file = optarg;
           break;
+        case 'h':
+          nofollow_symlinks = true;
+          break;
         case 'R':
           recurse = true;
           break;
openSUSE Build Service is sponsored by