diff --git a/src/chmod.c b/src/chmod.c
index 014757d9d..39ba79ed9 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -89,6 +89,10 @@ static enum Verbosity verbosity = V_off;
    Otherwise nullptr.  */
 static struct dev_ino *root_dev_ino;
 
+/* affect the referent of each symbolic link or not, 
+   default is affect.  */
+static bool dereference = true;
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
@@ -108,6 +112,7 @@ static struct option const long_options[] =
   {"reference", required_argument, nullptr, REFERENCE_FILE_OPTION},
   {"silent", no_argument, nullptr, 'f'},
   {"verbose", no_argument, nullptr, 'v'},
+  {"no-dereference", no_argument, nullptr, 'h'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {nullptr, 0, nullptr, 0}
@@ -208,6 +213,12 @@ process_file (FTS *fts, FTSENT *ent)
   struct change_status ch = {0};
   ch.status = CH_NO_STAT;
 
+  if(dereference != true && S_ISLNK (file_stats->st_mode))
+    {
+      return true;
+    }
+
+
   switch (ent->fts_info)
     {
     case FTS_DP:
@@ -398,6 +409,9 @@ With --reference, change the mode of each FILE to that of RFILE.\n\
 "), stdout);
       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);
@@ -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::,::+::=::"
+                           ("Rcfvhr::w::x::X::s::t::u::g::o::a::,::+::=::"
                             "0::1::2::3::4::5::6::7::"),
                            long_options, nullptr))
          != -1)
@@ -503,6 +517,9 @@ main (int argc, char **argv)
         case 'v':
           verbosity = V_high;
           break;
+        case 'h':
+          dereference = false;
+          break;
         case_GETOPT_HELP_CHAR;
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
         default:
@@ -564,8 +581,13 @@ main (int argc, char **argv)
       root_dev_ino = nullptr;
     }
 
+  int bit_flags = FTS_PHYSICAL | FTS_DEFER_STAT;
+  if (dereference == true) 
+    {
+      bit_flags = bit_flags | FTS_COMFOLLOW;
+    }
   ok = process_files (argv + optind,
-                      FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
+                      bit_flags);
 
   main_exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
 }
