From: David Masover Date: 2010-08-04T10:55:19+09:00 Subject: Re: Standard IO streams in Ruby On Tuesday, August 03, 2010 07:56:48 am Jatin Kumar wrote: > > From some of your questions, it seems like you're going to let the user > > enter > > source code, then compile it and run it. Is that true? If so, do you > > realize > > how insanely dangerous that is? > > Yes, I am exactly doing that. Why does it sound to you insanely > dangerous?? > Could you elaborate a little on that.? Because any user could compile and run this: #include int main() { execlp("rm", "rm", "-rf", "/", NULL); } The user might have limited privileges, but they'd certainly be able to wipe out any file they have access to, on any filesystem that's mounted. Unless you've thought through your sandboxing quite a bit, this is a Bad Idea. And if you are trying to sandbox it, you'd better keep up to speed on local vulnerabilities of all kinds. Even if you do all that, you still need to make sure you block it from making network connections, or you could become an open spam relay, among other things. Now, if you know what you're doing, all of the above should be obvious to you. If so, I apologize -- you may have a perfectly legitimate reason for doing this, and you may have already taken the necessary precautions. > > But that doesn't solve your problem by itself -- you need to send data > > to and > > from the browser interactively. That means you at least need AJAX, and > > possibly Comet or Web Sockets, combined with some sort of background > > processing. > > Yes, I am using AJAX. I will look into Comet or Web Sockets, but I have > no idea of a web socket and how do they work? How can I use them in > here? So, AJAX is just a way for the browser to initiate a conversation with the server. Rails is designed to be stateless, just like the Web -- that means, as soon as you render a response for the client, you're done, it's as if your program has ended and is ready to start again for the next response. You can run programs in the background, and there are many ways to do this. Then your program would be running in the background, but there'd be no communication between it and the user interface. You could have the browser periodically check back via AJAX -- this is called "polling" -- but then, you have a problem. If you poll too fast, you generate a lot of unnecessary network traffic. If you poll too slowly, it takes too long for a response to come back. Comet is a neat hack to turn AJAX into the opposite -- a "push" mechanism. It uses "long polling", which you can read about elsewhere, but the net result is that as soon as the server has data ready (so, as soon as your program sends more text to STDOUT), that data is sent to the client. Web sockets are a new technology to build the idea of a two-way communication into the browser -- so that either the server or the client can immediately tell the other when there's some new information. In other words, Comet is basically a really hackish way of emulating what WebSockets will do properly. To simplify things, you may want to start with polling (it's easier to do), but the pieces are still roughly the same -- you still need to run the program in the background and capture the output, only now, you just need to store it somewhere your Rails controller can get to. > >> I tried doing this : > >> > >> @output = `g++ j.cpp -o "prog" && ./prog| tee prog` > > > > That would overwrite your program with the output of your program. Is > > that > > really what you want to do? > > > > man tee > > No, I am not overwriting the program with the output. There's probably > something wrong but i can take care of it. Now that I think of it, you'd probably get lucky -- 'tee prog' might open the file first, then gcc would remove that file and overwrite it. But again, read the manual -- 'man tee' -- tee is for sending output both to standard output and to a file. Is that what you're trying to do here? I don't see why you're using tee at all. > > There are probably newer/better alternatives to those, too... > > Newer / Better alternatives ??? I could not think of a better way. If > you have something in your mind that can ease the above process, that > would be great. Nothing in particular, all I mean is that it's been awhile since I've looked at message queues, but I do remember there was a lot of active research the last time I looked. So, I couldn't tell you what's best, but the basic components haven't changed. You'll need: - Some way to fire off a background task. - A separate server (outside of Rails) to do Comet or WebSockets. - Some custom client-side JavaScript to connect to that server. - Some way for the background task to send updates to that server. The last time I did something like this, I used custom JavaScript code (with maybe a little jQuery), rubystomp, a custom Rack-based Comet server (borrowed some code from somewhere, can't remember where), and Rails for the rest of the application. I think I also used open3. However, I was also only running a certain limited number of commands remotely, and I was only allowing administrators to run them. I also never got this application to production, and as it would only have ever been used by administrators, it didn't need to be particularly efficient -- so I have no idea how well those pieces (rubystomp, etc) actually perform.