Explanation of code - fork, wait, execv - c

I'm trying to understand what the following code does:
#include <stdio.h>
#include <stdlib.h>
#include <syscall.h>
#include <unistd.h>
int main(void) {
int pid;
for(;;) {
pid = fork();
printf(getpid());
if(pid == -1) {
printf("fork failed");
exit(1);
}
if(pid == 0) {
execv("MYFORKAPP", NULL);
exit(2);
}
wait();
}
return 0;
}
The program itself is called MYFORKAPP. I'm learning about these 3 functions and I saw this code on the internet and I don't understand what it does.
I tried to run it (Fedora GCC) but the terminal is empty.
Should it at-least print the first getpid()?
Can you please explain me this code?

printf(getpid());
This may crash the program. printf() expects its first argument be a string, but getpid() will return a integer, so this integer will be used as a pointer to an array of character, this very likely leads to a crash, i.e. segmentation fault.
Besides that, what this program does is
fork() a child process and wait()
this child process will execuate the same program again
so it will fork() and wait()
and so on, until your system does not have enough resource to create new process
then fork() will fail, these different level child processes will exit one by one
finally, the first process created by your shell will exit, and the program ends.

What the following code does - segmentation fault.
Must be:
#include <stdio.h>
#include <stdlib.h>
#include <syscall.h>
#include <unistd.h>
int main(void) {
int pid;
for(;;) {
pid = fork();
if(pid == -1) {
printf("fork failed");
exit(1);
}
if(pid == 0) {
printf("child has pid %d\n", getpid());
execv("MYFORKAPP", NULL);
exit(2);
}
wait();
}
return 0;
}
This is a loop:
1. Parent creates a child process.
2. Child turnes to MYFORKAPP.
3. Parent wait for the child process.
4. Child terminates (may be).
5. goto 1

Related

Create a chain of n sub processes

In c++ create chain of n processes with n as input and the output of processes should be as parent1->child1(parent2)-->child2(parent3),by using recursive function im able to generate the output but unable to exit the loop i also need help in sending an input of n for which the loop should break.
below is my code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int foo(const char *whoami) {
printf("I am a %s. My pid is:%d my ppid is %d\n", whoami, getpid(), getppid() );
return 1;
}
int func() {
pid_t pid=fork();
if (pid==0) { /* only execute this if child */
foo("child");
pid_t pid=fork();
if (pid==0) { /* only execute this if child */
foo("child");
func();
exit(0);
}
}
exit(0);
}
wait(0); /* only the parent waits */
return 0;
}
int main(void){
foo("parent");
func();
return 0;
}
You can't exit the loop for a simple reason, and that is, you spawn child processes endless. Whenever you fork() a new process starts, then it forks again.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int n=5;
int foo(const char *whoami) {
printf("I am a %s. My pid is:%d my ppid is %d\n", whoami, getpid(), getppid() );
return 1;
}
int func(int n)
{
if (n == 0)
{
return 0;
}
int pid = fork();
if (pid == -1) {
exit(0);
}
if (pid==0) {
foo("child");
n = n-1;
func(n);
exit(0);
}
else {
wait(NULL);
}
return 0;
}
int main()
{
func(n);
return 0;
}
gcc -std=c99 prog.c -o prog
./prog
OUTPUT:
I am a child. My pid is: 1159 my ppid is 1158
I am a child. My pid is: 1160 my ppid is 1159
I am a child. My pid is: 1161 my ppid is 1160
I am a child. My pid is: 1162 my ppid is 1161
I am a child. My pid is: 1163 my ppid is 1162
From what you are saying i understand you are having the following problems:
1st. You are trying to send 'data' from one process to another
2nd. You are trying to find a way to stop your program from running.
Now for the first. If you want to do that and i understood it correctly, there are 2 ways to achieve that. One is the use of shared memory and the other is the use of pipelines. Shared memory is pretty obvious on what is doing. Pipes are taking the stdout of a process and redirecting it as a stdin in the next process.
Now you need a closure to your program. A child process is executed when it executes a command(exec) or when it is told so(with an IF statement for example and a return). You can create a statement of your liking, and when a child process meets your requirments then you can make it die(There is also a way to kill the parent process from the child process with the kill(pid, SIGKILL); command.
I didn't provide you with any code because it is unclear to me the exact nature of your problem.
Hope my assuming led you to something!

maximum concurrent processes active on a system at a time with fork()

this program is used to create maximum no. of processes system is allowed to create
Ok fine but i didn't get the else part what is going in there
When i execute it my system hangs boot itself automatically??
Can someone please explain it how the following code works??
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int i = 1;
for(;;)
{
pid = fork();
if(pid < 0)
printf("MAX no of concurrent process are %d\n",i);
if(pid == 0)
i++;
else
{
wait(0);
exit(0);
}
}
return 0;
}
On entering the for loop, the process is tried to be forked.
On success, in the parent process, fork() returns something > 0, the PID of the child. The child returns 0.
On failure, fork() returns < 0. This case should be handled appropriately.
In your code, the child process increments the "inherited" i and goes on with the next loop run, but the parent waits for its child and exits.
This all goes well up to the point where fork() fails. Then you get an output, but the code is continued nevertheless, up to wait(0). There it hangs, and so do all its parents.
If you would do
if(pid < 0) {
printf("MAX no of concurrent process are %d\n",i);
exit(0); // or return 0
}
the child which was unable to create another child would exit properly and so would do all of its parents.

IPC Pipe in Linux C

It's a simple code which makes two child processes communicate: first one execute "ls" and pass the output into myfd[1]; second one receives the output from myfd[0], and then execute "sort"(and shows the result). The parent process waits for these two processes.
But this code doesn't work. It gets stuck at the second child process. Any possible reason why?
Did I use the right "close" and "dump" in proper place?
my code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main(void)
{
int pid;
int wpid;
int status = 0;
int myfd[2];
printf("parent's pid: %d\n",getpid());
pipe(myfd);
pid = fork();
if(pid == 0) // child 1 - execute "ls"
{
printf("child1's pid: %d\n",getpid());
close(1);
dup(myfd[1]);
close(0);
close(myfd[0]);
execlp("ls","child_process1",NULL);
}
else
{
pid = fork();
if(pid == 0) // child 2 - execute "sort"
{
printf("child2's pid: %d\n",getpid());
close(myfd[1]);
close(0);
dup(myfd[0]);
execlp("sort","child_process2",NULL);
}
}
// parent
while((wpid = wait(&status)) > 0)
{
// wait until two child processes finish
}
printf("done!\n");
}

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;
}

Creating child processes/killing processes in C/UNIX

So I've been working on this today and I'm pretty sure I'm close, but I'm still a bit confused on how to terminate child processes and if I'm doing this assignment correctly. Here's the problem description:
Write a UNIX program that creates a child process that
prints a greeting, sleeps for 20 seconds, then exits.
The parent process should print a greeting before creating
the child, and another after the child has terminated. It
should then terminate.
And here's the code that I have:
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int child;
printf("Parent Greeting\n");
child = fork();
if(child >= 0)
{
if(child == 0)
{
printf("Child process\n");
sleep(2);
printf("Child exiting\n");
exit(0);
}
}
else
{
printf("Failed\n");
}
printf("End");
exit(1);
return 0;
}
The issue I'm running into is how to properly terminate the child process. If I have the exit statements commented out, then the child will run, wait, and then the "End" statement will print. If I have the exit statements in, then the child process will say that it's exiting and the program will just sit until I ctrl+c out of it. Any help would be appreciated, as I'm interested in the topic but am a bit confused :) Thank you!
You don't have to terminate the child process from the parent; it should terminate itself (and does after the sleep(), printf() and exit()). The parent process should wait() or waitpid() for the child to die before it prints the "End" message. Also, your "End\n" message should include a newline.
The exit(1); (at the end of the first program) is not wanted; it indicates failure. The exit() function does not return, so as written the return is redundant. But it would be better to remove the exit() and leave the return 0; indicating success.
(Note that the child should include a call to exit(), probably with the value 0 rather than 1 as in the revised code. After all, it has done its job successfully.)
The problem is that you have forced the parent process to exit before the child process , in that case the child process ceases to become a zombie process and in some time a ghost process , add a wait() at the end before the final exit .
I think this is exactly what you wanted to achieve.
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
void err_sys(const char* x)
{
perror(x);
exit(1);
}
int main()
{
pid_t childPid;
printf("Parent greeting\n");
childPid =fork();
if (childPid >=0)
{
if(childPid == 0)
{
printf("Child process\n");
sleep(20);
printf("child exiting\n");
}
else
{
waitpid(-1,NULL,0);
}
}
else
{
err_sys("fork error\n");
}
printf("END\n");
return 0;
}

Resources