# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at http://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
-# $Id$
###########################################################################
use strict;
use warnings;
+use serverhelp qw(
+ servername_id
+ mainsockf_pidfilename
+ datasockf_pidfilename
+ );
+
#######################################################################
# pidfromfile returns the pid stored in the given pidfile. The value
# of the returned pid will never be a negative value. It will be zero
}
#######################################################################
+# pidexists checks if a process with a given pid exists and is alive.
+# This will return the positive pid if the process exists and is alive.
+# This will return the negative pid if the process exists differently.
+# This will return 0 if the process could not be found.
+#
+sub pidexists {
+ my $pid = $_[0];
+
+ if($pid > 0) {
+ # verify if currently existing and alive
+ if(kill(0, $pid)) {
+ return $pid;
+ }
+
+ # verify if currently existing Windows process
+ if($^O eq "msys") {
+ my $filter = "PID eq $pid";
+ my $result = `tasklist -fi \"$filter\" 2>nul`;
+ if(index($result, "$pid") != -1) {
+ return -$pid;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#######################################################################
+# pidterm asks the process with a given pid to terminate gracefully.
+#
+sub pidterm {
+ my $pid = $_[0];
+
+ if($pid > 0) {
+ # signal the process to terminate
+ kill("TERM", $pid);
+
+ # request the process to quit
+ if($^O eq "msys") {
+ my $filter = "PID eq $pid";
+ my $result = `tasklist -fi \"$filter\" 2>nul`;
+ if(index($result, "$pid") != -1) {
+ system("taskkill -fi \"$filter\" >nul 2>&1");
+ }
+ }
+ }
+}
+
+#######################################################################
+# pidkill kills the process with a given pid mercilessly andforcefully.
+#
+sub pidkill {
+ my $pid = $_[0];
+
+ if($pid > 0) {
+ # signal the process to terminate
+ kill("KILL", $pid);
+
+ # request the process to quit
+ if($^O eq "msys") {
+ my $filter = "PID eq $pid";
+ my $result = `tasklist -fi \"$filter\" 2>nul`;
+ if(index($result, "$pid") != -1) {
+ system("taskkill -f -fi \"$filter\" >nul 2>&1");
+ # Windows XP Home compatibility
+ system("tskill $pid >nul 2>&1");
+ }
+ }
+ }
+}
+
+#######################################################################
# processexists checks if a process with the pid stored in the given
# pidfile exists and is alive. This will return 0 on any file related
# error or if a pid can not be extracted from the given file. When a
if($pid > 0) {
# verify if currently alive
- if(kill(0, $pid)) {
+ if(pidexists($pid)) {
return $pid;
}
else {
if($tmp =~ /^(\d+)$/) {
my $pid = $1;
if($pid > 0) {
- if(kill(0, $pid)) {
+ if(pidexists($pid)) {
print("RUN: Process with pid $pid signalled to die\n")
if($verbose);
- kill("TERM", $pid);
+ pidterm($pid);
push @signalled, $pid;
}
else {
while($twentieths--) {
for(my $i = scalar(@signalled) - 1; $i >= 0; $i--) {
my $pid = $signalled[$i];
- if(!kill(0, $pid)) {
+ if(!pidexists($pid)) {
print("RUN: Process with pid $pid gracefully died\n")
if($verbose);
splice @signalled, $i, 1;
if($pid > 0) {
print("RUN: Process with pid $pid forced to die with SIGKILL\n")
if($verbose);
- kill("KILL", $pid);
+ pidkill($pid);
# if possible reap its dead children
waitpid($pid, &WNOHANG);
push @reapchild, $pid;
}
}
-#############################################################################
-# Kill a specific slave
+#######################################################################
+# killsockfilters kills sockfilter processes for a given server.
#
-sub ftpkillslave {
- my ($id, $ext, $verbose)=@_;
+sub killsockfilters {
+ my ($proto, $ipvnum, $idnum, $verbose, $which) = @_;
+ my $server;
+ my $pidfile;
+ my $pid;
- for my $base (('filt', 'data')) {
- my $f = ".sock$base$id$ext.pid";
- my $pid = processexists($f);
+ return if($proto !~ /^(ftp|imap|pop3|smtp)$/);
+
+ die "unsupported sockfilter: $which"
+ if($which && ($which !~ /^(main|data)$/));
+
+ $server = servername_id($proto, $ipvnum, $idnum) if($verbose);
+
+ if(!$which || ($which eq 'main')) {
+ $pidfile = mainsockf_pidfilename($proto, $ipvnum, $idnum);
+ $pid = processexists($pidfile);
+ if($pid > 0) {
+ printf("* kill pid for %s-%s => %d\n", $server,
+ ($proto eq 'ftp')?'ctrl':'filt', $pid) if($verbose);
+ pidkill($pid);
+ waitpid($pid, 0);
+ }
+ unlink($pidfile) if(-f $pidfile);
+ }
+
+ return if($proto ne 'ftp');
+
+ if(!$which || ($which eq 'data')) {
+ $pidfile = datasockf_pidfilename($proto, $ipvnum, $idnum);
+ $pid = processexists($pidfile);
if($pid > 0) {
- printf("* kill pid for %s => %d\n", "ftp-$base$id$ext", $pid)
- if($verbose);
- kill (9, $pid);
+ printf("* kill pid for %s-data => %d\n", $server,
+ $pid) if($verbose);
+ pidkill($pid);
waitpid($pid, 0);
}
- unlink($f);
+ unlink($pidfile) if(-f $pidfile);
}
}
-#############################################################################
-# Make sure no FTP leftovers are still running. Kill all slave processes.
-# This uses pidfiles since it might be used by other processes.
+#######################################################################
+# killallsockfilters kills sockfilter processes for all servers.
#
-sub ftpkillslaves {
- my ($verbose) = @_;
-
- for my $ext (('', 'ipv6')) {
- for my $id (('', '2')) {
- for my $base (('filt', 'data')) {
- my $f = ".sock$base$id$ext.pid";
- my $pid = processexists($f);
- if($pid > 0) {
- printf("* kill pid for %s => %d\n", "ftp-$base$id$ext",
- $pid) if($verbose);
- kill (9, $pid);
- waitpid($pid, 0);
- }
- unlink($f);
+sub killallsockfilters {
+ my $verbose = $_[0];
+
+ for my $proto (('ftp', 'imap', 'pop3', 'smtp')) {
+ for my $ipvnum (('4', '6')) {
+ for my $idnum (('1', '2')) {
+ killsockfilters($proto, $ipvnum, $idnum, $verbose);
}
}
}