]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
df: dereference symlinks to disk device nodes
authorPádraig Brady <P@draigBrady.com>
Tue, 3 Dec 2013 23:36:02 +0000 (23:36 +0000)
committerPádraig Brady <P@draigBrady.com>
Wed, 4 Dec 2013 13:16:27 +0000 (13:16 +0000)
This is so the matching for the device is done on the canonical name
of the disk node, rather than on the path of the symlink.
In any case the user will generally want to use the symlink target.

* src/df.c (get_disk): Canonicalize the passed file,
before matching against the list of mounted file system devices.
Note we pass the original symlink name to the "file" output field,
as the symlink target is usually available through the "source" field.
* tests/df/df-symlink.sh: Test the dereferencing operation.
* tests/local.mk: Mention the new test.
* NEWS: Mention the fix.
Reported by Ondrej Oprala

NEWS
src/df.c
tests/df/df-symlink.sh [new file with mode: 0755]
tests/local.mk

diff --git a/NEWS b/NEWS
index b9678859c03f1ed69860f59a5029f1c4f532d45c..9274645a32c0ce30396cf898a459050ebdbd035f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   mount points.  Previously it may have failed to output some mount points.
   [bug introduced in coreutils-8.21]
 
+  df now processes symbolic links to disk device nodes correctly.  Previously
+  df displayed the symlink's device rather than that for the device node.
+  [This bug was present in "the beginning".]
+
   install now removes the target file if the strip program failed for any
   reason.  Before, that file was left behind, sometimes even with wrong
   permissions.
index ba8ef15c8efee1683620517eb9e4914e05dfd44a..8eabcbbaade97f39f484f92a4498af76f075716d 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -1056,6 +1056,11 @@ get_disk (char const *disk)
 {
   struct mount_entry const *me;
   struct mount_entry const *best_match = NULL;
+  char const *file = disk;
+
+  char *resolved = canonicalize_file_name (disk);
+  if (resolved && resolved[0] == '/')
+    disk = resolved;
 
   for (me = mount_list; me; me = me->me_next)
     {
@@ -1063,9 +1068,11 @@ get_disk (char const *disk)
         best_match = me;
     }
 
+  free (resolved);
+
   if (best_match)
     {
-      get_dev (best_match->me_devname, best_match->me_mountdir, disk, NULL,
+      get_dev (best_match->me_devname, best_match->me_mountdir, file, NULL,
                best_match->me_type, best_match->me_dummy,
                best_match->me_remote, NULL, false);
       return true;
diff --git a/tests/df/df-symlink.sh b/tests/df/df-symlink.sh
new file mode 100755 (executable)
index 0000000..45acfaa
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# Ensure that df dereferences symlinks to disk nodes
+
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ df
+
+disk=$(df --out=source '.' | tail -n1) ||
+  skip_ "cannot determine '.' file system"
+
+ln -s "$disk" symlink || framework_failure_
+
+df --out=source,target "$disk" > exp || skip_ "cannot get info for $disk"
+df --out=source,target symlink > out || fail=1
+compare exp out || fail=1
+
+Exit $fail
index 9b851f434a4723aa320cb79818eb99c7678efaf2..9a54e7b0758076ab59d70f608fdaaafc24afde98 100644 (file)
@@ -460,6 +460,7 @@ all_tests =                                 \
   tests/df/header.sh                           \
   tests/df/df-P.sh                             \
   tests/df/df-output.sh                                \
+  tests/df/df-symlink.sh                       \
   tests/df/unreadable.sh                       \
   tests/df/total-unprocessed.sh                        \
   tests/df/no-mtab-status.sh                   \