Your understanding of getpid
is correct, it returns the PID of the running process.
waitpid
is used (as you said) to block the execution of a process (unless
WNOHANG
is passed) and resume execution when a (or more) child of the process
ends. waitpid
returns the pid
of the child whose state has changed, -1 on
failure. It also can return 0 if WNOHANG
has specified but the child has not
changed the state. See:
man waitpid
RETURN VALUE
waitpid()
: on success, returns the process ID of the child whose state has changed; if WNOHANG
was specified and one or more child(ren) specified by pid exist, but have not yet changed state,
then 0 is returned. On error, -1 is returned.
Depending on the arguments passed to waitpid
, it will behave differently. Here
I'l quote the man page again:
man waitpid
pid_t waitpid(pid_t pid, int *wstatus, int options);
...
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 modifiable
via the options argument, as described below:
The value of pid can be:
< -1
: meaning wait for any child process whose process group ID is equal to the absolute value of pid
.
-1
: meaning wait for any child process.
0
: meaning wait for any child process whose process group ID is equal to that of the calling process.
> 0
: meaning wait for the child whose process ID is equal to the value of pid.
The value of options
is an OR of zero or more of the following constants:
WNOHANG
: return immediately if no child has exited.
WUNTRACED
also return if a child has stopped (but not traced via ptrace(2)).
Status for traced children which have stopped is provided even if this option is not specified.
WCONTINUED
(since Linux 2.6.10) also return if a stopped child has been resumed by delivery of SIGCONT
.
I'm a little unsure as to how waitpid() manages all this
waitpid
is a syscall and the OS handles this.
How does this change depending on whether or not a parent or child calls it, and whether or not a child process is still running, or has terminated?
wait
should only be called by a process that has executed fork()
. So the parent
process should cal wait()
/waitpid
. If the child process hasn't called
fork()
, then it doesn't need to call either one of these functions. If however
the child process has called fork()
, then it also should call
wait()
/waitpid()
.
The behaviour of these function is very well explained in the man page, I quoted the important parts of it. You should read the whole man page
to get a better understanding of it.