1d0825bca7fe65beaee391d30da42e937db621564Steve Block# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved 2d0825bca7fe65beaee391d30da42e937db621564Steve Block# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 3d0825bca7fe65beaee391d30da42e937db621564Steve Block# Copyright (C) 2010 Andras Becsi (abecsi@inf.u-szeged.hu), University of Szeged 42fc2651226baac27029e38c9d6ef883fa32084dbSteve Block# Copyright (C) 2011 Research In Motion Limited. All rights reserved. 5d0825bca7fe65beaee391d30da42e937db621564Steve Block# 6d0825bca7fe65beaee391d30da42e937db621564Steve Block# Redistribution and use in source and binary forms, with or without 7d0825bca7fe65beaee391d30da42e937db621564Steve Block# modification, are permitted provided that the following conditions 8d0825bca7fe65beaee391d30da42e937db621564Steve Block# are met: 9d0825bca7fe65beaee391d30da42e937db621564Steve Block# 10d0825bca7fe65beaee391d30da42e937db621564Steve Block# 1. Redistributions of source code must retain the above copyright 11d0825bca7fe65beaee391d30da42e937db621564Steve Block# notice, this list of conditions and the following disclaimer. 12d0825bca7fe65beaee391d30da42e937db621564Steve Block# 2. Redistributions in binary form must reproduce the above copyright 13d0825bca7fe65beaee391d30da42e937db621564Steve Block# notice, this list of conditions and the following disclaimer in the 14d0825bca7fe65beaee391d30da42e937db621564Steve Block# documentation and/or other materials provided with the distribution. 15d0825bca7fe65beaee391d30da42e937db621564Steve Block# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16d0825bca7fe65beaee391d30da42e937db621564Steve Block# its contributors may be used to endorse or promote products derived 17d0825bca7fe65beaee391d30da42e937db621564Steve Block# from this software without specific prior written permission. 18d0825bca7fe65beaee391d30da42e937db621564Steve Block# 19d0825bca7fe65beaee391d30da42e937db621564Steve Block# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20d0825bca7fe65beaee391d30da42e937db621564Steve Block# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21d0825bca7fe65beaee391d30da42e937db621564Steve Block# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22d0825bca7fe65beaee391d30da42e937db621564Steve Block# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23d0825bca7fe65beaee391d30da42e937db621564Steve Block# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24d0825bca7fe65beaee391d30da42e937db621564Steve Block# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25d0825bca7fe65beaee391d30da42e937db621564Steve Block# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26d0825bca7fe65beaee391d30da42e937db621564Steve Block# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27d0825bca7fe65beaee391d30da42e937db621564Steve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28d0825bca7fe65beaee391d30da42e937db621564Steve Block# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29d0825bca7fe65beaee391d30da42e937db621564Steve Block 30d0825bca7fe65beaee391d30da42e937db621564Steve Block# Module to share code to start and stop the Apache daemon. 31d0825bca7fe65beaee391d30da42e937db621564Steve Block 32d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse strict; 33d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse warnings; 34d0825bca7fe65beaee391d30da42e937db621564Steve Block 35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockuse File::Copy; 36d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse File::Path; 37d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse File::Spec; 38d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse File::Spec::Functions; 398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockuse Fcntl ':flock'; 40d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse IPC::Open2; 41d0825bca7fe65beaee391d30da42e937db621564Steve Block 42d0825bca7fe65beaee391d30da42e937db621564Steve Blockuse webkitdirs; 43d0825bca7fe65beaee391d30da42e937db621564Steve Block 44d0825bca7fe65beaee391d30da42e937db621564Steve BlockBEGIN { 45d0825bca7fe65beaee391d30da42e937db621564Steve Block use Exporter (); 46d0825bca7fe65beaee391d30da42e937db621564Steve Block our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); 47d0825bca7fe65beaee391d30da42e937db621564Steve Block $VERSION = 1.00; 48d0825bca7fe65beaee391d30da42e937db621564Steve Block @ISA = qw(Exporter); 498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block @EXPORT = qw(&getHTTPDPath 508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &getHTTPDConfigPathForTestDirectory 518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &getDefaultConfigForTestDirectory 528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &openHTTPD 538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &closeHTTPD 548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &setShouldWaitForUserInterrupt 558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &waitForHTTPDLock 568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block &getWaitTime); 57d0825bca7fe65beaee391d30da42e937db621564Steve Block %EXPORT_TAGS = ( ); 58d0825bca7fe65beaee391d30da42e937db621564Steve Block @EXPORT_OK = (); 59d0825bca7fe65beaee391d30da42e937db621564Steve Block} 60d0825bca7fe65beaee391d30da42e937db621564Steve Block 61d0825bca7fe65beaee391d30da42e937db621564Steve Blockmy $tmpDir = "/tmp"; 622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block$tmpDir = convertMsysPath($tmpDir) if isMsys(); 638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockmy $httpdLockPrefix = "WebKitHttpd.lock."; 648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockmy $myLockFile; 658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockmy $exclusiveLockFile = File::Spec->catfile($tmpDir, "WebKit.lock"); 66d0825bca7fe65beaee391d30da42e937db621564Steve Blockmy $httpdPidDir = File::Spec->catfile($tmpDir, "WebKit"); 67d0825bca7fe65beaee391d30da42e937db621564Steve Blockmy $httpdPidFile = File::Spec->catfile($httpdPidDir, "httpd.pid"); 68d0825bca7fe65beaee391d30da42e937db621564Steve Blockmy $httpdPid; 69d0825bca7fe65beaee391d30da42e937db621564Steve Blockmy $waitForUserInterrupt = 0; 708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockmy $waitBeginTime; 718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockmy $waitEndTime; 72d0825bca7fe65beaee391d30da42e937db621564Steve Block 738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block$SIG{'INT'} = 'handleInterrupt'; 748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block$SIG{'TERM'} = 'handleInterrupt'; 75d0825bca7fe65beaee391d30da42e937db621564Steve Block 76d0825bca7fe65beaee391d30da42e937db621564Steve Blocksub getHTTPDPath 77d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch my $httpdPath; 79d0825bca7fe65beaee391d30da42e937db621564Steve Block if (isDebianBased()) { 80d0825bca7fe65beaee391d30da42e937db621564Steve Block $httpdPath = "/usr/sbin/apache2"; 812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } elsif (isMsys()) { 822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block $httpdPath = 'c:\program files\apache software foundation\apache2.2\bin\httpd.exe'; 83d0825bca7fe65beaee391d30da42e937db621564Steve Block } else { 84d0825bca7fe65beaee391d30da42e937db621564Steve Block $httpdPath = "/usr/sbin/httpd"; 85d0825bca7fe65beaee391d30da42e937db621564Steve Block } 86d0825bca7fe65beaee391d30da42e937db621564Steve Block return $httpdPath; 87d0825bca7fe65beaee391d30da42e937db621564Steve Block} 88d0825bca7fe65beaee391d30da42e937db621564Steve Block 89d0825bca7fe65beaee391d30da42e937db621564Steve Blocksub getDefaultConfigForTestDirectory 90d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 91d0825bca7fe65beaee391d30da42e937db621564Steve Block my ($testDirectory) = @_; 92d0825bca7fe65beaee391d30da42e937db621564Steve Block die "No test directory has been specified." unless ($testDirectory); 93d0825bca7fe65beaee391d30da42e937db621564Steve Block 948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $httpdConfig = getHTTPDConfigPathForTestDirectory($testDirectory); 95d0825bca7fe65beaee391d30da42e937db621564Steve Block my $documentRoot = "$testDirectory/http/tests"; 96d0825bca7fe65beaee391d30da42e937db621564Steve Block my $jsTestResourcesDirectory = $testDirectory . "/fast/js/resources"; 9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch my $mediaResourcesDirectory = $testDirectory . "/media"; 98d0825bca7fe65beaee391d30da42e937db621564Steve Block my $typesConfig = "$testDirectory/http/conf/mime.types"; 99d0825bca7fe65beaee391d30da42e937db621564Steve Block my $httpdLockFile = File::Spec->catfile($httpdPidDir, "httpd.lock"); 100d0825bca7fe65beaee391d30da42e937db621564Steve Block my $httpdScoreBoardFile = File::Spec->catfile($httpdPidDir, "httpd.scoreboard"); 101d0825bca7fe65beaee391d30da42e937db621564Steve Block 102d0825bca7fe65beaee391d30da42e937db621564Steve Block my @httpdArgs = ( 103d0825bca7fe65beaee391d30da42e937db621564Steve Block "-f", "$httpdConfig", 104d0825bca7fe65beaee391d30da42e937db621564Steve Block "-C", "DocumentRoot \"$documentRoot\"", 105d0825bca7fe65beaee391d30da42e937db621564Steve Block # Setup a link to where the js test templates are stored, use -c so that mod_alias will already be loaded. 106d0825bca7fe65beaee391d30da42e937db621564Steve Block "-c", "Alias /js-test-resources \"$jsTestResourcesDirectory\"", 10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch "-c", "Alias /media-resources \"$mediaResourcesDirectory\"", 108d0825bca7fe65beaee391d30da42e937db621564Steve Block "-c", "TypesConfig \"$typesConfig\"", 109d0825bca7fe65beaee391d30da42e937db621564Steve Block "-c", "PidFile \"$httpdPidFile\"", 110d0825bca7fe65beaee391d30da42e937db621564Steve Block "-c", "ScoreBoardFile \"$httpdScoreBoardFile\"", 111d0825bca7fe65beaee391d30da42e937db621564Steve Block ); 112d0825bca7fe65beaee391d30da42e937db621564Steve Block 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block push @httpdArgs, ( 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block # Apache wouldn't run CGIs with permissions==700 otherwise 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "-c", "User \"#$<\"", 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block "-c", "LockFile \"$httpdLockFile\"" 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ) unless isMsys(); 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 119d0825bca7fe65beaee391d30da42e937db621564Steve Block # FIXME: Enable this on Windows once <rdar://problem/5345985> is fixed 120d0825bca7fe65beaee391d30da42e937db621564Steve Block # The version of Apache we use with Cygwin does not support SSL 121d0825bca7fe65beaee391d30da42e937db621564Steve Block my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem"; 122d0825bca7fe65beaee391d30da42e937db621564Steve Block push(@httpdArgs, "-c", "SSLCertificateFile \"$sslCertificate\"") unless isCygwin(); 123d0825bca7fe65beaee391d30da42e937db621564Steve Block 124d0825bca7fe65beaee391d30da42e937db621564Steve Block return @httpdArgs; 125d0825bca7fe65beaee391d30da42e937db621564Steve Block 126d0825bca7fe65beaee391d30da42e937db621564Steve Block} 127d0825bca7fe65beaee391d30da42e937db621564Steve Block 1288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub getHTTPDConfigPathForTestDirectory 1298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 1308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my ($testDirectory) = @_; 1318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block die "No test directory has been specified." unless ($testDirectory); 1328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $httpdConfig; 1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch my $httpdPath = getHTTPDPath(); 1348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (isCygwin()) { 1358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $windowsConfDirectory = "$testDirectory/http/conf/"; 1368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block unless (-x "/usr/lib/apache/libphp4.dll") { 1378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block copy("$windowsConfDirectory/libphp4.dll", "/usr/lib/apache/libphp4.dll"); 1388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block chmod(0755, "/usr/lib/apache/libphp4.dll"); 1398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $httpdConfig = "$windowsConfDirectory/cygwin-httpd.conf"; 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } elsif (isMsys()) { 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block $httpdConfig = "$testDirectory/http/conf/apache2-msys-httpd.conf"; 1438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } elsif (isDebianBased()) { 1448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf"; 1458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } elsif (isFedoraBased()) { 1468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $httpdConfig = "$testDirectory/http/conf/fedora-httpd.conf"; 1478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } else { 1488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $httpdConfig = "$testDirectory/http/conf/httpd.conf"; 1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|; 1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return $httpdConfig; 1528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 1538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 154d0825bca7fe65beaee391d30da42e937db621564Steve Blocksub openHTTPD(@) 155d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 156d0825bca7fe65beaee391d30da42e937db621564Steve Block my (@args) = @_; 157d0825bca7fe65beaee391d30da42e937db621564Steve Block die "No HTTPD configuration has been specified" unless (@args); 158d0825bca7fe65beaee391d30da42e937db621564Steve Block mkdir($httpdPidDir, 0755); 159d0825bca7fe65beaee391d30da42e937db621564Steve Block die "No write permissions to $httpdPidDir" unless (-w $httpdPidDir); 160d0825bca7fe65beaee391d30da42e937db621564Steve Block 161d0825bca7fe65beaee391d30da42e937db621564Steve Block if (-f $httpdPidFile) { 162d0825bca7fe65beaee391d30da42e937db621564Steve Block open (PIDFILE, $httpdPidFile); 163d0825bca7fe65beaee391d30da42e937db621564Steve Block my $oldPid = <PIDFILE>; 164d0825bca7fe65beaee391d30da42e937db621564Steve Block chomp $oldPid; 165d0825bca7fe65beaee391d30da42e937db621564Steve Block close PIDFILE; 166d0825bca7fe65beaee391d30da42e937db621564Steve Block if (0 != kill 0, $oldPid) { 167d0825bca7fe65beaee391d30da42e937db621564Steve Block print "\nhttpd is already running: pid $oldPid, killing...\n"; 168967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!killHTTPD($oldPid)) { 1698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block cleanUp(); 1708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block die "Timed out waiting for httpd to quit"; 1718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 172d0825bca7fe65beaee391d30da42e937db621564Steve Block } 173967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch unlink $httpdPidFile; 174d0825bca7fe65beaee391d30da42e937db621564Steve Block } 175d0825bca7fe65beaee391d30da42e937db621564Steve Block 1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch my $httpdPath = getHTTPDPath(); 177d0825bca7fe65beaee391d30da42e937db621564Steve Block 178d0825bca7fe65beaee391d30da42e937db621564Steve Block open2(">&1", \*HTTPDIN, $httpdPath, @args); 179d0825bca7fe65beaee391d30da42e937db621564Steve Block 180d0825bca7fe65beaee391d30da42e937db621564Steve Block my $retryCount = 20; 181d0825bca7fe65beaee391d30da42e937db621564Steve Block while (!-f $httpdPidFile && $retryCount) { 182d0825bca7fe65beaee391d30da42e937db621564Steve Block sleep 1; 183d0825bca7fe65beaee391d30da42e937db621564Steve Block --$retryCount; 184d0825bca7fe65beaee391d30da42e937db621564Steve Block } 185d0825bca7fe65beaee391d30da42e937db621564Steve Block 186d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!$retryCount) { 1878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block cleanUp(); 188d0825bca7fe65beaee391d30da42e937db621564Steve Block die "Timed out waiting for httpd to start"; 189d0825bca7fe65beaee391d30da42e937db621564Steve Block } 190d0825bca7fe65beaee391d30da42e937db621564Steve Block 191d0825bca7fe65beaee391d30da42e937db621564Steve Block $httpdPid = <PIDFILE> if open(PIDFILE, $httpdPidFile); 192d0825bca7fe65beaee391d30da42e937db621564Steve Block chomp $httpdPid if $httpdPid; 193d0825bca7fe65beaee391d30da42e937db621564Steve Block close PIDFILE; 194d0825bca7fe65beaee391d30da42e937db621564Steve Block 195d0825bca7fe65beaee391d30da42e937db621564Steve Block waitpid($httpdPid, 0) if ($waitForUserInterrupt && $httpdPid); 196d0825bca7fe65beaee391d30da42e937db621564Steve Block 197d0825bca7fe65beaee391d30da42e937db621564Steve Block return 1; 198d0825bca7fe65beaee391d30da42e937db621564Steve Block} 199d0825bca7fe65beaee391d30da42e937db621564Steve Block 200d0825bca7fe65beaee391d30da42e937db621564Steve Blocksub closeHTTPD 201d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 202d0825bca7fe65beaee391d30da42e937db621564Steve Block close HTTPDIN; 203967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch my $succeeded = killHTTPD($httpdPid); 2048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block cleanUp(); 205967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch unless ($succeeded) { 206967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch print STDERR "Timed out waiting for httpd to terminate!\n" unless $succeeded; 2078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return 0; 2088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 209d0825bca7fe65beaee391d30da42e937db621564Steve Block return 1; 210d0825bca7fe65beaee391d30da42e937db621564Steve Block} 211d0825bca7fe65beaee391d30da42e937db621564Steve Block 212967717af5423377c967781471ee106e2bb4e11c8Ben Murdochsub killHTTPD 213967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 214967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch my ($pid) = @_; 215967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 216967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 1 unless $pid; 217967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 218967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch kill 15, $pid; 219967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 220967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch my $retryCount = 20; 221967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch while (kill(0, $pid) && $retryCount) { 222967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch sleep 1; 223967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch --$retryCount; 224967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 225967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return $retryCount != 0; 226967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 227967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 228d0825bca7fe65beaee391d30da42e937db621564Steve Blocksub setShouldWaitForUserInterrupt 229d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 230d0825bca7fe65beaee391d30da42e937db621564Steve Block $waitForUserInterrupt = 1; 231d0825bca7fe65beaee391d30da42e937db621564Steve Block} 232d0825bca7fe65beaee391d30da42e937db621564Steve Block 2338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub handleInterrupt 234d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 235967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch # On Cygwin, when we receive a signal Apache is still running, so we need 236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch # to kill it. On other platforms (at least Mac OS X), Apache will have 237967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch # already been killed, and trying to kill it again will cause us to hang. 238967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch # All we need to do in this case is clean up our own files. 239967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (isCygwin()) { 240967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch closeHTTPD(); 241967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } else { 242967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch cleanUp(); 243967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 244967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 245d0825bca7fe65beaee391d30da42e937db621564Steve Block print "\n"; 246d0825bca7fe65beaee391d30da42e937db621564Steve Block exit(1); 247d0825bca7fe65beaee391d30da42e937db621564Steve Block} 2488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub cleanUp 2508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block rmdir $httpdPidDir; 2528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block unlink $exclusiveLockFile; 2538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block unlink $myLockFile if $myLockFile; 2548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub extractLockNumber 2578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my ($lockFile) = @_; 2598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return -1 unless $lockFile; 2608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return substr($lockFile, length($httpdLockPrefix)); 2618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub getLockFiles 2648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block opendir(TMPDIR, $tmpDir) or die "Could not open " . $tmpDir . "."; 2668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my @lockFiles = grep {m/^$httpdLockPrefix\d+$/} readdir(TMPDIR); 2678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block @lockFiles = sort { extractLockNumber($a) <=> extractLockNumber($b) } @lockFiles; 2688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block closedir(TMPDIR); 2698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return @lockFiles; 2708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub getNextAvailableLockNumber 2738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my @lockFiles = getLockFiles(); 2758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return 0 unless @lockFiles; 2768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return extractLockNumber($lockFiles[-1]) + 1; 2778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub getLockNumberForCurrentRunning 2808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my @lockFiles = getLockFiles(); 2828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return 0 unless @lockFiles; 2838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return extractLockNumber($lockFiles[0]); 2848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub waitForHTTPDLock 2878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $waitBeginTime = time; 2898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block scheduleHttpTesting(); 2908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block # If we are the only one waiting for Apache just run the tests without any further checking 2918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (scalar getLockFiles() > 1) { 2928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $currentLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getLockNumberForCurrentRunning()); 2938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $currentLockPid = <SCHEDULER_LOCK> if (-f $currentLockFile && open(SCHEDULER_LOCK, "<$currentLockFile")); 2948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block # Wait until we are allowed to run the http tests 2958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block while ($currentLockPid && $currentLockPid != $$) { 2968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $currentLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getLockNumberForCurrentRunning()); 2978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if ($currentLockFile eq $myLockFile) { 2988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $currentLockPid = <SCHEDULER_LOCK> if open(SCHEDULER_LOCK, "<$currentLockFile"); 2998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if ($currentLockPid != $$) { 3008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block print STDERR "\nPID mismatch.\n"; 3018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block last; 3028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 3038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } else { 3048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block sleep 1; 3058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 3068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 3078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 3088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $waitEndTime = time; 3098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 3108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 3118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub scheduleHttpTesting 3128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 3138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block # We need an exclusive lock file to avoid deadlocks and starvation and ensure that the scheduler lock numbers are sequential. 3148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block # The scheduler locks are used to schedule the running test sessions in first come first served order. 3158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block while (!(open(SEQUENTIAL_GUARD_LOCK, ">$exclusiveLockFile") && flock(SEQUENTIAL_GUARD_LOCK, LOCK_EX|LOCK_NB))) {} 3168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $myLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getNextAvailableLockNumber()); 3178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block open(SCHEDULER_LOCK, ">$myLockFile"); 3188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block print SCHEDULER_LOCK "$$"; 3198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block print SEQUENTIAL_GUARD_LOCK "$$"; 3208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block close(SCHEDULER_LOCK); 3218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block close(SEQUENTIAL_GUARD_LOCK); 3228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block unlink $exclusiveLockFile; 3238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 3248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 3258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocksub getWaitTime 3268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 3278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block my $waitTime = 0; 3288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if ($waitBeginTime && $waitEndTime) { 3298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block $waitTime = $waitEndTime - $waitBeginTime; 3308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 3318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return $waitTime; 3328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 3332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3342fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocksub convertMsysPath 3352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 3362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block my ($path) = @_; 3372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return unless isMsys(); 3382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block $path = `cmd.exe //c echo $path`; 3402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block $path =~ s/\r\n$//; 3412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return $path; 3422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 343