summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Kerola2019-08-02 20:39:05 +0200
committerSami Kerola2019-08-02 20:39:05 +0200
commit6d56251220954f4937c9fafbcdb427d4aa50d330 (patch)
treefae19fbb136d499e4a7bc1037a86c485847f5d7d
parentdmesg: fix output hex encoding (diff)
downloadkernel-qcow2-util-linux-6d56251220954f4937c9fafbcdb427d4aa50d330.tar.gz
kernel-qcow2-util-linux-6d56251220954f4937c9fafbcdb427d4aa50d330.tar.xz
kernel-qcow2-util-linux-6d56251220954f4937c9fafbcdb427d4aa50d330.zip
mountpoint: add --nofollow option
The no follow option will allow user to distinct mount points from symbolic links pointing to them. Arguably this is pretty pedantic option, mounting a device or bind mount to a directory via symlink does not have or cause any issues. Addresses: https://github.com/karelzak/util-linux/issues/832 Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--bash-completion/mountpoint2
-rw-r--r--sys-utils/mountpoint.17
-rw-r--r--sys-utils/mountpoint.c19
-rw-r--r--tests/expected/misc/mountpoint9
-rwxr-xr-xtests/ts/misc/mountpoint27
5 files changed, 59 insertions, 5 deletions
diff --git a/bash-completion/mountpoint b/bash-completion/mountpoint
index f14327ce2..15c6d2314 100644
--- a/bash-completion/mountpoint
+++ b/bash-completion/mountpoint
@@ -11,7 +11,7 @@ _mountpoint_module()
esac
case $cur in
-*)
- OPTS="--quiet --fs-devno --devno --help --version"
+ OPTS="--quiet --nofollow --fs-devno --devno --help --version"
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
return 0
;;
diff --git a/sys-utils/mountpoint.1 b/sys-utils/mountpoint.1
index afc469ebc..6669b13eb 100644
--- a/sys-utils/mountpoint.1
+++ b/sys-utils/mountpoint.1
@@ -1,4 +1,4 @@
-.TH MOUNTPOINT 1 "July 2014" "util-linux" "User Commands"
+.TH MOUNTPOINT 1 "August 2019" "util-linux" "User Commands"
.SH NAME
mountpoint \- see if a directory or file is a mountpoint
.SH SYNOPSIS
@@ -28,6 +28,11 @@ directory.
.BR \-q , " \-\-quiet"
Be quiet - don't print anything.
.TP
+.B "\-\-nofollow"
+Do not follow symbolic link if it the last elemnt of the
+.I directory
+path.
+.TP
.BR \-x , " \-\-devno"
Show the major/minor numbers of the given blockdevice on standard output.
.TP
diff --git a/sys-utils/mountpoint.c b/sys-utils/mountpoint.c
index 985130cba..052440bd4 100644
--- a/sys-utils/mountpoint.c
+++ b/sys-utils/mountpoint.c
@@ -47,6 +47,7 @@ struct mountpoint_control {
unsigned int
dev_devno:1,
fs_devno:1,
+ nofollow:1,
quiet:1;
};
@@ -123,6 +124,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(USAGE_OPTIONS, out);
fputs(_(" -q, --quiet quiet mode - don't print anything\n"
+ " --nofollow do not follow symlink\n"
" -d, --fs-devno print maj:min device number of the filesystem\n"
" -x, --devno print maj:min device number of the block device\n"), out);
fputs(USAGE_SEPARATOR, out);
@@ -137,8 +139,13 @@ int main(int argc, char **argv)
int c;
struct mountpoint_control ctl = { NULL };
+ enum {
+ OPT_NOFOLLOW = CHAR_MAX + 1
+ };
+
static const struct option longopts[] = {
{ "quiet", no_argument, NULL, 'q' },
+ { "nofollow", no_argument, NULL, OPT_NOFOLLOW },
{ "fs-devno", no_argument, NULL, 'd' },
{ "devno", no_argument, NULL, 'x' },
{ "help", no_argument, NULL, 'h' },
@@ -159,6 +166,9 @@ int main(int argc, char **argv)
case 'q':
ctl.quiet = 1;
break;
+ case OPT_NOFOLLOW:
+ ctl.nofollow = 1;
+ break;
case 'd':
ctl.fs_devno = 1;
break;
@@ -179,17 +189,20 @@ int main(int argc, char **argv)
warnx(_("bad usage"));
errtryhelp(EXIT_FAILURE);
}
+ if (ctl.nofollow && ctl.dev_devno)
+ errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"),
+ "--devno", "--nofollow");
ctl.path = argv[optind];
-
- if (stat(ctl.path, &ctl.st)) {
+ c = ctl.nofollow ? lstat(ctl.path, &ctl.st) : stat(ctl.path, &ctl.st);
+ if (c) {
if (!ctl.quiet)
err(EXIT_FAILURE, "%s", ctl.path);
return EXIT_FAILURE;
}
if (ctl.dev_devno)
return print_devno(&ctl) ? EXIT_FAILURE : EXIT_SUCCESS;
- if (dir_to_device(&ctl)) {
+ if ((ctl.nofollow && S_ISLNK(ctl.st.st_mode)) || dir_to_device(&ctl)) {
if (!ctl.quiet)
printf(_("%s is not a mountpoint\n"), ctl.path);
return EXIT_FAILURE;
diff --git a/tests/expected/misc/mountpoint b/tests/expected/misc/mountpoint
new file mode 100644
index 000000000..e7c20cd25
--- /dev/null
+++ b/tests/expected/misc/mountpoint
@@ -0,0 +1,9 @@
+default
+./symlink-to-root is a mountpoint
+0
+try --nofollow
+./symlink-to-root is not a mountpoint
+1
+mutually exclusive
+mountpoint: --devno and --nofollow are mutually exclusive
+1
diff --git a/tests/ts/misc/mountpoint b/tests/ts/misc/mountpoint
new file mode 100755
index 000000000..0b93a9c36
--- /dev/null
+++ b/tests/ts/misc/mountpoint
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="mountpoint"
+
+. $TS_TOPDIR/functions.sh
+ts_init "$*"
+
+ts_check_test_command "$TS_CMD_MOUNTPOINT"
+
+ln -s / ./symlink-to-root
+
+echo "default" >> $TS_OUTPUT 2>&1
+$TS_CMD_MOUNTPOINT ./symlink-to-root >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+
+echo "try --nofollow" >> $TS_OUTPUT 2>&1
+$TS_CMD_MOUNTPOINT --nofollow ./symlink-to-root >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+
+echo "mutually exclusive" >> $TS_OUTPUT 2>&1
+$TS_CMD_MOUNTPOINT --devno --nofollow / >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+
+rm -f ./symlink-to-root
+
+ts_finalize