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 CHANGED
@@ -1,3 +1,6 @@
1
+ = 0.5.9 - 14-Jun-2008
2
+ * Added a proper implementation of Process.ppid.
3
+
1
4
  = 0.5.8 - 24-Mar-2008
2
5
  * Fixed a bug in Process.create where the handles in the PROCESS_INFORMATION
3
6
  struct were not closed, regardless of the 'close_handles' option. Thanks
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. In addition, it provides a different implementation of the
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.7.4 or later.
9
- The 'sys-proctable' library, 0.7.0 or later (test suite only).
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. We will try to address this in a future release, if possible.
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. If that succeeds, we know the process is running.
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. These will not kill
57
- GUI processes. It will not (currently) send a signal to remote
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. The ExitProcess() function is then sent to that
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. This
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.8'
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 package. This test suite will start
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 TestUnit itself. Ideas
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
- STDERR.puts "Stopping!"
22
- STDERR.puts "The sys/proctable module is required to run this test suite."
23
- STDERR.puts "You can find it at #{site} or the RAA"
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.8', Process::WIN32_PROCESS_VERSION)
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)
@@ -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.8"
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.1")
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.8
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-04-24 00:00:00 -06:00
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.1
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