Permalink
Browse files

From pull request #319.

Squashed commit of the following:

commit 5c29a2ee1bbd9855eaab9531fdfdf4a3d97f297e
Author: rogerdpack <rogerpack2005@gmail.com>
Date:   Wed Sep 26 17:44:12 2012 -0600

     implement Signal.kill 0 for windows

commit 66321aa1d43468edde119be2b3412aac51289ca4
Author: rogerdpack <rogerpack2005@gmail.com>
Date:   Wed Sep 26 16:54:04 2012 -0600

    throw not implemented for unimplemented signals in windows
  • Loading branch information...
1 parent 4381bc2 commit 679a73173f933f63de0ba58a7d7e822af3b12424 @headius headius committed Sep 29, 2012
Showing with 47 additions and 17 deletions.
  1. +47 −17 src/org/jruby/RubyProcess.java
View
64 src/org/jruby/RubyProcess.java
@@ -29,6 +29,7 @@
***** END LICENSE BLOCK *****/
package org.jruby;
+import jnr.ffi.*;
import jnr.constants.platform.Signal;
import jnr.constants.platform.Sysconf;
import jnr.posix.Times;
@@ -880,7 +881,13 @@ private static int parseSignalString(Ruby runtime, String value) {
throw runtime.newArgumentError("unsupported name `" + signalName + "'");
}
}
-
+
+ public static interface Kernel32 {
+ jnr.ffi.Pointer OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
+ int CloseHandle(jnr.ffi.Pointer handle);
+ int GetLastError();
+ }
+
@Deprecated
public static IRubyObject kill(IRubyObject recv, IRubyObject[] args) {
return kill(recv.getRuntime(), args);
@@ -894,12 +901,6 @@ public static IRubyObject kill(Ruby runtime, IRubyObject[] args) {
throw runtime.newArgumentError("wrong number of arguments -- kill(sig, pid...)");
}
- // Windows does not support these functions, so we won't even try
- // This also matches Ruby behavior for JRUBY-2353.
- if (Platform.IS_WINDOWS) {
- return runtime.getNil();
- }
-
int signal;
if (args[0] instanceof RubyFixnum) {
signal = (int) ((RubyFixnum) args[0]).getLongValue();
@@ -913,18 +914,47 @@ public static IRubyObject kill(Ruby runtime, IRubyObject[] args) {
boolean processGroupKill = signal < 0;
- if (processGroupKill) signal = -signal;
-
- POSIX posix = runtime.getPosix();
- for (int i = 1; i < args.length; i++) {
- int pid = RubyNumeric.num2int(args[i]);
-
- // FIXME: It may be possible to killpg on systems which support it. POSIX library
- // needs to tell whether a particular method works or not
- if (pid == 0) pid = runtime.getPosix().getpid();
- checkErrno(runtime, posix.kill(processGroupKill ? -pid : pid, signal));
+ if (processGroupKill) {
+ if (Platform.IS_WINDOWS) {
+ throw runtime.newErrnoEINVALError("group signals not implemented in windows");
+ }
+ signal = -signal;
}
+ if (Platform.IS_WINDOWS) {
+ if (signal == 0) {
+ Kernel32 libc = Library.loadLibrary("kernel32", Kernel32.class);
+ int PROCESS_QUERY_INFORMATION = 0x0400;
+ int ERROR_INVALID_PARAMETER = 0x57;
+ for (int i = 1; i < args.length; i++) {
+ int pid = RubyNumeric.num2int(args[i]);
+ jnr.ffi.Pointer ptr = libc.OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
+ if(ptr != null && ptr.address() != -1) {
+ libc.CloseHandle(ptr); // success
+ } else {
+ if (libc.GetLastError() == ERROR_INVALID_PARAMETER) {
+ throw runtime.newErrnoESRCHError();
+ } else {
+ throw runtime.newErrnoEPERMError("Process does not exist " + pid);
+ }
+ }
+ }
+
+ } else {
+ throw runtime.newNotImplementedError("this signal not yet implemented in windows");
+ }
+ } else {
+ POSIX posix = runtime.getPosix();
+ for (int i = 1; i < args.length; i++) {
+ int pid = RubyNumeric.num2int(args[i]);
+
+ // FIXME: It may be possible to killpg on systems which support it. POSIX library
+ // needs to tell whether a particular method works or not
+ if (pid == 0) pid = runtime.getPosix().getpid();
+ checkErrno(runtime, posix.kill(processGroupKill ? -pid : pid, signal));
+ }
+ }
+
return runtime.newFixnum(args.length - 1);
}

0 comments on commit 679a731

Please sign in to comment.