Stream: beginners

Topic: Rebinding stdin using basic cli


view this post on Zulip Isaac Van Doren (Nov 19 2023 at 22:53):

I would like to write a program using basic-cli that reads input that is piped in, and then later on in the execution, reads more input from the terminal. My understanding is that when I pipe something in like in

echo 7 | myRocProgram

the stdout of the first program is bound to the stdin of the second. So when I try to read anything else in from myRocProgram it doesn't work because stdin is not bound to the terminal input.

Does anyone know if this is possible with basic cli? If not, does it seem like a reasonable thing to add given the scope?

I thought I might be able to accomplish it by running commands but I suspect that that will not work since the commands run in a child process but I need to alter the main process.

view this post on Zulip Richard Feldman (Nov 19 2023 at 22:58):

seems like a reasonable use case to me!

view this post on Zulip Richard Feldman (Nov 19 2023 at 22:58):

I think the question is what the API would look like

view this post on Zulip Brendan Hansknecht (Nov 19 2023 at 22:59):

Can that be done in a regular c program?

view this post on Zulip Isaac Van Doren (Nov 19 2023 at 23:05):

It looks like it https://stackoverflow.com/questions/584868/rerouting-stdin-and-stdout-from-c

view this post on Zulip Brendan Hansknecht (Nov 19 2023 at 23:41):

That doesn't work as you think. it will reopen stdin, which is just at the eof from echo 7.

view this post on Zulip Isaac Van Doren (Nov 19 2023 at 23:41):

Ah I see

view this post on Zulip Brendan Hansknecht (Nov 19 2023 at 23:42):

Just tested with this

#include <stdio.h>
#include <stdbool.h>

int main(void){
    size_t no = 0;
    bool line_top = true;

    while (1) {
        int ch = fgetc(stdin);
        if(ch == EOF) break;

        if(line_top)
            printf("%zu ", ++no);

        line_top = (ch == '\n');

        fputc(ch, stdout);
    }
    fflush(stdout);

    freopen("newin", "r", stdin);
    int ch = fgetc(stdin);
    if(ch == EOF) {
        printf("reopened file is just at eof");
    } else {
        printf("the reopened file is useful");
    }
    fflush(stdout);
    return 0;
}
$ clang main.c -o main && echo 7 | ./main
1 7
reopened file is just at eof%

view this post on Zulip Brendan Hansknecht (Nov 19 2023 at 23:50):

you may be able to read /dev/tty as a file. That may be a fix. Though it sounds like that is not really a proper solution. It sounds like if you want stdin from the terminal, you should really make all other input come through command line arguments and files rather than being piped in.

view this post on Zulip Isaac Van Doren (Nov 19 2023 at 23:53):

Mm I'll have to give that a try. I agree that it seems improper. Unfortunately being able to pipe the input in specifically is very relevant here

view this post on Zulip Brendan Hansknecht (Nov 19 2023 at 23:57):

Just curious, what are you working on?

view this post on Zulip Isaac Van Doren (Nov 20 2023 at 00:52):

In gob you can pipe programs into other programs, which I think could be interesting for scripting purposes. So piping is important to be able to chain multiple together easily.

There is an option to step through the execution of a program one state at a time where it waits for input before taking the next step.

So when you pipe in input, the stepping doesn't work because Stdin.line always returns End.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 01:55):

Interesting. Makes sense


Last updated: Jul 05 2025 at 12:14 UTC