From bbb2a0de816f0cb506a0bdb34c9ca7ba94e53f9a Mon Sep 17 00:00:00 2001
From: Kent Fredric <kentnl@gentoo.org>
Date: Fri, 18 Sep 2020 04:53:23 +1200
Subject: Enable overriding tempdir used for base of fuse mounts

- Add 5 new external variables to control locations for mountpoints,
  scratch directories, pid files and logs:
  - FUSE_TEMPDIR (weak support) : Change the base directory for various
    path defaults
  - FUSE_MOUNTPOINT : Change where the test filesystem is mounted
  - FUSE_TESTMOUNT : Change the path to the "fusetest-" directory used
    in various tests
  - FUSE_PIDFILE : Change the path to the PID file for the fuse daemon
  - FUSE_LOGFILE : Change the path to the log file for the fuse daemon
- Convert stringy $_opts into a proper array to avoid path escaping
  headaches.
- Use `opendir` to check existence/traversability of the mountpoint
  instead of a cruddy stringy system($string) call, avoiding need for
  stdout redirection and dangerous path handling, as well as removing
  the need for POSIX module hacks to check the exit status of "ls"
- Use array based invocation of the $_loop script to avoid problems with
  path handling/escaping
- Use list-mode system(@args) for `rm` call to avoid dangerous
  nightmares in path handling/escaping.
- Use native perl file IO for reading pid files instead of consuming the
  output of a system("cat"), both avoiding a lot of silly shenanigans
  with IPC and path handling/escaping

Signed-off-by: Kent Fredric <kentnl@gentoo.org>
---
 examples/loopback.pl |  7 ++++++-
 test/helper.pm       | 40 ++++++++++++++++++++++++++++++----------
 test/s/mount.t       | 24 +++++++++++++++++-------
 3 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/examples/loopback.pl b/examples/loopback.pl
index ef53e9d..c1ddfc2 100755
--- a/examples/loopback.pl
+++ b/examples/loopback.pl
@@ -65,7 +65,12 @@ GetOptions(
     'logfile=s'         => \$logfile,
 ) || die('Error parsing options');
 
-sub fixup { return "/tmp/fusetest-" . $ENV{LOGNAME} . shift }
+sub fixup {
+  my $tempdir = $ENV{FUSE_TESTMOUNT};
+  $tempdir = "/tmp/fusetest-" . $ENV{LOGNAME}
+    unless defined $tempdir and length $tempdir;
+  return $tempdir . shift;
+}
 
 sub x_getattr {
     my ($file) = fixup(shift);
diff --git a/test/helper.pm b/test/helper.pm
index f210105..f24f2a4 100644
--- a/test/helper.pm
+++ b/test/helper.pm
@@ -4,15 +4,37 @@ package # avoid cpan indexing
 use strict;
 use Exporter;
 use Config;
-use POSIX qw(WEXITSTATUS);
 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
 @ISA = "Exporter";
-@EXPORT_OK = qw($_loop $_opts $_point $_pidfile $_real);
-my $tmp = -d '/private' ? '/private/tmp' : '/tmp';
-our($_loop, $_point, $_pidfile, $_real, $_opts) = ('examples/loopback.pl',"$tmp/fusemnt-".$ENV{LOGNAME},$ENV{'PWD'} . "/test/s/mounted.pid","$tmp/fusetest-".$ENV{LOGNAME}, '');
-$_opts = ' --pidfile ' . $_pidfile;
-$_opts .= ' --logfile /tmp/fusemnt.log';
-$_opts .= $Config{useithreads} ? ' --use-threads' : '';
+@EXPORT_OK = qw($_loop @_opts $_point $_pidfile $_real);
+
+our $_loop = 'examples/loopback.pl';
+my $tmp = $ENV{FUSE_TEMPDIR};
+$tmp = -d '/private' ? '/private/tmp' : '/tmp'
+  unless defined $tmp and length $tmp;
+
+our $_point = $ENV{FUSE_MOUNTPOINT};
+$_point = "$tmp/fusemnt-$ENV{LOGNAME}"
+	unless defined $_point and length $_point;
+
+our $_pidfile = $ENV{FUSE_PIDFILE};
+$_pidfile = "$ENV{PWD}/test/s/mounted.pid"
+	unless defined $_pidfile and length $_pidfile;
+
+our $_real = $ENV{FUSE_TESTMOUNT};
+$_real = "$tmp/fusetest-$ENV{LOGNAME}"
+	unless defined $_real and length $_real;
+
+our $_logfile = $ENV{FUSE_LOGFILE};
+$_logfile = "/tmp/fusemnt.log"
+	unless defined $_logfile and length $_logfile;
+
+our @_opts = (
+	'--pidfile' => $_pidfile,
+	'--logfile' => $_logfile,
+	( $Config{useithreads} ? '--use-threads' : () ),
+);
+
 if($0 !~ qr|s/u?mount\.t$|) {
 	my ($reject) = 1;
 	if(open my $fh, '<', $_pidfile) {
@@ -27,8 +49,6 @@ if($0 !~ qr|s/u?mount\.t$|) {
 			}
 		}
 	}
-	system("ls $_point >/dev/null");
-	$reject = 1 if (POSIX::WEXITSTATUS($?));
-	die "not properly mounted\n" if $reject;
+	opendir my $dfh, $_point or die "$_point not properly mounted: $!";
 }
 1;
diff --git a/test/s/mount.t b/test/s/mount.t
index 0f545b7..3bf65c6 100644
--- a/test/s/mount.t
+++ b/test/s/mount.t
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 use lib './test/';
-use helper qw($_point $_loop $_opts $_real $_pidfile);
+use helper qw($_point $_loop @_opts $_real $_pidfile);
 use strict;
 use Errno qw(:POSIX);
 use Test::More tests => 3;
@@ -21,7 +21,7 @@ open REALSTDOUT, '>&STDOUT';
 open REALSTDERR, '>&STDERR';
 open STDOUT, '>', '/dev/null';
 open STDERR, '>&', \*STDOUT;
-system("perl -Iblib/lib -Iblib/arch $_loop $_opts $_point");
+system('perl','-Iblib/lib','-Iblib/arch',$_loop, @_opts, $_point);
 open STDOUT, '>&', \*REALSTDOUT;
 open STDERR, '>&', \*REALSTDERR;
 
@@ -33,10 +33,20 @@ while ($count++ < 50 && !$success) {
 diag "Mounted in ", $count/10, " secs";
 
 ok($success,"mount succeeded");
-system("rm -rf $_real");
-unless($success) {
-	kill('INT',`cat $_pidfile`);
-	unlink($_pidfile);
-} else {
+
+system("rm","-vrf",$_real);
+if ($success) {
 	mkdir($_real);
+} else {
+	my $pid;
+	if ( open my $fh, '<', "$_pidfile" ) {
+		local $/ = undef;
+		$pid = scalar <$fh>;
+	} else {
+		warn "Can't read pidfile $_pidfile, $!"
+	}
+	if ( $pid ) {
+		kill('INT',$pid);
+	}
+	unlink($_pidfile);
 }
-- 
2.28.0

