----extPart_ST_10_14_03_Tuesday_November_02_2004_23267
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi Brian,

Firstly, thanks for the help.

> I don't think you said anything about the platform you are running under.
> When I run your test under ruby 1.8.2p2 and FreeBSD 4.10, I get:
> 
> $ ruby command_runner_shell_test.rb 
> Hello, world! 2 times!
> $ 
>
> which looks pretty good to me too.

You actually need to run the test script with a shell redirection. Like
in the example output I gave, I redirected output of the script to a
file, output.txt, and then cat'ed it:

    $ ruby command_runner_shell_test.rb > output.txt
    $ cat output.txt
    Hello, world! 2 times!
    Hello, world! 2 times!
    Hello, world! 2 times!

Hopefully that will reproduce the same results I am seeing? Otherwise if
this problem just happens on mine... well that is just going to make it
even more difficult for me to track. :(

> If you are running under cygwin plus some Microsoft operating system

I am running this on Debian Linux 3.1, the testing branch of the
distribution. Ruby v1.8.2. Maybe the Debian package maintainers applied
some patches, but I doubt that would be the cause... but maybe.

> Seriously, Windows is badly broken with regard to processes and pipes.

I would agree there. I once had to write a sh-like shell that compiled
and ran on both Windows and Linux, for a uni project. :) I never
finished the windows part by the deadline (I did start a bit last minute
though)...

> Why is this a problem? You can call waitpid on the child pid, and if it has
> already terminated, then it will still be in the process table (as a zombie)
> waiting for you to reap its exit status. That's unless someone has messed
> with SIGCHLD.

That is just the handy little fact I needed. Now I guess I can remove
all that part of the code and be confident it works.  Thanks!

> And even if the process had gone completely, you'd just get an error from
> waitpid saying that the child did not exist (which is fine, since you know
> it did exist at the time you forked, so it must have died since then). Only
> if another process on the system had forked and re-used the same PID in the
> mean time would that be a problem.

Which was the (unlikely) problem I was trying to protect myself from. I
know it won't happen... but the fact that it "technically" could made me
uncomfortable. :P

I've attached the 'updated' command_runner with the threading stuff
removed. Hopefully with that cruft gone, it is easier to read.

Steven
-- 
NAUTRONIX LTD
Marine Technology Solutions

Steven Wong
Undergraduate Software Engineer

Nautronix Ltd ABN 28 009 019 603
108 Marine Terrace, Fremantle, WA 6160, Australia
T +61 (0)8 9431 0000, F +61 (0)8 9430 5901, http://www.nautronix.com

E steven.wong / nautronix.com.au
T +61 (0)8 9431 0024
M +61 (0)413 332 005

--
This email is confidential and intended solely for the use of the individual to whom it is addressed.  
Any views or opinions presented are solely those of the author and do not necessarily represent those of NAUTRONIX LTD.

If you are not the intended recipient, you have received this email in error and use, dissemination, forwarding, printing, or copying of this email is strictly prohibited.  If you have received this email in error please contact the sender.   

Although our computer systems use active virus protection software, and we take various measures to reduce the risk of viruses being transmitted in e-mail messages and attachments sent from this company, we cannot guarantee that such e-mail messages and attachments are free from viruses on receipt.  It is a condition of our using e-mail to correspond with you, that any and all liability on our part arising directly or indirectly out of any virus is excluded.  Please ensure that you run virus checking software on all e-mail messages and attachments before reading them.
----extPart_ST_10_14_03_Tuesday_November_02_2004_23267
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="command_runner.rb"

class CommandRunner
    attr :command
    attr :childPid

    def initialize(*command)
        @command        ommand
        @childPid       il
        
        @readPipe       il
        @readErrorPipe  il
        @writePipe      il
    end

    def closeWrite
        @writePipe.close
    end

    def kill
        Process.kill("KILL", @childPid)
    end

    def read
        return @readPipe.read
    end

    def readError
        return @readErrorPipe.read
    end

    def run
        parent_to_child_read, parent_to_child_write              O.pipe
        child_to_parent_read, child_to_parent_write              O.pipe
        child_to_parent_error_read, child_to_parent_error_write  O.pipe
        
        @childPid  ork do
            parent_to_child_write.close
            child_to_parent_read.close
            child_to_parent_error_read.close
            
            $stdin.reopen(parent_to_child_read) or
                    raise "Unable to redirect STDIN"
            $stdout.reopen(child_to_parent_write) or
                    raise "Unable to redirect STDOUT"
            $stderr.reopen(child_to_parent_error_write) or
                    raise "Unable to redirect STDERR"

            exec(*@command)
        end

        child_to_parent_write.close
        child_to_parent_error_write.close
        parent_to_child_read.close

        @readPipe       hild_to_parent_read
        @readErrorPipe  hild_to_parent_error_read
        @writePipe      arent_to_child_write
    end

    #--------------------------------------------------------------------------
    # Description: Waits for command to exit
    # Returns    : The return code of the program when it exited
    #--------------------------------------------------------------------------
    def wait
        if not @childPid
            raise "Waiting for a process that has not started"
        end

        return_value  rocess.waitpid2(@childPid)[1].exitstatus
        
        @childPid  il

        return return_value
    end

    def write(string)
        @writePipe.write(string)
    end
end

----extPart_ST_10_14_03_Tuesday_November_02_2004_23267--