f80a318d55
a job is cancelled.
313 lines
10 KiB
Diff
313 lines
10 KiB
Diff
diff -up foomatic-filters-3.0-20080211/foomatic-rip.in.clean-up-on-cancel foomatic-filters-3.0-20080211/foomatic-rip.in
|
|
--- foomatic-filters-3.0-20080211/foomatic-rip.in.clean-up-on-cancel 2008-02-11 21:16:36.000000000 +0000
|
|
+++ foomatic-filters-3.0-20080211/foomatic-rip.in 2008-03-13 11:42:35.000000000 +0000
|
|
@@ -155,19 +155,19 @@ my $EXIT_PRNERR_NORETRY = 2; # printer
|
|
my $EXIT_JOBERR = 3; # job is defective
|
|
my $EXIT_SIGNAL = 4; # terminated after catching signal
|
|
my $EXIT_ENGAGED = 5; # printer is otherwise engaged (connection
|
|
- # refused)
|
|
+ # refused)
|
|
my $EXIT_STARVED = 6; # starved for system resources
|
|
my $EXIT_PRNERR_NORETRY_ACCESS_DENIED = 7; # bad password? bad port
|
|
- # permissions?
|
|
+ # permissions?
|
|
my $EXIT_PRNERR_NOT_RESPONDING = 8; # just doesn't answer at all
|
|
- # (turned off?)
|
|
+ # (turned off?)
|
|
my $EXIT_PRNERR_NORETRY_BAD_SETTINGS = 9; # interface settings are invalid
|
|
my $EXIT_PRNERR_NO_SUCH_ADDRESS = 10; # address lookup failed, may be
|
|
- # transient
|
|
+ # transient
|
|
my $EXIT_PRNERR_NORETRY_NO_SUCH_ADDRESS = 11; # address lookup failed, not
|
|
- # transient
|
|
+ # transient
|
|
my $EXIT_INCAPABLE = 50; # printer wants (lacks) features
|
|
- # or resources
|
|
+ # or resources
|
|
# Standard Unix signal names
|
|
#my SIGHUP = 1;
|
|
#my SIGINT = 2;
|
|
@@ -181,6 +181,21 @@ my $EXIT_INCAPABLE = 50;
|
|
|
|
my $ESPIPE = 29; # the errno value when seeking a pipe or socket
|
|
|
|
+# The modern_shell() function will register the PIDs of all shell calls,
|
|
+# so that rip_die() can kill these processes
|
|
+my %pids;
|
|
+
|
|
+# $kidgeneration stays 0 for the main process, child processes of the
|
|
+# main process get $kidgeneration = 1, their children 2, ...
|
|
+my $kidgeneration = 0;
|
|
+
|
|
+# Catch signals
|
|
+my $retval = $EXIT_PRINTED;
|
|
+use sigtrap qw(handler set_exit_canceled normal-signals
|
|
+ handler set_exit_error error-signals
|
|
+ handler set_exit_prnerr USR1
|
|
+ handler set_exit_prnerr_noretry USR2
|
|
+ handler set_exit_engaged TTIN);
|
|
|
|
|
|
## Some important variables
|
|
@@ -2153,7 +2168,7 @@ if ($debug) {
|
|
}
|
|
|
|
|
|
-
|
|
+
|
|
## From here on we have to repeat all the rest of the program for
|
|
## every file to print
|
|
|
|
@@ -3538,13 +3553,8 @@ sub getrendererhandle {
|
|
|
|
print $logh "${added_lf}Starting renderer\n";
|
|
|
|
- # Catch signals
|
|
+ # Reset return value of the renderer
|
|
$retval = $EXIT_PRINTED;
|
|
- use sigtrap qw(handler set_exit_prnerr USR1
|
|
- handler set_exit_prnerr_noretry USR2
|
|
- handler set_exit_engaged TTIN);
|
|
-
|
|
- # Variables for the kid processes reporting their state
|
|
|
|
# Set up a pipe for the kids to pass their exit stat to the main process
|
|
pipe KID_MESSAGE, KID_MESSAGE_IN;
|
|
@@ -3585,6 +3595,8 @@ sub getrendererhandle {
|
|
return ( *KID3, $kid3 );
|
|
|
|
} else {
|
|
+ $kidgeneration += 1;
|
|
+
|
|
close KID3;
|
|
|
|
pipe KID4_IN, KID4;
|
|
@@ -3774,6 +3786,8 @@ sub getrendererhandle {
|
|
print $logh "KID3 finished\n";
|
|
exit $EXIT_PRINTED;
|
|
} else {
|
|
+ $kidgeneration += 1;
|
|
+
|
|
# child, trailing task on the pipe; we write jcl stuff
|
|
close KID4;
|
|
close KID3_IN;
|
|
@@ -4112,6 +4126,8 @@ sub getfileconverterhandle {
|
|
return ( *KID1_IN, $kid1 );
|
|
|
|
} else {
|
|
+ $kidgeneration += 1;
|
|
+
|
|
# We go on reading the job data and stuff it into the file
|
|
# converter
|
|
close KID1_IN;
|
|
@@ -4253,6 +4269,8 @@ sub getfileconverterhandle {
|
|
print $logh "KID1 finished\n";
|
|
exit $EXIT_PRINTED;
|
|
} else {
|
|
+ $kidgeneration += 1;
|
|
+
|
|
# child, first part of the pipe, reading in the data from
|
|
# standard input and stuffing it into the file converter
|
|
# after putting in the already read data (in $alreadyread)
|
|
@@ -4580,6 +4598,8 @@ sub getdocgeneratorhandle {
|
|
return ( *KID0_IN, $kid0 );
|
|
}
|
|
|
|
+ $kidgeneration += 1;
|
|
+
|
|
# we are the kid; we generate the documentation page
|
|
|
|
close KID0_IN;
|
|
@@ -4867,66 +4887,100 @@ sub rip_die {
|
|
my $errmsg = "$!";
|
|
my $errcod = $! + 0;
|
|
|
|
- # Close the documentation page generator (if it was used)
|
|
- if ($docgeneratorpid) {
|
|
- if ($kid0) {
|
|
- print $logh "Killing process $kid0 (KID0)\n";
|
|
- kill(9, $kid0);
|
|
+ # Log that we are dying ...
|
|
+ print $logh "Process dying with \"$message\", exit stat: $exitstat\n\terror: $errmsg ($errcod)\n";
|
|
+
|
|
+ print $logh "Cleaning up ...\n";
|
|
+ foreach my $killsignal (15, 9) {
|
|
+
|
|
+ # Kill all registered subshells
|
|
+ foreach my $pid (keys %pids) {
|
|
+ print $logh "Killing process $pid ($pids{$pid}) and its subprocesses with signal $killsignal\n";
|
|
+ # This call kills the process group with group ID $pid, the
|
|
+ # group which was formed from the initial process $pid which
|
|
+ # contains $pid and all its subprocesses
|
|
+ kill(-$killsignal, $pid);
|
|
+ # If the system does not support process groups and therefore
|
|
+ # the call above does not kill anything, kill at least $pid
|
|
+ kill($killsignal, $pid);
|
|
}
|
|
- $docgeneratorpid = 0;
|
|
- }
|
|
|
|
- # Close the file converter (if it was used)
|
|
- if ($fileconverterpid) {
|
|
+ # Close the documentation page generator (if it was used)
|
|
+ if ($kid0) {
|
|
+ print $logh "Killing process $kid0 (KID0) with signal $killsignal\n";
|
|
+ kill($killsignal, $kid0);
|
|
+ }
|
|
+
|
|
+ # Close the file converter (if it was used)
|
|
if ($kid2) {
|
|
- print $logh "Killing process $kid2 (KID2)\n";
|
|
- kill(9, $kid2);
|
|
+ print $logh "Killing process $kid2 (KID2) with signal $killsignal\n";
|
|
+ kill($killsignal, $kid2);
|
|
}
|
|
if ($kid1) {
|
|
- print $logh "Killing process $kid1 (KID1)\n";
|
|
- kill(9, $kid1);
|
|
+ print $logh "Killing process $kid1 (KID1) with signal $killsignal\n";
|
|
+ kill($killsignal, $kid1);
|
|
}
|
|
- $fileconverterpid = 0;
|
|
- }
|
|
|
|
- # Close the renderer
|
|
- if ($rendererpid) {
|
|
+ # Close the renderer
|
|
if ($kid4) {
|
|
- print $logh "Killing process $kid4 (KID4)\n";
|
|
- kill(9, $kid4);
|
|
+ print $logh "Killing process $kid4 (KID4) with signal $killsignal\n";
|
|
+ kill($killsignal, $kid4);
|
|
}
|
|
if ($kid3) {
|
|
- print $logh "Killing process $kid3 (KID3)\n";
|
|
- kill(9, $kid3);
|
|
+ print $logh "Killing process $kid3 (KID3) with signal $killsignal\n";
|
|
+ kill($killsignal, $kid3);
|
|
}
|
|
- $rendererpid = 0;
|
|
+
|
|
+ # Wait some time for the processes to close
|
|
+ sleep(5 - $kidgeneration) if $killsignal != 9;
|
|
}
|
|
|
|
- print $logh "Process dying with \"$message\", exit stat: $exitstat\n\terror: $errmsg ($errcod)\n";
|
|
- if ($spooler eq 'ppr_int') {
|
|
- # Special error handling for PPR intefaces
|
|
- $message =~ s/\\/\\\\/;
|
|
- $message =~ s/\"/\\\"/;
|
|
- my @messagelines = split("\n", $message);
|
|
- my $firstline = "TRUE";
|
|
- for my $line (@messagelines) {
|
|
- modern_system("lib/alert $printer $firstline \"$line\"");
|
|
- $firstline = "FALSE";
|
|
+ # Do the debug dump and the PPR error handling only from the main process
|
|
+ if ($kidgeneration == 0) { # We are the main process
|
|
+
|
|
+ if ($spooler eq 'ppr_int') {
|
|
+ # Special error handling for PPR intefaces
|
|
+ $message =~ s/\\/\\\\/;
|
|
+ $message =~ s/\"/\\\"/;
|
|
+ my @messagelines = split("\n", $message);
|
|
+ my $firstline = "TRUE";
|
|
+ for my $line (@messagelines) {
|
|
+ modern_system("lib/alert $printer $firstline \"$line\"");
|
|
+ $firstline = "FALSE";
|
|
+ }
|
|
+ } else {
|
|
+ print STDERR $message . "\n";
|
|
+ }
|
|
+ if ($debug) {
|
|
+ use Data::Dumper;
|
|
+ local $Data::Dumper::Purity=1;
|
|
+ local $Data::Dumper::Indent=1;
|
|
+ print $logh Dumper($dat);
|
|
}
|
|
- } else {
|
|
- print STDERR $message . "\n";
|
|
- }
|
|
- if ($debug) {
|
|
- use Data::Dumper;
|
|
- local $Data::Dumper::Purity=1;
|
|
- local $Data::Dumper::Indent=1;
|
|
- print $logh Dumper($dat);
|
|
}
|
|
+
|
|
+ ## The End
|
|
+ print $logh "${added_lf}Closing foomatic-rip.\n";
|
|
+ close $logh;
|
|
+
|
|
exit $exitstat;
|
|
}
|
|
|
|
# Signal handling routines
|
|
|
|
+sub do_nothing {
|
|
+}
|
|
+
|
|
+sub set_exit_canceled {
|
|
+ $retval = $EXIT_PRINTED;
|
|
+ rip_die ("Caught termination signal: Job canceled", $retval);
|
|
+}
|
|
+
|
|
+sub set_exit_error {
|
|
+ $retval = $EXIT_SIGNAL;
|
|
+ rip_die ("Caught error signal: Error in renderer, driver, or foomatic-rip", $retval);
|
|
+}
|
|
+
|
|
sub set_exit_prnerr {
|
|
$retval = $EXIT_PRNERR;
|
|
}
|
|
@@ -6592,20 +6646,36 @@ sub read_attribute_file {
|
|
sub modern_system {
|
|
my (@list) = @_;
|
|
|
|
- if (($modern_shell =~ /.+/) && ($modern_shell ne '/bin/sh')) {
|
|
- # a "modern" shell other than the default shell was specified
|
|
- my $pid = fork();
|
|
-
|
|
- ($pid < 0) && die "failed to fork()";
|
|
-
|
|
- if ($pid == 0) { # child, execute the commands under a modern shell
|
|
- exec($modern_shell, "-c", @list);
|
|
- die "exec($modern_shell, \"-c\", @list);";
|
|
- } else { # parent, wait for the child
|
|
- waitpid($pid, 0);
|
|
- }
|
|
- } else { # the system shell is "modern" enough.
|
|
- system(@list);
|
|
+ if ($modern_shell |~ /.+/) {
|
|
+ # No "modern" shell other than the default shell was specified
|
|
+ $modern_shell = '/bin/sh';
|
|
+ }
|
|
+
|
|
+ my $pid = fork();
|
|
+ ($pid < 0) && die "failed to fork()";
|
|
+
|
|
+ if ($pid == 0) { # child, execute the commands under a modern shell
|
|
+ # If the system supports process groups, we create a process
|
|
+ # group of this subshell process. All the children of this
|
|
+ # process (calls of external filters, renderers, or drivers)
|
|
+ # will be members of this process group and so by killing this
|
|
+ # process group we can kill all subprocesses and so we can
|
|
+ # cleanly cancel print jobs
|
|
+ eval("setpgrp()");
|
|
+ # Stop catching signals
|
|
+ #use sigtrap qw(die normal-signals error-signals
|
|
+ # handler do_nothing USR1 USR2 TTIN);
|
|
+ exec($modern_shell, "-c", @list);
|
|
+ rip_die("exec($modern_shell, \"-c\", @list);",
|
|
+ $EXIT_PRNERR_NORETRY_BAD_SETTINGS);
|
|
+ } else { # parent, register child's PID, wait for the child, and
|
|
+ # unregister the PID
|
|
+ $pids{$pid} = substr(join(" ", @list), 0, 100) .
|
|
+ (length(join(" ", @list)) > 100 ? "..." : "");
|
|
+ print $logh "Starting process $pid: \"$pids{$pid}\"\n";
|
|
+ waitpid($pid, 0);
|
|
+ print $logh "Process $pid ending: \"$pids{$pid}\"\n";
|
|
+ delete $pids{$pid};
|
|
}
|
|
}
|
|
|