Fork on Windows

R

Robert James

What's the best way to see if a particular platform supports fork? I
know I could check if it's running on Windows, but I'd like something
more direct (and presumably accurate).

A similar question: assuming a standard Ruby install (that is, no
popen4), what's the most robust way of running a shell command and
capturing STDOUT and STDERR?
`command 2>&1` seems to not always work on Windows.
 
M

Michael P. Soulier

What's the best way to see if a particular platform supports fork? I
know I could check if it's running on Windows, but I'd like something
more direct (and presumably accurate).

You could test fork and see if you get a defined value back.
A similar question: assuming a standard Ruby install (that is, no
popen4), what's the most robust way of running a shell command and
capturing STDOUT and STDERR?
`command 2>&1` seems to not always work on Windows.

And it won't. That's bourne-shell syntax.

http://www.ruby-doc.org/stdlib/libdoc/open3/rdoc/index.html

Mike
 
R

Robert James

Michael said:
You could test fork and see if you get a defined value back.

Not sure how to do this... Kernel.respond_to? :fork is true on both
platforms.
 
U

Uma Geller

Not sure how to do this... Kernel.respond_to? :fork is true on both
platforms.

can you execute fork in windows and catch the exception if it fails ?
 
R

Robert James

Uma said:
can you execute fork in windows and catch the exception if it fails ?

Nope - fork is used deep inside a lib. I'd like to exit right away if
the platform doesn't support it, otherwise let the lib run as normal.
 
M

M. Edward (Ed) Borasky

Uma said:
can you execute fork in windows and catch the exception if it fails ?
Is this like "stick a fork in it and see if it's done?"

<ducking>
 
U

Uma Geller

Nope - fork is used deep inside a lib. I'd like to exit right away if
the platform doesn't support it, otherwise let the lib run as normal.

then do this exception test during the installation process
 
A

ara.t.howard

What's the best way to see if a particular platform supports fork? I
know I could check if it's running on Windows, but I'd like something
more direct (and presumably accurate).

has_fork =
begin
fork{ exit }
Process.wait
true
rescue
false
end
A similar question: assuming a standard Ruby install (that is, no
popen4), what's the most robust way of running a shell command and
capturing STDOUT and STDERR?
`command 2>&1` seems to not always work on Windows.

NAME

systemu.rb

SYNOPSIS

univeral capture of stdout and stderr and handling of child process pid for windows, *nix, etc.

URIS

http://rubyforge.org/projects/codeforpeople/
http://codeforpeople.com/lib/ruby/

INSTALL

gem install systemu

SAMPLES

<========< samples/a.rb >========>

~ > cat samples/a.rb

#
# systemu can be used on any platform to return status, stdout, and stderr of
# any command. unlike other methods like open3/popen4 there is zero danger of
# full pipes or threading issues hanging your process or subprocess.
#
require 'systemu'

date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )

status, stdout, stderr = systemu date
p [ status, stdout, stderr ]

~ > ruby samples/a.rb

[#<Process::Status: pid=9960,exited(0)>, "Fri Nov 03 17:22:23 MST 2006\n", "Fri Nov 03 17:22:23 MST 2006\n"]


<========< samples/b.rb >========>

~ > cat samples/b.rb

#
# quite a few keys can be passed to the command to alter it's behaviour. if
# either stdout or stderr is supplied those objects should respond_to? '<<'
# and only status will be returned
#
require 'systemu'

date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )

stdout, stderr = '', ''
status = systemu date, 'stdout' => stdout, 'stderr' => stderr
p [ status, stdout, stderr ]

~ > ruby samples/b.rb

[#<Process::Status: pid=9965,exited(0)>, "Fri Nov 03 17:22:23 MST 2006\n", "Fri Nov 03 17:22:23 MST 2006\n"]


<========< samples/c.rb >========>

~ > cat samples/c.rb

#
# of course stdin can be supplied too. synonyms for 'stdin' include '0' and
# 0. the other stdio streams have similar shortcuts
#
require 'systemu'

cat = %q( ruby -e" ARGF.each{|line| puts line} " )

status = systemu cat, 0=>'the stdin for cat', 1=>stdout=''
puts stdout

~ > ruby samples/c.rb

the stdin for cat


<========< samples/d.rb >========>

~ > cat samples/d.rb

#
# the cwd can be supplied
#
require 'systemu'
require 'tmpdir'

pwd = %q( ruby -e" STDERR.puts Dir.pwd " )

status = systemu pwd, 2=>(stderr=''), :cwd=>Dir.tmpdir
puts stderr


~ > ruby samples/d.rb

/tmp


<========< samples/e.rb >========>

~ > cat samples/e.rb

#
# any environment vars specified are merged into the child's environment
#
require 'systemu'

env = %q( ruby -r yaml -e" puts ENV[ 'answer' ] " )

status = systemu env, 1=>stdout='', 'env'=>{ 'answer' => 0b101010 }
puts stdout

~ > ruby samples/e.rb

42


<========< samples/f.rb >========>

~ > cat samples/f.rb

#
# if a block is specified then it is passed the child pid and run in a
# background thread. note that this thread will __not__ be blocked during the
# execution of the command so it may do useful work such as killing the child
# if execution time passes a certain threshold
#
require 'systemu'

looper = %q( ruby -e" loop{ STDERR.puts Time.now.to_i; sleep 1 } " )

status, stdout, stderr =
systemu looper do |cid|
sleep 3
Process.kill 9, cid
end

p [ status, stdout, stderr ]


~ > ruby samples/f.rb

[#<Process::Status: pid=9985,signaled(SIGKILL=9)>, "", "1162599744\n1162599745\n1162599746\n1162599747\n"]



-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,197
Messages
2,571,038
Members
47,633
Latest member
BriannaLyk

Latest Threads

Top