Can someone please clarify the definition of related and unrelated processes?
I know that fork creates two related processes
fork()
However, I am not sure whether the process is still considered related when we call exec* family functions to replace program image:
if (child) {
exec("path to binary", ...) <- Is it still related process
}
The reason I am asking is to clarify which IPC method can be used in which scenario. For instance, pipes
are only allowed between related processes. So I am asking above to clarify whether new program that I wrote, probably with different language, can access to the pipe file descriptors or not.
Can we say that any process created with fork() regardless of whether exec or original program image is used is always related and all others are unrelated?
Thanks!
ref: mark mitchell: advanced linux programming
A call to pipe creates file descriptors, which are valid only within that process and its children. A process’s file descriptors cannot be passed to unrelated processes; however, when the process calls fork, file descriptors are copied to the new child process.Thus, pipes can connect only related processes.
Can we say that any process created with fork() regardless of whether exec or original program image is used is always related?
Yes, we can.
Regardless of whether you call exec in child, parent and child processes can still talk to each other using pipes. See below example of creating child process, which will change itself into echo and then parent can still read its echo argument.
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <assert.h>
int main() {
int filedes[2];
int const pipeRes = ::pipe(filedes);
assert(pipeRes != -1) ;
pid_t pid = ::fork();
assert(pid != -1);
if (pid == 0) // child code
{
// connect the entrance of the pipe to STDOUT_FILENO within the child process
while ((::dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
// close both input and output of new pipe in child process
close(filedes[1]);
close(filedes[0]);
execl("/bin/echo", "echo", "child-says-hello", (char*)0);
assert(false); // execl failed
}
// parent code
close(filedes[1]); // close input of new pipe in parent, it will only read from it
char buffer[1024];
while (1)
{
ssize_t count = read(filedes[0], buffer, sizeof(buffer));
if (count == -1)
{
if (errno == EINTR) continue;
else assert(false);
}
else if (count == 0)
{
// read everything
break;
}
else
{
std::cout << "received count:" << count << " bytes with: " << buffer << "\n";
}
}
close(filedes[0]);
wait(0);
return 0;
}
The output is
eceived count:17 bytes with: child-says-hello
Code example above was based on this tutorial.