man
man

Reputation: 23

How to determine if the process waits input from the user

My app is to take c++ CPP file and compile it and then run it. everything seems to be perfect. but when the user forgets to but the input and the c++ program require an input the program stops working. so is there is a way to know if the c++ program requires user input or not so I can handle the situation when the user forgets to but input? and if not how can I treat this situation?

my code for run function is:

public void runFile(String input) {
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "./a.out");
        Process process = processBuilder.start();

        BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        writer.write((input + "\n").getBytes());
        writer.flush();

        String s = null;
        // Read the output from the command:
        textArea2.setText(stdInput.readLine());
        while ((s = stdInput.readLine()) != null)
            textArea2.setText(textArea2.getText() + "\n" + s);
        
        // Read any errors from the attempted command:
        if((s = stdError.readLine()) != null) {
            textArea2.setText(s);
            while ((s = stdError.readLine()) != null) {
                textArea2.setText(textArea2.getText() + "\n" + s);
            }
        }

    } catch (Exception e) {
        textArea2.setText(e.toString());
        e.printStackTrace();
    }
}

Upvotes: 0

Views: 68

Answers (1)

man
man

Reputation: 23

After a lot of searches and reading about this bug I found that there is no way to know if the process waits for input before writing output and also there is no way in Process class to stop the java program from being frozen and stopped working when the c++ program requires two inputs for example and the user entered only one input.

How to deal with this situation: I used Thread as shown in the new code below to keep the java program alive when this situation acquires and stops it from being frozen.

public byte runFile(String input, byte compilere, String fileName) {
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();

        if (compilere == 0) // c++  code
            processBuilder.command("bash", "-c", "./a.out");
        else
            processBuilder.command("bash", "-c", "java " + fileName);

        Process process = processBuilder.start();

        BufferedOutputStream writer = new BufferedOutputStream(process.getOutputStream());
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        if (!input.isEmpty()) {
            writer.write((input + "\n").getBytes());
            writer.flush();
        } else {
            textArea2.setText("Input field is empty!");
            return 1;
        }

        // Read the output from the command:
        thread1 = new Thread() {
            public void run() {
                try {
                    String s = null;
                    s = stdInput.readLine();
                    if (s != null) {
                        textArea2.setText(s);
                        while ((s = stdInput.readLine()) != null)
                            textArea2.setText(textArea2.getText() + "\n" + s);
                    }
                    thread2.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        // Read any errors from the attempted command:
        thread2 = new Thread() {
            public void run() {
                try {
                    String s = null;
                    s = stdError.readLine();
                    if (s != null) {
                        textArea2.setText(s);
                        while ((s = stdError.readLine()) != null)
                            textArea2.setText(textArea2.getText() + "\n" + s);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();

        thread3 = new Thread() {
            @Override
            public void run() {
                try {
                    sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (textArea2.getText().isEmpty()) {
                    textArea2.setText("The input is not complete or the your program is slow !");
                }
            }
        };
        thread3.start();

    } catch (Exception e) {
        textArea2.setText(textArea2.getText() + "\n" + e.toString());
        e.printStackTrace();
        return 1;
    }
    return 0;
}

Edit: After Marquis of Lorne 's comment I handled the situation when there is no input and the c++ app requires an input.

Upvotes: 1

Related Questions