- Timestamp:
- 2017-05-24T19:59:51+12:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/gli/src/org/greenstone/gatherer/util/SafeProcess.java
r31697 r31699 751 751 } 752 752 753 // https://stackoverflow.com/questions/8533377/why-child-process-still-alive-after-parent-process-was-killed-in-linux 754 // Didn't work for when build scripts run from GLI: kill -TERM -pid 755 // but the other suggestion did work: pkill -TERM -P pid did work 756 // https://unix.stackexchange.com/questions/117227/why-pidof-and-pgrep-are-behaving-differently 757 // https://unix.stackexchange.com/questions/67635/elegantly-get-list-of-children-processes 758 // https://stackoverflow.com/questions/994033/mac-os-x-quickest-way-to-kill-quit-an-entire-process-tree-from-within-a-cocoa-a 759 // https://unix.stackexchange.com/questions/132224/is-it-possible-to-get-process-group-id-from-procâÃâà 760 761 /** 762 * On Unix, will kill the process denoted by processID and any subprocessed this launched. Tested on a Mac. 763 * @force if true will send the -KILL (-9) signal, which may result in abrupt termination 764 * if false, will send the -TERM (-15) signal, which will allow cleanup before termination 765 * @killEntireTree if false, will terminate only the process denoted by processID, otherwise all descendants too. 766 * @return true if running the kill process returned an exit value of 0 767 * 768 */ 769 static boolean killUnixProcessTreeWithID(long processID, boolean force, boolean killEntireTree) { 770 // Kill signals, their names and numerical equivalents: http://www.faqs.org/qa/qa-831.html 771 772 /* 773 String cmd = force ? "kill -KILL" : "kill -TERM"; // kill -15 vs kill -9 774 // https://stackoverflow.com/questions/8533377/why-child-process-still-alive-after-parent-process-was-killed-in-linux 775 cmd += killEntireTree ? " -" : " "; // prefix hyphen to pid to kill all subprocesses launched by pid 776 cmd = cmd + processID; 777 */ 778 779 String cmd = "pkill -TERM -P " + processID; 780 if(force) { 781 cmd = "pkill -KILL -P " + processID; 782 } 783 784 SafeProcess proc = new SafeProcess(cmd); 785 int exitValue = proc.runProcess(); 786 if(exitValue != 0) { 787 log("@@@ Not able to successfull terminate process, got exitvalue " + exitValue); 788 log("@@@ Got output " + proc.getStdOutput()); 789 log("@@@ Got err output " + proc.getStdError()); 790 // caller can try again with kill -KILL, by setting force parameter to true 791 return false; 792 } else { 793 if(force) { 794 log("@@@ Successfully sent SIGKILL to unix process tree rooted at " + processID); 795 } else { 796 log("@@@ Successfully sent SIGTERM to unix process tree rooted at " + processID); 797 } 798 return true; 799 } 800 } 801 802 /** UNUSED. Kills only the process represented by the processID. 803 * @force if true will send the -KILL (-9) signal, which may result in abrupt termination 804 * if false, will send the -TERM (-15) signal, which will allow cleanup before termination 805 * @return true if running the kill process returned an exit value of 0 806 */ 807 static boolean killUnixProcessWithID(long processID, boolean force) { 808 // Kill signals, their names and numerical equivalents: http://www.faqs.org/qa/qa-831.html 809 String cmd = force ? "kill -KILL" : "kill -TERM"; // kill -15 vs kill -9 810 cmd = cmd + " " + processID; 811 812 SafeProcess proc = new SafeProcess(cmd); 813 int exitValue = proc.runProcess(); 814 if(exitValue != 0) { 815 log("@@@ Not able to successfull terminate process, got exitvalue " + exitValue); 816 log("@@@ Got output " + proc.getStdOutput()); 817 log("@@@ Got err output " + proc.getStdError()); 818 // caller can try again with kill -KILL, by setting force parameter to true 819 return false; 820 } else { 821 if(force) { 822 log("@@@ Successfully sent SIGKILL to unix process " + processID); 823 } else { 824 log("@@@ Successfully sent SIGTERM to unix process " + processID); 825 } 826 return true; 827 } 828 } 829 753 830 754 831 // On linux and mac, p.destroy() suffices to kill processes launched by p as well. … … 758 835 log("### in SafeProcess.destroyProcess(Process p)"); 759 836 837 String osName = Utility.getOSdirName(); 838 760 839 // If it isn't windows, process.destroy() terminates any child processes too 761 if( !Utility.isWindows()) {840 if(osName.equals("linux")) { 762 841 p.destroy(); 763 842 return; 764 } 765 843 } 844 845 if(osName.equals("darwin")) { 846 long pid = SafeProcess.getProcessID(p); 847 /* 848 // On Macs (all Unix?) can't get the child processes of a process once it's been destroyed 849 macTerminateSubProcessesRecursively(pid, p); // pid, true) 850 */ 851 852 if(pid == -1) { 853 p.destroy(); // at minimum, will have no effect if the process had already terminated 854 } else { 855 boolean forceKill = false; 856 boolean killEntireProcessTree = true; 857 if(!killUnixProcessTreeWithID(pid, !forceKill, killEntireProcessTree)) { // send sig TERM (kill -15 or kill -TERM) 858 killUnixProcessTreeWithID(pid, forceKill, killEntireProcessTree); // send sig KILL (kill -9 or kill -KILL) 859 } 860 } 861 862 return; 863 } 864 865 // else we're on windows: 866 766 867 if(!SafeProcess.isAvailable("wmic")) { 767 868 log("wmic, used to kill subprocesses, is not available. Unable to terminate subprocesses..."); … … 784 885 } 785 886 887 } 888 889 890 // UNUSED 891 // But if this method is needed, then need to parse childpids printed by "pgrep -P pid" and write recursive step 892 // The childpids are probably listed one per line, see https://unix.stackexchange.com/questions/117227/why-pidof-and-pgrep-are-behaving-differently 893 private static void macTerminateSubProcessesRecursively(long parent_pid, Process p) { //boolean isTopLevelProcess) { 894 log("@@@ Attempting to terminate mac process recursively"); 895 896 // https://unix.stackexchange.com/questions/67635/elegantly-get-list-of-children-processes 897 SafeProcess proc = new SafeProcess("pgrep -P "+parent_pid); 898 int exitValue = proc.runProcess(); 899 String stdOutput = proc.getStdOutput(); 900 String stdErrOutput = proc.getStdError(); 901 902 // now we have the child processes, can terminate the parent process 903 if(p != null) { // top level process, can just be terminated the java way with p.destroy() 904 p.destroy(); 905 } else { 906 // get rid of process with current pid 907 if(!SafeProcess.killUnixProcessWithID(parent_pid, false)) { // send kill -TERM, kill -15 908 SafeProcess.killUnixProcessWithID(parent_pid, true); // send kill -9, kill -KILL 909 } 910 } 911 912 /* 913 // get rid of any process with current pid 914 if(!isTopLevelProcess && !SafeProcess.killUnixProcessWithID(parent_pid, false)) { // send kill -TERM, kill -15 915 SafeProcess.killUnixProcessWithID(parent_pid, true); // send kill -9, kill -KILL 916 } 917 */ 918 919 if(stdOutput.trim().equals("") && stdErrOutput.trim().equals("") && exitValue == 1) { 920 log("No child processes"); 921 // we're done 922 return; 923 } else { 924 log("Got childpids on STDOUT: " + stdOutput); 925 log("Got childpids on STDERR: " + stdErrOutput); 926 } 786 927 } 787 928 … … 812 953 p.destroy(); 813 954 } else { // terminate windows way 814 SafeProcess.killWinProcessWithID(parent_pid); // get rid of fcurrent pid955 SafeProcess.killWinProcessWithID(parent_pid); // get rid of process with current pid 815 956 } 816 957
Note:
See TracChangeset
for help on using the changeset viewer.