0

I am writing a C# application that runs user code over the internet. The user code is sent to the application over an HTTP post request, and it is handled on the server (either compiled, then executed, or executed directly for languages such as python, lua, php). I am using the following code to read the output of the process that runs the user's code (either the compiled binary, or the interpreter):

Thread readThread = new Thread(() =>
{
    char[] buffer = new char[Console.BufferWidth];
    int read = 1;
    while (read > 0)
    {
        read = p.StandardOutput.Read(buffer, 0, buffer.Length);
        string data = read > 0 ? new string(buffer, 0, read) : null;
        if (data != null)
            env.ClientSock.Send(data);
        Thread.Sleep(10);
    }
});
readThread.Start();

Where p is the process running the user's code, and env.ClientSock is the web socket over which the output is sent to the user. The user can write to the process' standard input stream over this same web socket.

This works absolutely fine for most languages the application supports (C#, VB, C++, Python, PHP, Java). However, for C and Lua, if the user's code involves reading from the standard input stream, this read operations blocks before any output is given.

For example, the following C program:

#include <stdio.h>

int main(){
    printf("Hello, World!");
    int i;
    scanf("%d", &i);
    return 0;
}

Will not print anything until the user gives some input. For C, I am using the MSVC compiler that comes with Visual Studio. The same issue occurs when running Lua code:

io.write("Hello World!")
io.read()

Nothing is printed until the user enters some input. I cannot figure out why this is happening, and I would like my application to properly support C and Lua. This issue was also present using Python 2.7, although I overlooked this as Python 3 works as expected.

Why is this happening? How can I fix it?

rodit
  • 1,746
  • 2
  • 19
  • 33
  • 1
    Output is buffered when it is redirected, nothing appears until the buffer fills up to capacity, the program explicitly flushes the buffer or stdout is closed at program end. Only the latter clause applies to these snippets. But these programs cannot end until somebody enters something, stdin is not redirected. This is not different in other runtime environments. Hoping that I/O redirection will always work without trouble for any program is idle hope. – Hans Passant Mar 03 '18 at 14:05
  • @HansPassant Thanks for the reply. Is there any way I can make the program's stdout flush whenever something is written to it? I don't really want the user to have to explicitly flush the stdout (i.e. using fflush in c). Also, why is it that if I was to run the application in command prompt, I do not have this issue? – rodit Mar 03 '18 at 14:08
  • `io.flush()` before `io.read()`. – i486 Mar 03 '18 at 14:14
  • Perhaps [this](https://stackoverflow.com/questions/1033648/c-sharp-redirect-console-application-output-how-to-flush-the-output) might help? – Francesco B. Mar 03 '18 at 14:15
  • @i486 Thanks - I understand that this will work, but I do not really want users to have to do this in their code. And again, why is this not necessary when running the program in command prompt (the output appears without flushing before the read operation). – rodit Mar 03 '18 at 14:17
  • 1
    @FrancescoB. Thanks - I'll have a read of that. – rodit Mar 03 '18 at 14:17

0 Answers0