On Sat, 10 May 2003 08:45:26 +0900, Brian Candler wrote:

> I had a bit of a think about this, and setting Ruby aside for the moment,
> why not consider the following question similar to your original one:
> 
>   If I write a subroutine (function) in C++, how can I wrap it so that
>   any output it generates does not go to stdout, but is discarded or
>   captured in a string?
> 
> Now, I'm not a C++ programmer, but I imagine the answer goes something along
> the lines of: "change cout to point to a new object, so that cout << "foo"
> writes to this object rather than what cout normally points to". Or you
> could close fd 1 and fd 2 and reopen them pointing to /tmp/result or
> /dev/null.

Good parallel..  im terrible in explaining such things.

 
> This is all fine so far. However there are a number of ways in which the
> subroutine could bypass this restriction if it chose to:
> 
>   (1) it explicitly opens /dev/stdout to a new fd, and writes to it
>   (2) it explicitly write()s to fd 1
>   (3) it forks and execs a child, and the child writes to stdout
>   (4) probably a load of other things
> 
> (2) and (3) won't be an issue if you had reopened fd 1, because they will
> write to whatever you reopened it as (say /tmp/result, which you can read
> later)

Yes this is not a safe jail. If people really want to clutter up their
console then let them.  A ruby-jail is left as an exercise for 
the reader :-)
I am aware of this insecureness, but I have not written anything about
this in the tutorial.... yet 


[snip preparation for argumentation] 
> 
> Hence I do not believe that it is necessary or even desirable to try to set
> up some sort of 'sand box' execution environment for the Ruby interpreter,
> when it is *part of your program*. In fact it could be a positive
> disadvantage, because I for one would definitely want the ability for my
> Ruby code to report debug messages to stderr, in the same way as my C(++)
> code can. I cannot see any real-world application where such a sandbox is
> needed, because it probably just means that the logic is being done in the
> wrong place: if the Ruby part of your program needs to redirect any output
> it generates, or capture output of a child, then just do it in Ruby.

Some might need such sandbox, other don't. 
I need it myself therefore I investigate it.

BTW:  pipe is a unix thing.. How do I make a ruby-sandbox on windows?
I don't own a windows box myself. What issues should I be aware of ???

 
> One final point: you posted some code showing native threads communicating
> over a pipe. I think it's a very bad idea to encourage use of threads in
> embedded Ruby applications, because Ruby really does not play well with
> them. If you made sure that *all* Ruby calls occured in *one* thread it
> would probably work, but a safer rule (especially for a tutorial) is: just

Yes I know ruby is not thread-safe and that things is running within the
main-thread. It does fork childprocesses. 
Yes ruby-specific things happens within one thread, so that I can avoid
raceconditions.

> don't do it. You'll see recent postings to this list of people who have
> tried it, with good reason to do so, and have achieved little more than some
> spectacular crashes.

Yes.. I have tried crashing with ruby in a single thread, very hard debuggable! 
I have not-yet tried crashing with a huge multithreaded-ruby application.
I don't know if I fear it or love it ?
 
 
> So, if I needed to call some Ruby from C++ and have it as a totally separate
> entity which I communicated with down a pipe, then I would fork a new
> process. However this loses much of the benefit of embedding because the
> _only_ way you could communicate with it would be down the pipe... no direct
> method calls or rb_eval_string or whatever.

Pedantic seperation.  Every day everyone is linking with a dosin
3rd party libraries without being worried.  I think ruby is safer than
most 3rd party libraries around, but I have no evidence of this... yet

--
Simon Strandgaard