Child executing entire process - c

The following commands are inputted into this code: "CREATE", then "QUIT". When "CREATE" is called, the process needs to fork and further code executed within the child.
My output should be this (with the input being printed):
- INPUT: CREATE
- CALLED_CREATE
- CHILD_PROCESS
- INPUT: QUIT
However, I have this:
- INPUT: CREATE
- CALLED_CREATE
- INPUT: QUIT
- INPUT: CREATE
- CALLED_CREATE
- CHILD_PROCESS
- INPUT: QUIT
My understanding of fork() is that the parent process will continue executing the code if it's available to the parent, and likewise for the child - beginning from the instruction, fork(). Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include "locker.h"
int main(){
char user_input[100];
int active_input = 0;
int this_pid;
while(active_input == 0){
//receive user_input
scanf("%s", user_input);
printf("INPUT: %s\n", user_input);
if(strcmp(user_input, "CREATE") == 0){
printf("CALLED_CREATE\n");
if((this_pid = fork()) < 0){
perror("Failed to fork process");
return EXIT_FAILURE;
}
//child
if(this_pid == 0){
printf("CHILD_PROCESS\n");
}
//parent
if(this_pid > 0){
//printf("PARENT_PROCESS\n");
}
}
if(strcmp(user_input, "QUIT") == 0){
active_input = 1;
break;
}
}
}
Thanks for your help :)

I suspect that the main problem is that you don't stop the child process. E.g., after you enter once CREATE, the child process will print CHILD PROCESS, but will continue looping in its own process, while the parent does the same.
You should make sure that the child process exits after doing something meaningful. Also, as noted above by Chrono Kitsune, the parent needs to wait() for the child process to reap its exit status and prevent zombies.
Other than that, your user input buffer is 100 chars, opening your program to buffer overflow attacks. But that's a different story.
Your code, slightly reworked which I think does what you want:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int main() {
char user_input[100];
int this_pid;
while (1) {
//receive user_input
scanf("%s", user_input);
printf("INPUT: %s\n", user_input);
if(strcmp(user_input, "CREATE") == 0){
printf("CALLED_CREATE\n");
if((this_pid = fork()) < 0){
perror("Failed to fork process");
return EXIT_FAILURE;
}
//child
if (this_pid == 0){
printf("CHILD_PROCESS\n");
// do some interesting stuff here, and then don't forget to
exit(0);
}
}
if(strcmp(user_input, "QUIT") == 0)
break;
}
}

Related

Communication between parent and child results in system lockup

I am trying to create some communication between two programs by forking in the child program within the parent program.
When I execute the child program separately, it works. The purpose of it is that if someone types 1, 2, or 3 followed by enter, that program prints that number as a word. But if one presses 0 and enter, the program exits.
Now I am trying to make the parent program execute the child program in a way where all it does is exit the program while showing the progress of action.
When I execute my program, I see:
Child to start
Parent running OK
Which suggest the child program is running, otherwise I would see:
Exec failed
So instead of me seeing any actual useful output, the system decides to gradually slow down to the point where at first the mouse cursor doesn't move smoothly when I move the mouse, then It got to the point where it wouldn't respond to the keyboard, so I literally had to hold the power button to reset my computer.
How do I fix this so that it can work with any program (that I use as a child) that can exit when I press 0 and enter from within it?
This is my code for the parent:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
//Setup child read and write file handle named parr and parw respectively
//and parent read and write file handle named to parr and parw respectively
#define kidr wrp[0]
#define kidw rdp[1]
#define parw wrp[1]
#define parr rdp[0]
int main(){
int cmd=0;
//setup and start pipes
int wrp[2],rdp[2];
if (pipe(wrp) == -1 || pipe(rdp) == -1){printf("ERROR: cant run pipes.\n");return -1;}
//Start fork
pid_t f=fork();
if (f > 0){
int wstat; //wait state data
char buff[100]; //our data buffer
close(kidr); //we are parent so close child handles
close(kidw);
struct timeval tv;
fd_set readfds;
tv.tv_sec = 1;
tv.tv_usec = 0;
printf("Parent running OK\n");
while(1){
//process other async events here
pid_t wpid=waitpid(-1,&wstat,WNOHANG);
if (wpid==-1){printf("Wait PID error\n");break;}
if (wpid > 0){printf("Children closed OK\n");break;}
//Process data only when child data is readable via pipe
FD_ZERO(&readfds);FD_SET(parr, &readfds);
select(parr+1, &readfds, NULL, NULL, &tv);
if(FD_ISSET(parr, &readfds)){
memset(buff,0,99);
int rd=read(parr, buff, 50);
//doesnt seem to reach this point...
if (rd > 0){
printf("Got: %s\n", buff);
}else{
if (cmd==0){
printf("sending data...\n");
char*dat="0\n"; //parent sends 0 and the enter button.
cmd++; //so this doesn't get called again
write(parw,dat,strlen(dat));
}
}
}
}
//close everything and exit
close(parr);
close(parw);
return 0;
}
if (f==0){
printf("Child to start\n");
//Child mode.
//Close parents
close(parr);close(parw);
//make stdio as child handles
dup2(kidr,STDIN_FILENO);dup2(kidw,STDOUT_FILENO);
//close old child handles
close(kidw);close(kidr);
execlp("/path/to/forkt","forkt",NULL);
//We shouldn't get here unless 'ls' command isnt found
printf("Exec failed\n");
_exit(-1);
}
if (f==-1){
//If fork() doesnt work...
printf("Fork error\n");
}
return 0;
}
This is my code for the child and I compiled it so its named forkt.
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("The child has started\n\n");
char c[100];
while (1){
printf("Enter number or 0 to exit: \n>");
scanf("%s",c);
if (c[0]=='1'){printf("one\n");}
if (c[0]=='2'){printf("two\n");}
if (c[0]=='3'){printf("three\n");}
if (c[0]=='0'){return 0;}
}
}
Update
I took a suggestion of running my parent code through the gdb debugger.
I compiled my code using the gcc -g switch then executed it with gdb a.out
Then in gdb, I set a break point to first line of code then used the "run" command then i kept using the "step" command until I found the crashing point which is here:
pid_t f=fork();
if (f > 0){ // <- right here
This suggests that somehow the child is creating the lockup(?) even though the child runs fine if it is run by itself without a parent?
AFAICS, the parent won't write anything to the child until the child sends something back, but the child won't send anything until it gets something from the parent. That's a deadlock. There's also a problem with buffering. The pipes are not 'interactive devices' so the output streams are not flushed until the buffer is full, the stream is closed, or you call fflush().
Here's some alternative but very similar code to yours:
forkt.c
#include <stdio.h>
int main(void)
{
printf("The child has started\n\n");
fflush(stdout);
char c[100];
while (1)
{
printf("Enter number or 0 to exit:\n>");
fflush(stdout);
if (scanf("%s", c) != 1)
return 0;
fprintf(stderr, "Child received: [%s]\n", c);
if (c[0] == '1')
{
printf("one\n");
}
if (c[0] == '2')
{
printf("two\n");
}
if (c[0] == '3')
{
printf("three\n");
}
if (c[0] == '0')
{
return 0;
}
fflush(stdout);
}
}
This is mostly noticeable for a collection of calls fflush(stdout).
parent.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#define kidr wrp[0]
#define kidw rdp[1]
#define parr rdp[0]
#define parw wrp[1]
int main(void)
{
int cmd = 0;
int wrp[2], rdp[2];
fprintf(stderr, "Parent process: PID %d\n", getpid());
if (pipe(wrp) == -1 || pipe(rdp) == -1)
{
fprintf(stderr, "ERROR: cant run pipes.\n");
exit(1);
}
pid_t f = fork();
if (f == -1)
{
fprintf(stderr, "Fork error\n");
exit(1);
}
if (f > 0)
{
int wstat;
char buff[100];
close(kidr);
close(kidw);
fprintf(stderr, "Parent running OK - child %d\n", f);
while (1)
{
pid_t wpid = waitpid(-1, &wstat, WNOHANG);
if (wpid == -1)
{
fprintf(stderr, "Wait PID error\n");
break;
}
if (wpid > 0)
{
fprintf(stderr, "Child %d exited\n", wpid);
break;
}
for (cmd = 3; cmd >= 0; cmd--)
{
char buffer[30];
int nb = snprintf(buffer, sizeof(buffer), "%d\n", cmd);
int wr = write(parw, buffer, strlen(buffer));
if (wr != nb)
{
fprintf(stderr, "Parent failed to write: %d\n", wr);
exit(1);
}
fprintf(stderr, "Parent sent: %s", buffer);
memset(buff, 0, 99);
int rd = read(parr, buff, 50);
if (rd > 0)
{
fprintf(stderr, "Got: [[%.*s]]\n", rd, buff);
}
else
{
fprintf(stderr, "Parent read failed\n");
exit(1);
}
}
}
close(parr);
close(parw);
return 0;
}
if (f == 0)
{
fprintf(stderr, "Child %d to start\n", getpid());
close(parr);
close(parw);
dup2(kidr, STDIN_FILENO);
dup2(kidw, STDOUT_FILENO);
close(kidw);
close(kidr);
execlp("forkt", "forkt", NULL);
fprintf(stderr, "Exec failed\n");
_exit(-1);
}
return 0;
}
The surgery here is more extensive.
When I ran the code, one time I got the output:
Parent process: PID 94693
Parent running OK - child 94694
Parent sent: 3
Child 94694 to start
Got: [[The child has started
]]
Parent sent: 2
Child received: [3]
Got: [[Enter number or 0 to exit:
>]]
Parent sent: 1
Child received: [2]
Got: [[three
Enter number or 0 to exit:
>]]
Parent sent: 0
Child received: [1]
Got: [[two
Enter number or 0 to exit:
>]]
Child received: [0]
Parent sent: 3
Got: [[one
Enter number or 0 to exit:
>]]
Parent sent: 2
Parent read failed
Note that the prompts from the child are mixed up with the output.

Use IPC Mechanism of pipe to complete the program so the child and parent print the same output

So I recently had an exam in a class about operating systems and it had asked me to write a program using pipe(). This program was intended to send and receive data through the pipe so that regardless of which file was run, the output would be the same.
The output should be the following.
Hello (from child) 1
Hello (from parent)
Hello (from child) 2
The template code was given as follows. (I could not change this code, I was only to insert code to make it work). No creativity... I know.
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
int main() {
pid_t pid;
char buf[32];
if ((pid = fork()) < 0) {
puts("Error");
} else if(pid == 0) { //child
fprintf(stdout, "Hello (from child) 1\n");
fprintf(stdout, "Hello (from child) 2\n");
fflush(stdout);
}
else {
fprintf(stdout, "Hello (from parent)\n");
}
}
After some time my conclusion was the following. But after executing nothing printed. (I couldn't test it because it was a paper exam but I tested it after). Also, I was under a time crunch so I know the mistakes are probably frequent.
I added the User Start and User End to show where I could change the code. Any help would be appreciated.
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
int main() {
pid_t pid;
char buf[32];
// User Start
int fds[2];
pipe(fds);
close(1);
dup(fds[1]);
// User End
if ((pid = fork()) < 0) {
puts("Error");
} else if(pid == 0) { //child
// User Start
// User End
fprintf(stdout, "Hello (from child) 1\n");
// User Start
write(fds[1],"Hello (from child) 1\n",21);
read(fds[0],buf,21);
write(fds[1],"Hello (from child) 2\n",21);
// User End
fprintf(stdout, "Hello (from child) 2\n");
// User Start
// User End
}
else {
// User Start
read(fds[0],buf,21);
// User End
fprintf(stdout, "Hello (from parent)\n");
// User Start
write(fds[1],"Hello (from parent)\n",21);
read(fds[0],buf,21);
// User End
}
}
UPDATE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
int main()
{
pid_t pid;
char buf[32];
int returnstatus1;
int fds[2];
returnstatus1 = pipe(fds);
printf("Return status = %d\n",returnstatus1); //check if pipe is created or not
if(returnstatus1 == -1)
{
printf("Pipe 1 could not be created\n");
return 1;
}
if((pid = fork()) < 0)
{
puts("ERROR");
}
//child
else if(pid == 0)
{
fprintf(stdout,"hello (from child) 1\n");
close(fds[0]);
write(fds[1],"hello (from child) 1\n",21);
close(fds[1]);
read(fds[0],buf,21);
fprintf(stdout,"hello (from child) 2\n");
close(fds[0]);
write(fds[1],"hello (from child) 2",21);
}
//parent
else
{
close(fds[1]);
read(fds[0],buf,21);
fprintf(stdout,"hello (from parent)\n");
close(fds[0]);
write(fds[1],"hello (from parent)\n",21);
close(fds[1]);
read(fds[0],buf,21);
}
return 0;
}
The use of pipes for synchronization is slightly unorthodox, but it's perfectly doable. You have to remember that reading from an empty pipe is blocking — it waits until something has written to it.
Since it's clearer that way, I'll show the parent first, not the child. Of course it doesn't matter in which order you put the if branches — you can adapt it to your exam's format, and I strongly encourage you to do so in order to get a hang of it.
With that in mind, we go ahead:
#include <stdio.h>
#include <unistd.h>
int main (void) {
pid_t pid;
char buf;
int parent_pipes[2];
int child_pipes[2];
pipe(child_pipes);
pipe(parent_pipes);
if ((pid = fork()) < 0)
puts("Error");
else if (pid) {
// parent first!
// wait for the child to write something into the pipe...
read(*child_pipes, &buf, 1);
// and now write to stdout, and tell the child that we're ready
fprintf(stdout, "Hello (from parent)\n");
fflush(stdout);
write(parent_pipes[1], "R", 1); // it doesn't matter what we write; we have to write anything
} else {
// and now the child
// output and flush...
fprintf(stdout, "Hello (from child) 1\n");
fflush(stdout);
// ...and tell the parent that we're ready
write(child_pipes[1], "R", 1); // write end of the pipe
// now wait!
read(*parent_pipes, &buf, 1); // read end of the pipe
fprintf(stdout, "Hello (from child) 2\n");
}
return 0;
}

Redirection of stdin and stdout via pipes in C works for external programmes but not for recursive call

I am trying to communicate with forked child processes via pipe redirection of stdin and stdout in C. I already managed to get this to work for shell commands (like ls, for example) executed in child processes. However, I wasn't able to recursively execute the same program and redirect the output (printed by printf(), fprintf() to stdout, ...) via the pipes from the child process to the parent (in this test to stdout of the parent), although this works fine for ls or similar commands.
Here's how I tried to approach this:
I create a pipe, the reading end is for the parent, the child process should write to the writing end.
The Process forks, both processes close the unused end, respectively.
The writing end of the pipe is redirected to STDOUT_FILENO and closed
The child process executes the program recursively (it is called ./to2)
As mentioned, this does work if I execute ls in the child process, but not if I try to call the same program recursively. Here's my test program where I tried to get this to work:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netdb.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <fcntl.h>
static void usage(void){
fprintf(stderr,"RIP");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]){
if(argc > 1){
dprintf(STDOUT_FILENO,"Please work\n");
printf("\n THIS IS A MESSAGE FROM THE CHILD \n");
fputs("Pretty Please!\n",stdout);
fflush(stdout);
exit(EXIT_SUCCESS);
}
int p1[2];
if(-1 == pipe(p1)) {
fprintf(stderr,"pipe\n");
fprintf(stderr,"%s\n",strerror(errno));
usage();
}
int f = fork();
if(f == 0){
close(p1[0]);
if(dup2(p1[1],STDOUT_FILENO) < 0){
fprintf(stderr,"dup2\n");
usage();
}
close(p1[1]);
//I want this to work:
//execlp("./to2", "./to2", "-e");
//This works fine:
execlp("ls", "ls");
exit(EXIT_SUCCESS);
} else if (f == -1) {
usage();
} else {
close(p1[1]);
int w = -1;
if(-1 == wait(&w)) usage();
char b[12];
memset(b,0,12);
read(p1[0],&b,12);
char reading_buf[1];
while(read(p1[0], reading_buf, 1) > 0){
write(1, reading_buf, STDOUT_FILENO);
}
close(p1[0]);
}
}
For testing purposes, the function is called recursively with additional arguments, while the parent program is called without additional arguments (hence the if(argc>1)).
In the final program, endless recursion is being avoided by other means.
Did I understand something wrongly? I am pretty confused by the fact that the only thing that doesn't seem to work is redirecting the output of my own
program...
Thank you very much in advance, any help or ideas are greatly appreciated.
The primary problem is precisely as outlined in the comments — you are not calling execlp() correctly (nor ls in the alternative). You must make the last argument on those function calls into an explicit null pointer, as shown in this code, which is a mostly mildly edited version of what's in the question:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static void usage(void)
{
fprintf(stderr, "RIP\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
if (argc > 1)
{
dprintf(STDOUT_FILENO, "Please work\n");
printf("THIS IS A MESSAGE FROM THE CHILD\n");
fputs("Pretty Please!\n", stdout);
fflush(stdout);
exit(EXIT_SUCCESS);
}
int p1[2];
if (-1 == pipe(p1))
{
fprintf(stderr, "pipe: %s\n", strerror(errno));
usage();
}
int f = fork();
if (f == 0)
{
close(p1[0]);
if (dup2(p1[1], STDOUT_FILENO) < 0)
{
fprintf(stderr, "dup2: %s\n", strerror(errno));
usage();
}
close(p1[1]);
execlp(argv[0], argv[0], "-e", (char *)0);
fprintf(stderr, "failed to exec %s again\n", argv[0]);
exit(EXIT_FAILURE);
}
else if (f == -1)
{
usage();
}
else
{
close(p1[1]);
char b[13];
memset(b, 0, 13);
if (read(p1[0], &b, 12) < 0)
{
fprintf(stderr, "Failed to read from pipe (%s)\n", strerror(errno));
exit(EXIT_FAILURE);
}
int len = strcspn(b, "\n");
printf("M1 [%.*s]\n", len, b);
char reading_buf[1];
while (read(p1[0], reading_buf, 1) > 0)
{
write(1, reading_buf, STDOUT_FILENO);
}
close(p1[0]);
int w = -1;
if (-1 == wait(&w))
usage();
}
return 0;
}
Two important changes should be highlighted:
This code echoes the first line of data — the one written by dprintf() — whereas the original code just read it and discarded it.
The wait() call is after the input, not before. If the child had more data to write than a set of fixed messages, it could block waiting for the parent to read some of the data, while the parent is blocked waiting for the child to exit. This would be a deadlock.
The usage() function is not appropriately named — it doesn't report how to run the program. I also exit with a failure status, not success, if the child process fails the execlp().
Under peculiar circumstances, the wait() call might report on the exit status from some child other than the one that was forked. It is generally best to use a loop to reap such children. However, the circumstances required are extremely peculiar — the process which launched the parent with an exec*() function must have previously created some children for which it didn't wait, so that they are inherited by the parent process (because the PID doesn't change across an exec*() call).

How to set status termination of a process C?

My program is a rudimental little shell.
It allow you to run programs in PATH as ls, cd..also with arguments.
To run the program type from terminal "./myshell2" then it starts and you can insert how many commands you want.
It starts a child process, runs execvp,it returns and restarts so you can type a new command.
When typed "Q" or "q" all the entire program should terminates.
The problem is that I don't know how to stop it,the code is below.
My idea is, when typed "Q" or "q", to kill the child process created and send a signal to comunicate its bad termination(of child process).
So the final status(from parent) 'll be not 1 and the function returns.
I commented some parts of the code hoping that it's easier to understand.
It works the problem is that to stop it I need of ctrl C.
I would like to say to child process that he must ends with a non-zero value.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
int main(int argc, char * argv[]) {
while(1)
{
pid_t pid = fork();
if (pid == -1) {
perror("fork error");
exit(EXIT_FAILURE);
}
if (pid == 0) { // child process
printf("type the command to start (and arguments if required) \n"
"Q to quit\n");
char *dest[10]; // allow you to insert
char line[4096];//commands from terminal
if (fgets(line,sizeof(line),stdin)==0) return 1;
int i;
line[strcspn(line, "\n")] = '\0';
char *st = line;
for (i=0; i< 10 && (dest[i]=strsep(&st," "))!=NULL;i++)
continue;//now you typed the command
if ( ( memcmp(dest[0],"Q",1)==0 ) // if Q or q the program
|| (memcmp(dest[0],"q",1)==0) ) //must end
{
printf("got it!\n");
if (kill(getpid(),SIGSEGV)==-1) printf("kill error\n");
//in theory the process should terminates with bad status
// and the value of the variable "status" 'll be not 0
// I think that the problem is in this part of the code
}
if( strcmp(dest[0]," ")!=0 )
{
int res = execvp(dest[0], dest);
}
else
{ int res= execvp(dest[1],dest+1);}
perror("execvp error");
exit(EXIT_FAILURE);
}
int status;
pid_t child = wait(&status);
if (child == -1) {
perror("wait error");
exit(EXIT_FAILURE);
}
if (status==1)
break; //so it can exit from the loop that creates new process
setenv("WAIT","TRUE",0); //dont' worry about
//perror("setenv error\n");
if (memcmp("TRUE",getenv("WAIT"),4) == 0 ) //these 6 lines
printf("WAIT=TRUE\n");
else if(memcmp("FALSE",getenv("WAIT"),4) == 0 )
printf("WAIT=FALSE\n");
printf("end current process (status=%d, child=%d)\n", WEXITSTATUS(status), son);
}
return EXIT_SUCCESS;
}
You're printing out WEXITSTATUS() for all cases, but that isn't right. You need to check if the status returned by wait is an exit status or not using WIFEXITED(). If it's non-zero then the child exited normally. Otherwise, you can use WIFSIGNALED() to see if the child was terminated and you'll get the signal from WTERMSIG()
if(WIFEXITED(status))
{
printf("end current process (status=%d, child=%d)\n", WEXITSTATUS(status), son);
}
else if(WIFSIGNALED(status))
{
printf("end current process (signal=%d, child=%d)\n", WTERMSIG(status), son);
}
You really should have the parent process handle the inputting of the command and leave the child process to run it though.

Using Scanf() in child process executed via execv not working

I am executing a really simple program which takes input in integer from user using scanf. I execute this program as a child program via fork() and execv.The child program never takes input from user.Any help would be appreciated.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
pid_t childpid;
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
execv("child",NULL);
exit(1);
}
else
{
printf("Parent process is terminating...\n");
return 0;
}
}
and the child code is
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int temp;
printf("This is Child Process. Child is going to sleep for 5 seconds\n");
sleep(5);
printf("Please enter an integer to terminate the process ");
scanf("%d",&temp);
printf("You entered %d ",temp);
printf("Child terminated");
return 0;
}
OUTPUT
[#localhost cascading]$ ./cascading
Parent process is terminating...
[#localhost cascading]$ This is Child Process. Child is going to sleep for 5 seconds
Please enter an integer to terminate the process You entered 12435[#localhost cascading]$ ^C
[#localhost cascading]$
I am running the code in fedora installed on a virtual machine.Thanks
Once the parent process finishes, control is returned to shell; and stdin could be closed.
To retain child's access to stdin, you can let the parent wait until the child is done.
So, in your parent:
else {
printf("Parent process is terminating...\n");
wait(NULL);
return 0;
}
You need to wait for child process to be finished, please modify your code like this
if(childpid == 0)
{
execv("child",NULL);
exit(1);
}
else
{
wait(); //wait for child
printf("Parent process is terminating...\n");
return 0;
}

Resources