tags:

views:

2508

answers:

3

Hello, I have a java app that uses ProcessBuilder to prepare an operating system command and gives me a Process object. (The actual os command is rsync over ssh using cygwin).

This is working well in wondows, however if I want to stop the process using process.destroy() it will not kill the child ssh and rsync processes..... I have to manually kill them using the windows task manager..

Is it possible to get the OutputStream of the process and send a ctrl-c somehow before I call destroy();?

If anyone has any ideas on a workaround it would be great. Thanks, D

A: 

I'm not sure what Process.destroy() does under the covers (sends a signal or similar?).

What you may find works better is to invoke your ssh/rsync within a shell script, and have that return a process id on stdout, and then when you want to kill the process, perform a /bin/kill with that process id. A little messy, but perhaps more reliable.

Note you can /bin/kill with SIGTERM, and SIGKILL if it's particularly stubborn.

Brian Agnew
Process.destroy() calls the Windows function TerminateProcess (http://msdn.microsoft.com/en-us/library/ms686714(VS.85).aspx ).
Michael Myers
+3  A: 

I also think that emulating Ctrl-C in order to kill ssh entirely is problematic.

What I would do, is one of the following approaches. Either use windows commands to find out who are ssh's sons (which is a little bit problematic, since you need to know your current pid in order to recieve your own children-processes). I believe pstools of sysinternals is a good command-line tool that should enable you to track orphan processes. See this example for controlling windows processes either with taskList.exe (which can give you its output in CSV format BTW) or by executing a special VBScript.

The second approach is using a java library such as winp to execute and control the ssh process. I believe you'd be able to list all its children and forcibly kill them if sending the correct message would not suffice. This would be my preferred approach. Please note that the killRecursively method does exactly what you want.

Please note that those approaches should not render your application windows only. You can encapsulate those in a class that would run differently on Windows and linux machines.

Please note I didn't try to gain a fine-grained control on windows processes with, so I'm not sure how mature would those solutions I found are.

Elazar Leibovich
A: 

Thanks everyone for the help. Been thinking about it and reading the cygwin documentation. I think i can use a combination of ps and kill to kill any orphan processes as the ps will just list the cygwin processes. I'll do this from within the java app using the ProcessBuilder to call cygwin.

Thanks again. D

Derek