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