Fork system call

#include<iostream>
using namespace std;
#include<sys/types.h>
#include<unistd.h>
#include<string>
#include<stdlib.h>

int global=2;
string teststr;

int main()
{ pid_t PID;
PID =fork();
cout<<"PID is"<<PID<<endl;

if(PID==0)
{
teststr="child process";
global--;
}

else if(PID<0)
{
cout<<"Sorry coudnt fork the process"<<endl;
exit(1);
}

else
{
teststr="Parent process";
}


cout<<teststr<<endl;
cout<<"Global variable is"<<"\t"<<global<<endl;

return 0;
}




Here In the prgoram process forked will continue to sexcute the statements till return is reached in main.

If I fork a process in a function till when the process is effective?....will it execute all the statements till that function ends?

where do we use this forking mechanism?It doesnt make sense to me executing same set of statements twice.
and why do we use exec system call?

I am new to c++...Please help.


Thanks
Venkat
You are not executing the same set of statements twice.

Those if statements seperate the parent process from the child and they execute different routes.

The child process has zero in variable PID, whereas the parent has the child's process id.
http://www.freebsd.org/cgi/man.cgi?query=fork&apropos=0&sektion=2&manpath=FreeBSD+9.2-RELEASE&arch=default&format=html
Last edited on
Thanks @kbw
I understood fork call.

Can anyone modify that above program by including an exec system call?


Thanks in advance
Venkata
Include it where, to do what? Do you want the child to run some other program?
Hi kbw,

after fork is invoked you can exec the same child process to execute some other program so that I can easily understand the purpose of exec.

if we can create another process to excute someother program through exec ...
why do we need fork sysstem call which can only create a process but cant execute someother program?


Thanks in advance
Venkata
Hi kbw,

You can include exec after fork system call and execute someother program so that its easier for me to understand exec.

If we can create another and process to execute someother program through exec system call then why do we need fork call which can only create a process and cant be made to execute another program?

Hope I am making some sense:)

Thanks in advance
Venkata
fork() creates a child process,, pretty much identical to the parent. (As you've seen above.)

exec() replaces the current process with the named executable file. The variants of exec indicate how the parameters. l means the program args are passed as a list, v means the program args are passed as an array, e means an environment can be passed, and p means the program passed in may be a script and needs to be interpretted.

So execvp() expects the args to be passed in an array, and the command can be a script, the current environment is used.

execle() expects the args to be passed as a list, and the environment to be specified.

I accept this is probably your homework, but here's a simple shell thing that just executes stuff. It demonstrates how to run one program from another.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/errno.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>

std::vector<char*> getargs(const std::string& line);

const std::string prompt = "$ ";

int main()
{
	for (;;)
	{
		// get a commmand from the user
		std::cout << prompt;
		std::string line;
		std::getline(std::cin, line);
		if (line == "done")
			break;

		pid_t pid = fork();
		if (pid == -1)
		{
			std::clog << "fork() failed: " << strerror(errno) << std::endl;
			break;
		}
		else if (pid == 0)
		{
			// execute in child
			std::vector<char*> args = getargs(line);
			int ret = execvp(args[0], &args.front());
			if (ret == -1)
			{
				std::clog << "execvp() failed: " << strerror(errno) << std::endl;
				exit(1);
			}
		}
		else
		{
			// parent waits for child to complete
			int status;
			waitpid(pid, &status, 0);
			std::cout << WEXITSTATUS(status);
		}
	}

	return 0;
}

std::vector<char*> getargs(const std::string& line)
{
	std::vector<char*> args;

	char* p = strdup(line.c_str());
	while (char* q = strchr(p, ' '))
	{
		// save arg
		*q = 0;
		args.push_back(p);

		// step pass spaces
		for (p = q + 1; *p == ' '; ++p)
			;
	}
	// save final arg and terminator
	args.push_back(p);
	args.push_back(nullptr);	// force C++11 so args is moved rather than copied in C++98

	return args;
}
Last edited on
Thanks @KBW

Thanks a lot for your explanation.Vey helpful
Topic archived. No new replies allowed.