How do I get input from a terminal in a separate process?

Viewed 77

I tried using fork() in order to get input from the terminal at the same time as my program was exchanging messages with server, but the result was a program that was reading input even before I pressed enter.

So if I use this:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <mqueue.h>
#include <sys/msg.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>


int main(int argc, char ** argv){
    int pid = fork();

    if (pid == 0){
        for(int i =0; i<10; i++){
            char command[255];
            fgets (command, 255, stdin);
            printf("%s\n", command);
            sleep(1);
        }
        exit(0);
    } else {

    }
}

When I run the program this happens without me doing anything:

�   
�   
�   
�   
�   
�   
�   
�   
�   
�   

Exactly the same thing happens if I use scanf("%s\n", command); or fgets (command, 255, stdin);and all other variations I could find...

If I change the code to

int main(int argc, char ** argv){
    int pid = fork();

    if (pid != 0){
        for(int i =0; i<10; i++){
            char command[255];
            fgets (command, 255, stdin);
            printf("%s\n", command);
            sleep(1);
        }
        exit(0);
    } else {

    }
}

then it works fine, but I wanted my input reading process to be a child as pid of the original process was a part of information given to my server process.

Some additioanl information:

I use makefile when compiling programs:

cc = gcc -Wall -D_DEFAULT_SOURCE -std=c11 -g

all: server client

dirs:
    mkdir -p build

server: dirs utils server.c
    $(cc) -c server.c -o build/server.o
    $(cc) build/server.o build/utils.a -o server
    
client: dirs utils client.c
    $(cc) -c client.c -o build/client.o
    $(cc) build/client.o build/utils.a -o client
    
utils: dirs utils.c
    $(cc) -c utils.c -o build/utils.o
    ar rcs build/utils.a build/utils.o
    
problem: dirs problem.c
    $(cc) -c problem.c -o build/problem.o
    $(cc) build/problem.o -o problem

clean:
    rm -Rf build *.out *.so *.o *.a
1 Answers

The parent process dies and the child process is adopted by the reaper or an subreaper process. Therefore, your child process is "detached" from the terminal, and thus, the parent process have to call wait() or waitpid().

 void init_reader(){
    int pid = fork();

    if (pid == 0){
        for(int i =0; i<10; i++){
            char command[255];
            fgets (command, 255, stdin);
            printf("%s\n", command);
            sleep(1);
        }
        exit(0);
    } else {
       wait(NULL);
    }
}
Related