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

--
Steve Litt
http://www.troubleshooters.com
slitt@troubleshooters.com

I believe you are looking for Process.setsid.

   ri Process.setsid

James Edward Gray II

···

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

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

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 12:09 am, James Edward Gray II wrote:

On Dec 17, 2005, at 10:56 PM, Steve Litt 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 Gray II

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 Litt
http://www.troubleshooters.com
slitt@troubleshooters.com

···

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

On Sunday 18 December 2005 12:09 am, James Edward Gray II wrote:
> On Dec 17, 2005, at 10:56 PM, Steve Litt 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 Gray 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.

Steve Litt 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 Litt

slitt@troubleshooters.com

···

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

Steve Litt 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

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:

···

On Sunday 18 December 2005 13:43, Steve Litt wrote:

On Sunday 18 December 2005 04:46 am, Florian Frank wrote:
> Steve Litt 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:

##########################################################
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

I've seen it also called the 'splat' operator, and (I think?) David Black called it the 'unary unarray' operator, which I a good name for it. It doesn't just work with method arguments, and it doesn't just work with arrays:

  p = *File.open('/etc/passwd')

gives an array of all the lines in the file. I was most impressed when I found that out recently :wink:

(p.s. I'm not advocating that method of reading files _at all_ - it's just an example)

···

On Sun, 18 Dec 2005 12:58:09 -0000, Stefan Lang <langstefan@gmx.at> wrote:

On Sunday 18 December 2005 13:43, Steve Litt wrote:

On Sunday 18 December 2005 04:46 am, Florian Frank wrote:
> Steve Litt 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:

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.

--
Ross Bamford - rosco@roscopeco.remove.co.uk

> Steve Litt 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:

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.

I've seen it also called the 'splat' operator, and (I think?) David Black called it the 'unary unarray' operator, which I a good name for it. It doesn't just work with method arguments, and it doesn't just work with arrays:

  p = *File.open('/etc/passwd')

gives an array of all the lines in the file. I was most impressed when I found that out recently :wink:

(p.s. I'm not advocating that method of reading files _at all_ - it's just an example)

--
Ross Bamford - rosco@roscopeco.remove.co.uk

This scared me, so I did some experiments
logan:/Users/logan% irb
irb(main):001:0> lines = *File.open('test.yml')
=> ["---\n", "words:\n", " - yes\n", " - put\n", " - it\n", " - on\n", " - the\n", " - off\n", " - setting\n"]
irb(main):002:0> h = { :a=>:b, :c=>:d }
=> {:a=>:b, :c=>:d}
irb(main):003:0> keysvals = *h
=> [[:a, :b], [:c, :d]]
irb(main):004:0> class Q
irb(main):005:1> def to_a
irb(main):006:2> "Hello!"
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> q = Q.new
=> #<Q:0xc13e4>
irb(main):010:0> qarray = *q
TypeError: `to_a' did not return Array
         from (irb):10
irb(main):011:0>

Apparently splat will splat almost anything as long as its to_a method returns an array (a reasonable assumption). I don't know if I really like this. I always kind of thought of splat as syntax (like &), not really as a method (operator). Apparently its not the unary unarray operator, its the unary to array then unarray operator.

···

On Dec 18, 2005, at 8:38 AM, Ross Bamford wrote:

On Sun, 18 Dec 2005 12:58:09 -0000, Stefan Lang <langstefan@gmx.at> > wrote:

On Sunday 18 December 2005 13:43, Steve Litt wrote:

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

         from :0

& works on anything with a to_proc(). See:

http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc

James Edward Gray II

···

On Dec 19, 2005, at 9:02 AM, Logan Capaldo wrote:

Apparently splat will splat almost anything as long as its to_a method returns an array (a reasonable assumption). I don't know if I really like this. I always kind of thought of splat as syntax (like &), not really as a method (operator).

Ok. I was unaware of that. But to_proc is more like to_ary than to_a, IMO. (Not that I've ever seen a to_p :wink: ). I could maybe go for splat working on anything that responded to to_ary, but currently it just personally feels kinda icky.

···

On Dec 19, 2005, at 10:15 AM, James Edward Gray II wrote:

On Dec 19, 2005, at 9:02 AM, Logan Capaldo wrote:

Apparently splat will splat almost anything as long as its to_a method returns an array (a reasonable assumption). I don't know if I really like this. I always kind of thought of splat as syntax (like &), not really as a method (operator).

& works on anything with a to_proc(). See:

http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc

James Edward Gray II

Apparently splat will splat almost anything as long as its to_a method returns an array (a reasonable assumption). I don't know if I really like this. I always kind of thought of splat as syntax (like &), not really as a method (operator).

& works on anything with a to_proc(). See:

http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc

James Edward Gray II

Ok. I was unaware of that. But to_proc is more like to_ary than to_a, IMO. (Not that I've ever seen a to_p :wink: ). I could maybe go for splat working on anything that responded to to_ary, but currently it just personally feels kinda icky.

Wish granted. :wink:

>> class ToAry
>> undef to_a
>> def to_ary
>> [1, 2, 3]
>> end
>> end
=> nil
>> arr = ToAry.new
=> #<ToAry:0x31fa18>
>> arr.respond_to? :to_a
=> false
>> def show( one, two, three )
>> p one
>> p two
>> p three
>> end
=> nil
>> show(*arr)
1
2
3
=> nil

to_ary() is favored. Otherwise, to_a() is used.

James Edward Gray II

···

On Dec 19, 2005, at 9:25 AM, Logan Capaldo wrote:

On Dec 19, 2005, at 10:15 AM, James Edward Gray II wrote:

On Dec 19, 2005, at 9:02 AM, Logan Capaldo wrote:

Well my real wish was that the otherwise didn't exist but I takes whats I can gets I suppose. If it really bothers me I'll just switch to Java or Python. Those languages match my exact ideals of how splat and & should work. (kidding)

···

On Dec 19, 2005, at 10:35 AM, James Edward Gray II wrote:

On Dec 19, 2005, at 9:25 AM, Logan Capaldo wrote:

On Dec 19, 2005, at 10:15 AM, James Edward Gray II wrote:

On Dec 19, 2005, at 9:02 AM, Logan Capaldo wrote:

Apparently splat will splat almost anything as long as its to_a method returns an array (a reasonable assumption). I don't know if I really like this. I always kind of thought of splat as syntax (like &), not really as a method (operator).

& works on anything with a to_proc(). See:

http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc

James Edward Gray II

Ok. I was unaware of that. But to_proc is more like to_ary than to_a, IMO. (Not that I've ever seen a to_p :wink: ). I could maybe go for splat working on anything that responded to to_ary, but currently it just personally feels kinda icky.

Wish granted. :wink:

[snip example code]

to_ary() is favored. Otherwise, to_a() is used.

James Edward Gray II