0

I'm trying to write a program that creates a child process and then closes itself. I then need the child to remain connected to the terminal.

The child process is working as intended (waits for terminal input, then prints it out) until the parent closes . When the parent process is terminated the child no longer waits for input and the "fgets error" message is printed out in the terminal indefinitely.

This is strange, as it seems that after the parent terminated the stdin closed but stdout of the child remained connected to the terminal.

int main(){
int pid1;
pid1=fork();
if (pid1==-1){
   perror("fork");
   exit(EXIT_FAILURE);
}
if (pid1==0){
   while(1){
   char *data;
   char *result;

   result=fgets(data,100,stdin);
   if (result!=NULL){
      printf("%s\n",data);
   }
   else{
       printf("fgets error\n");
       sleep(1);
       }
   }
}
else
{
//The sleep below is for debugging purposes
sleep(5);
exit(EXIT_SUCCESS);
}   
}

Is there a way to keep the stdin/stdout of the child process directed from/to the terminal after it's parent has terminated? Any help/explanation would be greatly appreciated.

tomullus
  • 11
  • 2
  • 2
    I think you've got the same scenario as in [Two children of same parent are not communicating using pipe if parent does not call `wait()`?](http://stackoverflow.com/questions/32460033). The [`tcsetpgrp()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html) call used by modern job-control shells is part of the problem. I'm not clear whether there's a way around it — AFAICT, when the controlling process denies the child process access to the terminal, that denial is irrevocable and incontrovertible. I started experimenting, but getting the right setup is hard. – Jonathan Leffler Sep 16 '15 at 23:22
  • 1
    You are calling `fgets()` with an uninitialized pointer. That will cause problems, but maybe not what you describe. – rodrigo Sep 16 '15 at 23:32
  • 1
    @JonathanLeffler: It might be possible if the child disowns the controlling terminal and tries to use it as a non-controlling terminal, but then it will be fighting with the shell for input. The setup OP is asking for does not logically make sense. – R.. GitHub STOP HELPING ICE Sep 16 '15 at 23:42

1 Answers1

0

As the other answer by @Jonathan-Leffler points out, that is caused by the shell taking ownership of stdin when the parent process finishes. The problem is that, while stdout can be shared by as many process as you want (output is just mixed), stdin cannot be easily shared.

A possible workaround, without modifying your program (let it be ./test) may be:

$ cat | ./test

Now, the shell will wait for cat to finish, but cat will not finish until you type EOF (^D) or writing to stdout fails. But even if your parent process finishes, the duplicated fd in the child process will continue to consume the catted data.

rodrigo
  • 94,151
  • 12
  • 143
  • 190