Spawning

Hi all,

My umenu program has a utility called ufork.pl, whose job it is to
run an X program in the background in such a way that even if the
process that ran it is killed, the X program continues to live. I
want to translate it to Ruby, but I can’t find an equivalent to
Perl’s setsid anywhere in the Kernel module. Here’s the code:

#!/usr/bin/perl -w
use strict;

use POSIX qw(setsid);

sub launch(@) {
my(@args) = @_;
unless (fork) {
setsid; # set child process to new session
unless (fork) { # Create a grandchild
close STDIN; # close std files
close STDOUT;
close STDERR;
exec @args; # exec the x program
}
}
sleep(1);
}

launch(@ARGV);

=======================

Anyone know an equivalent to setsid? Anyone ever do this in Ruby
before? I think it’s a fairly common riff.

Thanks

SteveT

On Dec 17, 2005, at 10:56 PM, Steve L. wrote:

I want to translate it to Ruby, but I can’t find an equivalent to
Perl’s setsid anywhere in the Kernel module.

I believe you are looking for Process.setsid.

ri Process.setsid

James Edward G. II

On Sunday 18 December 2005 12:36 am, Steve L. wrote:

Thanks James.

That works! I can run it from a terminal, close the terminal, and
the spawned program containues running. This is the exact
behavior I need. However…

I have one other problem. Somehow I cannot use exec on my array
of arguments – only on the very first one (the program name).
This means I can’t pass arguments to the spawned program.

I got it to work with a kludge:

exec argarray.join(’ ')

I converted the array of arguments to a string, and it worked. But
it should have worked the other way too. What am I missing?

SteveT

Steve L.

[email protected]

Steve L. wrote:

I converted the array of arguments to a string, and it worked. But
it should have worked the other way too. What am I missing?

exec *argarray

On Sunday 18 December 2005 12:09 am, James Edward G. II wrote:

On Dec 17, 2005, at 10:56 PM, Steve L. wrote:

I want to translate it to Ruby, but I can’t find an equivalent
to Perl’s setsid anywhere in the Kernel module.

I believe you are looking for Process.setsid.

ri Process.setsid

James Edward G. II

Thanks James.

That works! I can run it from a terminal, close the terminal, and
the spawned program containues running. This is the exact behavior
I need. However…

I have one other problem. Somehow I cannot use exec on my array of
arguments – only on the very first one (the program name). This
means I can’t pass arguments to the spawned program.

See here:

#!/usr/bin/ruby -w

def launch(argarray)
unless (fork)
Process::setsid # set child process to new session
unless (fork) # Create a grandchild
STDIN.close # close std files
STDOUT.close
STDERR.close
#exec argarray ## This doesn’t run the program
command = argarray.shift
exec command
# exec command, argarray ## Doesn’t run pgm
# exec command, argarray[0], argarray[1] ## no run pgm
end
end
sleep(1)
end # launch()

launch(ARGV)

On Sunday 18 December 2005 13:43, Steve L. wrote:

one argument.

Curious – what does the asterisk do to make it work when it didn’t
work without the asterisk. What does the asterisk do? I know it
doesn’t mean “the contents of this address” – that’s another
language :slight_smile:

It flattens the array (argarray) into an argument list.
This means the first element of argarray becomes the first
argument to exec, the second element of argarray becomes
the second argument to exec and so on.

The following irb session demonstrates this:
##########################################################
irb(main):001:0> def m(arg1 = nil, arg2 = nil, arg3 = nil)
irb(main):002:1> p arg1
irb(main):003:1> p arg2
irb(main):004:1> p arg3
irb(main):005:1> end
=> nil
irb(main):006:0> m
nil
nil
nil
=> nil
irb(main):007:0> m(1, 2, 3)
1
2
3
=> nil
irb(main):008:0> ary = [1, 2, 3]
=> [1, 2, 3]
irb(main):010:0> m(ary)
[1, 2, 3]
nil
nil
=> nil
irb(main):011:0> m(*ary)
1
2
3
=> nil
irb(main):012:0> ary = [1, 2]
=> [1, 2]
irb(main):013:0> m(ary)
[1, 2]
nil
nil
=> nil
irb(main):014:0> m(*ary)
1
2
nil
=> nil

Regards,
Stefan

On Sunday 18 December 2005 04:46 am, Florian F. wrote:

Steve L. wrote:

I converted the array of arguments to a string, and it worked.
But it should have worked the other way too. What am I missing?

exec *argarray

Confirmed! Thanks Florian.

Now I can run a command with several words quoted together to make
one argument.

Curious – what does the asterisk do to make it work when it didn’t
work without the asterisk. What does the asterisk do? I know it
doesn’t mean “the contents of this address” – that’s another
language :slight_smile:

SteveT

Steve L.

[email protected]