How to get child PID in C? - c

I'm creating child processes in a for-loop. Inside the child process, I can retrieve the child PID with getpid().
However, for some reason when I try to store the value of getpid() into a variable declared by the parent process, the change is nullified when I check for it in the parent process. I'm assuming this has to do with some sort of process variable scope. Not really familiar with C, so can't be too sure.
Anyhow what is a way of storing the result of getpid() of a child PID (when called from the child process) into a variable in the parent process?
Or maybe another approach is storing fork() into a variable in the parent and calling some function on that variable to retrieve the child's PID? I don't know how to do this either, so if this is the better way, how would you do this?

fork already returns the child's pid. Just store the return value.
look at man 2 fork:
RETURN VALUES
Upon successful completion, fork() returns a value of 0 to the child process and
returns the process ID of the child process to the parent process. Otherwise, a
value of -1 is returned to the parent process, no child process is created, and
the global variable errno is set to indicate the error.

As mentioned in previous answer that "fork() returns a value of 0 to the child process and returns the process ID of the child process to the parent process." So, the code can be written in this way:
pid = fork(); /* call fork() from parent process*/
if (0 == pid)
{
/* fork returned 0. This part will be executed by child process*/
/* getpid() will give child process id here */
}
else
{
/* fork returned child pid which is non zero. This part will be executed by parent process*/
/* getpid() will give parent process id here */
}
This link is very helpful and explains in detail.

if fork() is successfully created then it returns 0 value in the child process.
int main(void)
{
int id;
id= fork();
if(id==0)
{
printf("I am child process my ID is = %d\n" , getpid());
}
}

If you are calling fork in the following way:
pid = fork()
Then pid is in fact your child PID. So you can print it out from the parent.

Yes, the child process's pid is already returned with fork(), fork() is called once but return twice, different return value in parent and child process, so you can do this:
pid_t pid, pid_c;
pid = fork();
if (pid == -1) { // error
perror("Falied to fork");
} else if(pid == 0) { // execute in child process
// you can get child's pid by getpid() in child process:
pid_t tmp_pid_c = getpid();
execl("bin/ls", "ls", "./", NULL);
} else {
// you can also get child's pid that already returned by fork() in parent process
pid_c = pid;
}

There are two main functions to get the process id of parent process and child. getpid() and getppid()

Related

Parameters of the waitpid()

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int status;
int pid = fork();assigned to variable "pid"
if(pid == 0)
{
printf("I am the child with pid = %d\n", getpid());
}
else
{
printf("I am the parent with pid = %d\n", getpid());
waitpid(pid, &status, 0); // line 51
}
return 0;
}
In line number 51, please clarify the "pid" parameter. what will this process wait for?
fork returns 0 for the child process, -1 on error, and something else for the parent process. The else begins the part for the parent process, that means pid in waitpid contains the child's PID.
Citing man wait:
The waitpid() system call suspends execution of the calling
process
until a child specified by pid argument has changed state. By default,
waitpid() waits only for terminated children, but this behavior is mod-
ifiable via the options argument [...]
In short, waitpid waits for the child process to terminate.
If the fork is successful, fork returns 0 to the child, and returns to the parent the (positive) pid of the newly forked child process. In this statement, the parent waits the child's termination.
on success fork will return child id to parent and 0 to child,
waitpid(pid, &status, 0);
parameter.. ) pid - particular child ID.
parameter.. ) &status - exit status that will send to parent by child
parameter.. ) option
0 - option is indicated that
parent will wait till child is terminated.

Parent and child of fork() in C

Since each process is doing its own thing, which to me feels more like a "brothers/sisters" relationship. Is there a specific reason behind calling them parent process and child process?
Also, is it true that the parent process always run before the child process?
The parent owns the process group and thus spawns and reaps the children. Usually this process does a little bit of administrative work, while the children act as peers and siblings.
The naming is just convention for describing which process spawned the other, though.
The parent process and child process does the work based on your code but not because of parent or child relationship. When you execute fork() in the main thread it will create a child process, here the fork returns a value which is different in parent process and child process which can be used to differentiate the work of parent and child processes accordingly.
fork() always return pid of child in parent process and 0 in child process.
Coming to your second question it always depends on the scheduler as soon as the fork() is called and we cannot predict which process gets to run first after fork() function call.
Is there a specific reason behind calling them parent process and child process?
Well, since it one process (the parent) that creates the second one (the child), that might be the reasoning for the naming.
Also, is it true that the parent process always run before the child process?
The short answer. Nope.
I have been using this in all of my C-code
pid_t pid = fork();
if(pid == 0){ // child
// Child stuff
}else{ // parent
// Parent stuff
}
You might also want to use the
waitpid(pid, NULL, 0);
Parents are always before child. Sort and sweet!!!
fork() creates a copy of the current process which is a part of the process control group. The new process is subordinate to the originating process, for example when a child process dies, SIGCHLD is sent to the parent. Also, the clone is an inferior copy: for instance, any stored getpid() results will be inaccurate in the child; the child has a different parentid, the child has copies of the parent's file descriptors, and has independent resource usage counters.
The parent process, then, is always the one that made the call to fork(), if that's what you mean by run first. If you mean "will the scheduler always give the parent process slices first" then the answer is no.
See: http://gauss.ececs.uc.edu/Courses/c694/lectures/ForksThreads/forks.html, http://linux.die.net/man/2/fork
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char* argv[])
{
pid_t otherPid;
printf("parent pid = %u\n", getpid());
otherPid = fork();
// in the parent, otherPid = the child's (new) process ID
// in the child, otherPid = 0.
switch (otherPid) {
case -1:
printf("Fork failed: %d\n", errno);
return errno;
break;
case 0: // child
sleep(2);
printf("child: my pid is %u\n", getpid());
break;
default:
printf("parent: pid is %u, child should have %u\n", getpid(), otherPid);
sleep(3);
break;
}
return 0;
}

Getting PID of the process created by xdg-open

The situation is the following: I fork the process to open an html file with the default browser. Here is how it looks in my case:
if ((pid=fork())==0) {
execlp("/usr/bin/xdg-open", "xdg-open", url, NULL);
/*if execlp failed, exit the child*/
exit(0);
}
However, I want to get hold of the PID of the process (opened browser), so that I could close it later too. But I do not seem to know how could I get it. Please let me know if you have any suggestions.
You should already have the PID of the child process, the man page of fork() says:
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child.
So in the child process you detect the 0 and run your program, in the parent pid will be the actual PID of the child.
According to your comment what will then happen is that the xdg-open process - who's PID you now now will in turn start a browser and you have no direct access to the PID of that browser process.
At present the only thing I can think of doing is creating yet another child process that you run a command such as ps or pgrep in. You can then parse the output of that command to find the PID of the browser that is running as a child of the xdg-open. There is an example of reading the output of a child process here
fork() returns the pid of the child process to the parent.
In the child you can acquire it's own pid with the standard getpid().
pid_t child_pid = fork();
if (child_pid < 0) {
perror("fork");
// error handling
} else if (!child_pid) {
// child goes here
pid_t my_pid = getpid();
} else {
// parent continues here
}

Understanding how the child process executes in this code

I was given this starter code for a project, but am having difficulty understanding how the child process executes.
int pid ;
int child_info = -1;
if ( argv[0] == NULL ) /* nothing succeeds */
return 0;
if( (pid= fork()==-1)
perror("fork");
else if ( pid == 0 ){
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
execvp(argv[0], argv);
perror("cannot execute command");
exit(1);
}
else { //check if wait error or print out exit status
if ( wait(&child_info) == -1 )
perror("wait");
else {
printf("Exit status: %d, %d\n", child_info>>8, child_info&0377);
}
}
return child_info;
}
Looking at the code, the current process forks and in this case, the child inherits all of the relevant properties of the parent process, since there are no timers, signals or anything involved. However, the pid values of the new processes are in the 18000 range, so how can execvp(argv[0], argv) be executed since in this case, pid != 0.
From the fine manual for fork:
Upon successful completion, fork() shall return 0 to the child process and shall return the process ID of the child process to the parent process.
The first branch of the if is an error condition and will be executed in the parent process if there was an error. The second branch (pid == 0) is executed in the child process, the child does a bit of signal housekeeping and does the exec. The third branch is in the parent when there was no error.
In the parent, pid will be non-zero but in the new child process, pid will be zero.
It gets executed in the child process, where pid will be 0.
http://linux.die.net/man/2/fork
Fork returns the pid of the child to the parent process and 0 to the child process. so when asking for pid == 0 means "is this the child process?". If so, it executes the program passed through command line arguments.
There's only one new process created; the child.
fork() in the child process returns 0, which is what you're checking for.
fork() in the parent process (your original process) returns the child process' pid.
By checking the return of fork() for 0 you know if you're the parent or child; you're the child if it's 0.

What exactly does fork return?

On success, the PID of the child
process is returned in the parent’s
thread of execution, and a 0 is
returned in the child’s thread of execution.
p = fork();
I'm confused at its manual page,is p equal to 0 or PID?
I'm not sure how the manual can be any clearer! fork() creates a new process, so you now have two identical processes. To distinguish between them, the return value of fork() differs. In the original process, you get the PID of the child process. In the child process, you get 0.
So a canonical use is as follows:
p = fork();
if (0 == p)
{
// We're the child process
}
else if (p > 0)
{
// We're the parent process
}
else
{
// We're the parent process, but child couldn't be created
}
p = fork();
/* assume no errors */
/* you now have two */
/* programs running */
--------------------
if (p > 0) { | if (p == 0) {
printf("parent\n"); | printf("child\n");
... | ...
Processes are structured in a directed tree where you only know your single-parent (getppid()). In short, fork() returns -1 on error like many other system functions, non-zero value is useful for initiator of the fork call (the parent) to know its new-child pid.
Nothing is as good as example:
/* fork/getpid test */
#include <sys/types.h>
#include <unistd.h> /* fork(), getpid() */
#include <stdio.h>
int main(int argc, char* argv[])
{
int pid;
printf("Entry point: my pid is %d, parent pid is %d\n",
getpid(), getppid());
pid = fork();
if (pid == 0) {
printf("Child: my pid is %d, parent pid is %d\n",
getpid(), getppid());
}
else if (pid > 0) {
printf("Parent: my pid is %d, parent pid is %d, my child pid is %d\n",
getpid(), getppid(), pid);
}
else {
printf("Parent: oops! can not create a child (my pid is %d)\n",
getpid());
}
return 0;
}
And the result (bash is pid 2249, in this case):
Entry point: my pid is 16051, parent pid is 2249
Parent: my pid is 16051, parent pid is 2249, my child pid is 16052
Child: my pid is 16052, parent pid is 16051
If you need to share some resources (files, parent pid, etc.) between parent and child, look at clone() (for GNU C library, and maybe others)
Once fork is executed, you have two processes. The call returns different values to each process.
If you do something like this
int f;
f = fork();
if (f == 0) {
printf("I am the child\n");
} else {
printf("I am the parent and the childs pid is %d\n",f);
}
You will see both the messages printed. They're being printed by two separate processes. This is they way you can differentiate between the two processes created.
This is the cool part. It's equal to BOTH.
Well, not really. But once fork returns, you now have two copies of your program running! Two processes. You can sort of think of them as alternate universes. In one, the return value is 0. In the other, it's the ID of the new process!
Usually you will have something like this:
p = fork();
if (p == 0){
printf("I am a child process!\n");
//Do child things
}
else {
printf("I am the parent process! Child is number %d\n", p);
//Do parenty things
}
In this case, both strings will get printed, but by different processes!
fork() is invoked in the parent process. Then a child process is spawned. By the time the child process spawns, fork() has finished its execution.
At this point, fork() is ready to return, but it returns a different value depending on whether it's in the parent or child. In the child process, it returns 0, and in the parent process/thread, it returns the child's process ID.
Fork creates a duplicate process and a new process context. When it returns a 0 value it means that a child process is running, but when it returns another value that means a parent process is running. We usually use wait statement so that a child process completes and parent process starts executing.
I think that it works like this:
when pid = fork(), the code should be executed two times, one is in current process, one is in child process.
So it explains why if/else both execute.
And the order is, first current process, and then execute the child.

Resources