win32-process 0.5.8 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +3 -0
- data/README +16 -12
- data/lib/win32/process.rb +44 -3
- data/test/tc_process.rb +15 -6
- data/win32-process.gemspec +2 -2
- metadata +3 -3
data/CHANGES
CHANGED
data/README
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
= Description
|
2
2
|
This package provides the fork, wait, wait2, waitpid, and waitpid2 methods
|
3
|
-
for MS Windows.
|
4
|
-
kill method.
|
3
|
+
for MS Windows. In addition, it provides a different implementation of the
|
4
|
+
kill method, and a proper implementation of the Process.ppid method.
|
5
5
|
|
6
6
|
= Prerequisites
|
7
7
|
Ruby 1.8.2 or later.
|
8
|
-
The 'windows-pr' library, 0.
|
9
|
-
The 'sys-proctable' library, 0.7.
|
8
|
+
The 'windows-pr' library, 0.8.6 or later.
|
9
|
+
The 'sys-proctable' library, 0.7.6 or later (test suite only).
|
10
10
|
|
11
11
|
= Supported Platforms
|
12
12
|
This library is supported on Windows 2000 or later.
|
@@ -29,7 +29,7 @@
|
|
29
29
|
puts 'Done'
|
30
30
|
|
31
31
|
= Developer's Notes
|
32
|
-
== The fork and wait methods
|
32
|
+
== The Process.fork and Process.wait methods
|
33
33
|
The fork method is emulated on Windows by spawning another Ruby process
|
34
34
|
against $PROGRAM_NAME via the CreateProcess() Win32 API function. It will
|
35
35
|
use its parent's environment and starting directory.
|
@@ -46,25 +46,29 @@
|
|
46
46
|
IMPORTANT!
|
47
47
|
Note that because fork is calling CreateProcess($PROGRAM_NAME), it will
|
48
48
|
start again from the top of the script instead of from the point of the
|
49
|
-
call.
|
49
|
+
call. We will try to address this in a future release, if possible.
|
50
50
|
|
51
|
-
== The kill method
|
51
|
+
== The Process.kill method
|
52
52
|
Initially, the kill method will try to get a HANDLE on the PID using the
|
53
|
-
OpenProcess() function.
|
53
|
+
OpenProcess() function. If that succeeds, we know the process is running.
|
54
54
|
|
55
55
|
In the event of signal 2 or signal 3, the GenerateConsoleCtrlEvent()
|
56
|
-
function is used to send a signal to that process.
|
57
|
-
GUI processes.
|
56
|
+
function is used to send a signal to that process. These will not kill
|
57
|
+
GUI processes. It will not (currently) send a signal to remote
|
58
58
|
processes.
|
59
59
|
|
60
60
|
In the event of signal 1 or 4-8, the CreateRemoteThread() function is used
|
61
61
|
after the HANDLE's process has been identified to create a thread
|
62
|
-
within that process.
|
62
|
+
within that process. The ExitProcess() function is then sent to that
|
63
63
|
thread.
|
64
64
|
|
65
|
-
In the event of signal 9, the TerminateProcess() function is called.
|
65
|
+
In the event of signal 9, the TerminateProcess() function is called. This
|
66
66
|
will almost certainly kill the process, but doesn't give the process a
|
67
67
|
chance to necessarily do any cleanup it might otherwise do.
|
68
|
+
|
69
|
+
== The Process.ppid method
|
70
|
+
In MRI the Process.ppid always returns 0 on MS Windows. With this library
|
71
|
+
it returns the actual parent pid.
|
68
72
|
|
69
73
|
== Differences between Ruby's kill and the Win32 Utils kill
|
70
74
|
Ruby does not currently use the CreateRemoteThread() + ExitProcess()
|
data/lib/win32/process.rb
CHANGED
@@ -7,14 +7,15 @@ require 'windows/library'
|
|
7
7
|
require 'windows/console'
|
8
8
|
require 'windows/window'
|
9
9
|
require 'windows/unicode'
|
10
|
+
require 'windows/tool_helper'
|
10
11
|
|
11
12
|
module Process
|
12
13
|
class Error < RuntimeError; end
|
13
14
|
|
14
15
|
# Eliminates redefinition warnings.
|
15
|
-
undef_method :kill, :wait, :wait2, :waitpid, :waitpid2
|
16
|
+
undef_method :kill, :wait, :wait2, :waitpid, :waitpid2, :ppid
|
16
17
|
|
17
|
-
WIN32_PROCESS_VERSION = '0.5.
|
18
|
+
WIN32_PROCESS_VERSION = '0.5.9'
|
18
19
|
|
19
20
|
include Windows::Process
|
20
21
|
include Windows::Thread
|
@@ -25,6 +26,7 @@ module Process
|
|
25
26
|
include Windows::Synchronize
|
26
27
|
include Windows::Window
|
27
28
|
include Windows::Unicode
|
29
|
+
include Windows::ToolHelper
|
28
30
|
extend Windows::Error
|
29
31
|
extend Windows::Process
|
30
32
|
extend Windows::Thread
|
@@ -33,6 +35,7 @@ module Process
|
|
33
35
|
extend Windows::Library
|
34
36
|
extend Windows::Console
|
35
37
|
extend Windows::Unicode
|
38
|
+
extend Windows::ToolHelper
|
36
39
|
|
37
40
|
# Used by Process.create
|
38
41
|
ProcessInfo = Struct.new("ProcessInfo",
|
@@ -589,9 +592,46 @@ module Process
|
|
589
592
|
nil
|
590
593
|
end
|
591
594
|
|
595
|
+
# Returns the process ID of the parent of this process.
|
596
|
+
#--
|
597
|
+
# In MRI this method always returns 0.
|
598
|
+
#
|
599
|
+
def ppid
|
600
|
+
ppid = 0
|
601
|
+
|
602
|
+
return ppid if Process.pid == 0 # Paranoia
|
603
|
+
|
604
|
+
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
|
605
|
+
|
606
|
+
if handle == INVALID_HANDLE_VALUE
|
607
|
+
raise Error, get_last_error
|
608
|
+
end
|
609
|
+
|
610
|
+
proc_entry = 0.chr * 296 # 36 + 260
|
611
|
+
proc_entry[0, 4] = [proc_entry.size].pack('L') # Set dwSize member
|
612
|
+
|
613
|
+
unless Process32First(handle, proc_entry)
|
614
|
+
CloseHandle(handle)
|
615
|
+
raise Error, get_last_error
|
616
|
+
end
|
617
|
+
|
618
|
+
while Process32Next(handle, proc_entry)
|
619
|
+
if proc_entry[8, 4].unpack('L')[0] == Process.pid
|
620
|
+
ppid = proc_entry[24, 4].unpack('L')[0] # th32ParentProcessID
|
621
|
+
break
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
625
|
+
ppid
|
626
|
+
end
|
627
|
+
|
592
628
|
# Creates the equivalent of a subshell via the CreateProcess() function.
|
593
629
|
# This behaves in a manner that is similar, but not identical to, the
|
594
|
-
# Kernel.fork method for Unix.
|
630
|
+
# Kernel.fork method for Unix. Unlike the Unix fork, this method starts
|
631
|
+
# from the top of the script rather than the point of the call.
|
632
|
+
#
|
633
|
+
# WARNING: This implementation should be considered experimental. It is
|
634
|
+
# not recommended for production use.
|
595
635
|
#
|
596
636
|
def fork
|
597
637
|
last_arg = ARGV.last
|
@@ -640,6 +680,7 @@ module Process
|
|
640
680
|
end
|
641
681
|
|
642
682
|
module_function :kill, :wait, :wait2, :waitpid, :waitpid2, :create, :fork
|
683
|
+
module_function :ppid
|
643
684
|
end
|
644
685
|
|
645
686
|
# For backwards compatibility. Deprecated.
|
data/test/tc_process.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
###############################################################################
|
2
2
|
# tc_process.rb
|
3
3
|
#
|
4
|
-
# Test suite for the win32-process
|
4
|
+
# Test suite for the win32-process library. This test suite will start
|
5
5
|
# at least two instances of Notepad on your system, which will then
|
6
6
|
# be killed. Requires the sys-proctable package.
|
7
7
|
#
|
8
8
|
# I haven't added a lot of test cases for fork/wait because it's difficult
|
9
|
-
# to run such tests without causing havoc with
|
9
|
+
# to run such tests without causing havoc with Test::Unit itself. Ideas
|
10
10
|
# welcome.
|
11
11
|
#
|
12
12
|
# You should run this test case via the 'rake test' task.
|
@@ -18,9 +18,12 @@ begin
|
|
18
18
|
require 'sys/proctable'
|
19
19
|
rescue LoadError => e
|
20
20
|
site = 'http://www.rubyforge.org/projects/sysutils'
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
msg = %Q{
|
22
|
+
Stopping! The sys-proctable library is required to run this test suite.
|
23
|
+
You can find it at #{site} or the RAA.
|
24
|
+
Or, you can just 'gem install sys-proctable' and try again.
|
25
|
+
}
|
26
|
+
STDERR.puts msg
|
24
27
|
exit!
|
25
28
|
end
|
26
29
|
|
@@ -43,7 +46,7 @@ class TC_Win32Process < Test::Unit::TestCase
|
|
43
46
|
end
|
44
47
|
|
45
48
|
def test_version
|
46
|
-
assert_equal('0.5.
|
49
|
+
assert_equal('0.5.9', Process::WIN32_PROCESS_VERSION)
|
47
50
|
end
|
48
51
|
|
49
52
|
def test_kill
|
@@ -112,6 +115,12 @@ class TC_Win32Process < Test::Unit::TestCase
|
|
112
115
|
def test_waitpid2
|
113
116
|
assert_respond_to(Process, :waitpid2)
|
114
117
|
end
|
118
|
+
|
119
|
+
def test_ppid
|
120
|
+
assert_respond_to(Process, :ppid)
|
121
|
+
assert_equal(true, Process.ppid > 0)
|
122
|
+
assert_equal(false, Process.pid == Process.ppid)
|
123
|
+
end
|
115
124
|
|
116
125
|
def test_creation_constants
|
117
126
|
assert_not_nil(Process::CREATE_DEFAULT_ERROR_MODE)
|
data/win32-process.gemspec
CHANGED
@@ -3,7 +3,7 @@ require "rubygems"
|
|
3
3
|
spec = Gem::Specification.new do |gem|
|
4
4
|
desc = "Adds create, fork, wait, wait2, waitpid, and a special kill method"
|
5
5
|
gem.name = "win32-process"
|
6
|
-
gem.version = "0.5.
|
6
|
+
gem.version = "0.5.9"
|
7
7
|
gem.authors = ['Daniel Berger', 'Park Heesob']
|
8
8
|
gem.email = "djberg96@gmail.com"
|
9
9
|
gem.rubyforge_project = 'win32utils'
|
@@ -17,7 +17,7 @@ spec = Gem::Specification.new do |gem|
|
|
17
17
|
gem.files.reject! { |fn| fn.include? "CVS" }
|
18
18
|
gem.require_path = "lib"
|
19
19
|
gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
|
20
|
-
gem.add_dependency("windows-pr", ">= 0.8.
|
20
|
+
gem.add_dependency("windows-pr", ">= 0.8.6")
|
21
21
|
end
|
22
22
|
|
23
23
|
if $0 == __FILE__
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-process
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Berger
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2008-
|
13
|
+
date: 2008-06-14 00:00:00 -06:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.8.
|
23
|
+
version: 0.8.6
|
24
24
|
version:
|
25
25
|
description: Adds create, fork, wait, wait2, waitpid, and a special kill method
|
26
26
|
email: djberg96@gmail.com
|