#include <cstdio>
#include <unistd.h>
#include <sstream>
#include <vector>
#include <cerrno>
#include <cstring>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
fprintf(stderr,"main entered with pid: %d\n",getpid());
if(argc==1) // parent has only binary name as argument (else logic to tell command lines apart)
{
pid_t pid = fork();
if(pid) // parent
{
fprintf(stderr,"parent %d knows child at pid %d\n",(int)getpid(),(int)pid);
fprintf(stderr,"parent's argv[0]: %s\n",argv[0]);
waitpid(pid,nullptr,0); // wait for child to finish
}
else // child
{
pid = getppid();
fprintf(stderr,"child %d knows parent at pid %d\n",(int)getpid(),(int)pid);
std::ostringstream path_strm;
path_strm << "/proc/" << pid << "/exe"; // path to parent's binary (symlink)
// TODO: in advanced usage you may need to clean up certain
// system resources here so that the child does not continue to inherit
// them .. close open files, etc
std::string path = path_strm.str();
fprintf(stderr,"exec of %s\n", path.c_str());
execvp(path.c_str(), std::vector<char *>({
// note: cast away const-ness
(char *)path.c_str(),
(char *)"arg1",
nullptr}).data()); // nullptr marks the end of the args
// this line never reached unless there was an error, child starts at main() again
// errno is a global used for error reporting by certain system/library calls
fprintf(stderr,"execv error: %d (%s)\n", errno, strerror(errno));
}
}
else // child after execv
{
fprintf(stderr,"child %d has argv:\n",(int)getpid());
for(int i=0; i<argc; i++)
fprintf(stderr,"argv[%d]: %s\n", i, argv[i]);
}
return 0;
}
To embed this project on your website, copy the following code and paste it into your website's HTML: