process_starter 1.0.0
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/lib/process_starter.rb +90 -0
- metadata +67 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# 2012 (c) LineAct / www.lineact.com
|
|
2
|
+
|
|
3
|
+
module ProcessStarter
|
|
4
|
+
begin require 'posix/spawn' rescue LoadError; end
|
|
5
|
+
|
|
6
|
+
WINRUN = (RUBY_PLATFORM =~ /mswin|mingw/) ? true : false # run in windows?
|
|
7
|
+
HAVE_SPAWN = defined?(spawn) # have Ruby 1.9 spawn method
|
|
8
|
+
HAVE_POSIX_SPAWN = defined?(POSIX::Spawn::spawn) # loaded posix/spawn lib
|
|
9
|
+
|
|
10
|
+
def log(m)
|
|
11
|
+
defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER.info(m) : puts m
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Starts the process
|
|
15
|
+
# not waiting for it's finish, so child process run in parralel
|
|
16
|
+
# not inheritting file descriptors, so it finds and closes all opened handels
|
|
17
|
+
# works in windows and linux
|
|
18
|
+
def self.start(s)
|
|
19
|
+
log.info "**************** INVOKING EXTERNAL COMMAND #{s}, WINRUN IS #{WINRUN}, HAVE_POSIX_SPAWN IS #{HAVE_POSIX_SPAWN}, HAVE_SPAWN is #{HAVE_SPAWN}"
|
|
20
|
+
if WINRUN
|
|
21
|
+
if system("psexec -d #{s}")
|
|
22
|
+
log.info "Executed using PSEXEC"
|
|
23
|
+
elsif system("start cmd /c #{s}")
|
|
24
|
+
log.info "Executed using START cmd /c (inherits descriptors (?) - bad)"
|
|
25
|
+
else
|
|
26
|
+
log.info "Execute failed!"
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
log.info "Executing in Linux style"
|
|
30
|
+
if HAVE_POSIX_SPAWN
|
|
31
|
+
close_them = Hash[ close_io().map {|x| [x, :close]} ]
|
|
32
|
+
log.info "POSIX::Spawn::spawn with close descriptors: #{close_them.inspect}"
|
|
33
|
+
pid = POSIX::Spawn::spawn( s, close_them)
|
|
34
|
+
elsif HAVE_SPAWN
|
|
35
|
+
# we hope on http://www.ruby-doc.org/core-1.9.3/Process.html#method-c-spawn
|
|
36
|
+
# [close_others => true] option
|
|
37
|
+
# TODO: check it
|
|
38
|
+
log.info "Ruby 1.9 spawn"
|
|
39
|
+
spawn( s )
|
|
40
|
+
else
|
|
41
|
+
log.info "fork{ close_io; exec }"
|
|
42
|
+
Process.detach fork{
|
|
43
|
+
close_io(true)
|
|
44
|
+
exec(s)
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# based on close_io from: http://daemons.rubyforge.org/Daemonize.html
|
|
52
|
+
def self.close_io( do_close=false )
|
|
53
|
+
close_them = []
|
|
54
|
+
# Make sure all input/output streams are closed
|
|
55
|
+
# Part I: close all IO objects (except for STDIN/STDOUT/STDERR)
|
|
56
|
+
ObjectSpace.each_object(IO) do |io|
|
|
57
|
+
unless [STDIN, STDOUT, STDERR].include?(io)
|
|
58
|
+
begin
|
|
59
|
+
# puts "os #{io.to_i}, and="
|
|
60
|
+
# puts io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
|
|
61
|
+
if (not io.closed?) and (io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC) == 0
|
|
62
|
+
close_them << io.to_i
|
|
63
|
+
io.close if do_close
|
|
64
|
+
end
|
|
65
|
+
rescue ::Exception
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
# puts close_them.inspect
|
|
70
|
+
|
|
71
|
+
# Make sure all input/output streams are closed
|
|
72
|
+
# Part II: close all file decriptors (except for STDIN/STDOUT/STDERR)
|
|
73
|
+
ios = Array.new(8192) {|i| IO.for_fd(i) rescue nil}.compact
|
|
74
|
+
ios.each do |io|
|
|
75
|
+
# puts "qqq"
|
|
76
|
+
# puts io.to_i
|
|
77
|
+
next if io.fileno < 3
|
|
78
|
+
# puts "checking flag"
|
|
79
|
+
# puts io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
|
|
80
|
+
next if (io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC != 0)
|
|
81
|
+
# puts "adding"
|
|
82
|
+
close_them << io.to_i
|
|
83
|
+
io.close if do_close
|
|
84
|
+
end
|
|
85
|
+
# puts close_them.inspect
|
|
86
|
+
|
|
87
|
+
close_them.uniq
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: process_starter
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 23
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
- 0
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Pavel Vasev
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2012-09-21 00:00:00 +06:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies: []
|
|
21
|
+
|
|
22
|
+
description: A gem to start process in parallel plus dont inherit handles plus both in windows/linux plus learn me to make gems
|
|
23
|
+
email: pavel.vasev@gmail.com
|
|
24
|
+
executables: []
|
|
25
|
+
|
|
26
|
+
extensions: []
|
|
27
|
+
|
|
28
|
+
extra_rdoc_files: []
|
|
29
|
+
|
|
30
|
+
files:
|
|
31
|
+
- lib/process_starter.rb
|
|
32
|
+
has_rdoc: true
|
|
33
|
+
homepage: http://rubygems.org/gems/process_starter
|
|
34
|
+
licenses: []
|
|
35
|
+
|
|
36
|
+
post_install_message:
|
|
37
|
+
rdoc_options: []
|
|
38
|
+
|
|
39
|
+
require_paths:
|
|
40
|
+
- lib
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
hash: 3
|
|
47
|
+
segments:
|
|
48
|
+
- 0
|
|
49
|
+
version: "0"
|
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
hash: 3
|
|
56
|
+
segments:
|
|
57
|
+
- 0
|
|
58
|
+
version: "0"
|
|
59
|
+
requirements: []
|
|
60
|
+
|
|
61
|
+
rubyforge_project:
|
|
62
|
+
rubygems_version: 1.5.2
|
|
63
|
+
signing_key:
|
|
64
|
+
specification_version: 3
|
|
65
|
+
summary: Hola!
|
|
66
|
+
test_files: []
|
|
67
|
+
|