X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=testcases%2Flib%2FSocketActivation.pm;h=8f52bddc4a3eb8a92a3ba37ae8363a29cfd9b779;hb=c04343d26d72ff60ba1f791ff150e9d9eafa5afc;hp=e0b08d746fc3bde846b502c159f8e06b94cdd095;hpb=31b01798dde1b61eafe2f6532268cb3da472e36d;p=i3%2Fi3 diff --git a/testcases/lib/SocketActivation.pm b/testcases/lib/SocketActivation.pm index e0b08d74..8f52bddc 100644 --- a/testcases/lib/SocketActivation.pm +++ b/testcases/lib/SocketActivation.pm @@ -5,8 +5,9 @@ use strict; use warnings; use IO::Socket::UNIX; # core use Cwd qw(abs_path); # core -use POSIX (); # core +use POSIX qw(:fcntl_h); # core use AnyEvent::Handle; # not core +use AnyEvent::Util; # not core use Exporter 'import'; use v5.10; @@ -38,11 +39,6 @@ sub activate_i3 { # remove the old unix socket unlink($args{unix_socket_path}); - # pass all file descriptors up to three to the children. - # we need to set this flag before opening the socket. - open(my $fdtest, '<', '/dev/null'); - $^F = fileno($fdtest); - close($fdtest); my $socket = IO::Socket::UNIX->new( Listen => 1, Local => $args{unix_socket_path}, @@ -56,6 +52,10 @@ sub activate_i3 { $ENV{LISTEN_PID} = $$; $ENV{LISTEN_FDS} = 1; delete $ENV{DESKTOP_STARTUP_ID}; + unless ($args{dont_create_temp_dir}) { + $ENV{XDG_RUNTIME_DIR} = '/tmp/i3-testsuite/'; + mkdir $ENV{XDG_RUNTIME_DIR}; + } $ENV{DISPLAY} = $args{display}; $ENV{PATH} = join(':', '../i3-nagbar', @@ -65,31 +65,64 @@ sub activate_i3 { '..', $ENV{PATH} ); - # Only pass file descriptors 0 (stdin), 1 (stdout), 2 (stderr) and - # 3 (socket) to the child. - $^F = 3; + + # We are about to exec, but we did not modify $^F to include $socket + # when creating the socket (because the file descriptor could have a + # number != 3 which would lead to i3 leaking a file descriptor). This + # caused Perl to set the FD_CLOEXEC flag, which would close $socket on + # exec(), effectively *NOT* passing $socket to the new process. + # Therefore, we explicitly clear FD_CLOEXEC (the only flag right now) + # by setting the flags to 0. + POSIX::fcntl($socket, F_SETFD, 0) or die "Could not clear fd flags: $!"; # If the socket does not use file descriptor 3 by chance already, we # close fd 3 and dup2() the socket to 3. if (fileno($socket) != 3) { POSIX::close(3); POSIX::dup2(fileno($socket), 3); + POSIX::close(fileno($socket)); } + # Make sure no file descriptors are open. Strangely, I got an open file + # descriptor pointing to AnyEvent/Impl/EV.pm when testing. + AnyEvent::Util::close_all_fds_except(0, 1, 2, 3); + # Construct the command to launch i3. Use maximum debug level, disable # the interactive signalhandler to make it crash immediately instead. - my $i3cmd = abs_path("../i3") . " -V -d all --disable-signalhandler"; + # Also disable logging to SHM since we redirect the logs anyways. + # Force Xinerama because we use Xdmx for multi-monitor tests. + my $i3cmd = abs_path("../i3") . q| -V -d all --disable-signalhandler| . + q| --shmlog-size=0 --force-xinerama|; + + # For convenience: + my $outdir = $args{outdir}; + my $test = $args{testname}; + + if ($args{restart}) { + $i3cmd .= ' -L ' . abs_path('restart-state.golden'); + } if ($args{valgrind}) { $i3cmd = - qq|valgrind -v --log-file="$args{outdir}/valgrind.log" | . + qq|valgrind -v --log-file="$outdir/valgrind-for-$test.log" | . qq|--leak-check=full --track-origins=yes --num-callers=20 | . qq|--tool=memcheck -- $i3cmd|; } - # Append to $args{logpath} instead of overwriting because i3 might be + my $logfile = "$outdir/i3-log-for-$test"; + # Append to $logfile instead of overwriting because i3 might be # run multiple times in one testcase. - my $cmd = "exec $i3cmd -c $args{configfile} >>$args{logpath} 2>&1"; + my $cmd = "exec $i3cmd -c $args{configfile} >>$logfile 2>&1"; + + if ($args{strace}) { + my $out = "$outdir/strace-for-$test.log"; + + # We overwrite LISTEN_PID with the correct process ID to make + # socket activation work (LISTEN_PID has to match getpid(), + # otherwise the LISTEN_FDS will be treated as a left-over). + $cmd = qq|strace -fF -s2048 -v -o "$out" -- | . + 'sh -c "export LISTEN_PID=\$\$; ' . $cmd . '"'; + } # We need to use the shell due to using output redirections. exec '/bin/sh', '-c', $cmd;