Reputation: 4185
I want to kill a process started by (sb-ext:run-program)
.
(let ((process (sb-ext:run-program "/path/to/process.sh" '() :wait nil)))
(sleep 10)
(sb-ext:process-close process)
(sb-ext:process-kill process 9 :pid))
According to SBCL-Manual (sb-ext:process-kill process 9 :pid)
should send SIGKILL
(which has value 9) to process
, therefore annihilating this process.
But when I am trying to use this using a dummy process:
#!/bin/bash
i=0
while [ $i -lt 4 ]
do
sleep 5
i+=1
done
It leaves a corps behind which cannot even be killed using htop + kill.
The process tree before execution looked like this:
|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
During execution:
|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- /bin/bash /path/to/process.sh
| | | |- sleep 5
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
After execution (the process.sh will not terminate unless the main sbcl is killed/stopped):
|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- process.sh
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
The script can be killed and terminated just fine when started manually and using either Ctr-C
or htop + kill
.
Therefore how can I achive a seamless/corpsless kill within sbcl?
The same happens when using:
(let ((process (sb-ext:run-program "/usr/local/bin/sbcl" '("--dynamic-space-size" "512" "--eval" "(sleep 100)") :wait nil)))
(sleep 10)
(sb-ext:process-close process)
(sb-ext:process-kill process 9 :pid))
Upvotes: 2
Views: 1683
Reputation: 4722
If you're using the portable uiop:run-program
instead of the sbcl's one, you can kill the PID by calling run-program a second time, giving it the kill command, just like you would in the shell:
(uiop:run-program (format nil "kill ~a" (process-info-pid process)))
Where process
is the return result of the initial run-program
, the one that started the process you want to kill.
Upvotes: 0
Reputation: 4185
The solution looks either like this (if you use streams associated with the process you need process-close):
(let ((process (sb-ext:run-program "/home/user/processTest.sh" '() :wait nil)))
(sleep 10)
(sb-ext:process-kill process 15 :pid)
(sb-ext:process-wait process)
(sb-ext:process-close process)
(sb-ext:process-exit-code process))
Or as Sylvester pointed out you can just leave out the process-close
(if you do not have any streams associated with the process):
(let ((process (sb-ext:run-program "/home/user/processTest.sh" '() :wait nil)))
(sleep 10)
(sb-ext:process-kill process 15 :pid))
process-close
affects the process in a way that it will become a zombie.
This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status.
As soon as the exit status is read via process-exit-code
the process is reaped and will disappear.
Upvotes: 4