Strange Parent ID - c++

I am using two forks in my code:
int main()
{
cout<<"Main Process ID is: "<<getpid()<<endl;
int processID;
processID = fork();
cout<<"Part 1"<<endl;
cout<<"PID is: "<<getpid()<<" Child PID: "<<processID<<" Parent PID: "<<getppid()<<endl;
processID = fork();
cout<<"Part 2"<<endl;
cout<<"PID is: "<<getpid()<<" Child PID: "<<processID<<" Parent PID: "<<getppid()<<endl;
return 0;
}
But there are some strange "Parent ID" for "children". Why? (Please refer to screenshot below)
Thanks a lot in advance.

In your case the parent executed first, hence got eventually terminated. In this case child become orphan and hence it's parent id got replaced with the id of other process in same group or the child got re-parented.Hence, the parent id is different(strange).

Related

waitPID function not checking if the child process exited

I am unable to get the waitPid to tell me if the child process exited or not.
In the parent process this is what I am doing:
if (forkID != 0) {
pid_t result = waitpid(forkID, &status, WNOHANG);
if (result == 0) {
// Child still alive
std::cout<<"Child Alive"<<std::endl;
} else if (result == -1) {
// Error
std::cout<<"Error"<<std::endl;
} else {
// Child exited
std::cout<<"Child Exited"<<std::endl;
}
DriverParser P;
while (!std::cin.eof()) {
std::string line;
std::getline(std::cin, line);
arguments = P.BeginParsing(line);
if (arguments.size() > 0) {
for (int k = 0; k < 4; k++) {
finalArguments[k] = arguments[k];
}
close(fd[0]);
write(fd[1],finalArguments,4*sizeof(int));
close(fd[1]);
}
}
// pid = wait(&status);
// std::cout<<waitpid(forkID, &status, 0)<<std::endl;
}else if (forkID == 0) {
// child: reading only, so close the write-descriptor
std::cout<<"I am child process my PID is: "<<getpid()<<std::endl;
execv("./a.out", argList);
// close the read-descriptor
close(fd[0]);
}
I am basically sending the result of the parser as it reads from the stdin via pipe to child process, and then executing a process in execv. Now when this program exits using exit(0) - I am not seeing Child Exited on the terminal which means the waitpid is essentially not working for me.
What should I do?
You are calling waitpid with WNOHANG:
pid_t result = waitpid(forkID, &status, WNOHANG);
I shared with you the documentation, which says:
If WNOHANG was specified in options and there were no children in a waitable state, then waitid() returns 0 immediately and the state of the siginfo_t structure pointed to by infop is unspecified. To distinguish this case from that where a child was in a waitable state, zero out the si_pid field before the call and check for a nonzero value in this field after the call returns.
It also says:
WNOHANG
return immediately if no child has exited.
Considering that the call to waitpid happens immediately after fork, the chances are that the child is still running.
If you want to wait for the child process to end, just remove the WNOHANG option (pass 0 instead):
pid_t result = waitpid(forkID, &status, 0);

When a child process is created with fork, the parent ID is not as the same as the parent ID [duplicate]

This question already has answers here:
Why getppid() from the child return 1
(2 answers)
Closed 6 years ago.
In order to explain the question I'm asking let's consider this code,
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t child, parent;
parent = getpid();
printf("Main parent pid: %d\n",parent );
if((child = fork()) < 0) {
printf("Error\n");
} else if(child == 0 ) {
printf("A Child process is created, pid: %d, ppid: %d \n",
getpid(), getppid());
} else if(child > 0) {
printf("Parent says: Child pid: %d, getpid: %d, getppid: %d\n",
child, getpid(), getppid());
}
return 0;
}
When I execute this code on terminal I get such an output
Main pid: 711
Parent says: Child pid: 712, getpid: 711, getppid: 598
A Child process is created, pid: 712, ppid: 1
As far as I understand, when I'm creating a new process by forking from a already created process, the parent of this new process must the process that I have forked.Hovewer, as you can see from the output, the parent process ID of the child is 1, i.e the init process, so why is that so ? Is my understand wrong, or there is some other things that I'm not seeing ?
Note: I'm working on Mac OSX.
The problem is that the parent process (711) has died and the child process inherited by the init process (1) before it gets to report. If you have the parent wait for the child to die before exiting itself, you'll see the result you expect.
To demonstrate:
#include <sys/wait.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
pid_t child, parent;
parent = getpid();
printf("Main parent pid: %d\n", (int)parent);
if ((child = fork()) < 0)
{
printf("Error\n");
}
else if (child == 0)
{
printf("A Child process is created, pid: %d, ppid: %d\n",
(int)getpid(), (int)getppid());
}
else if (child > 0)
{
printf("Parent says: Child pid: %d, getpid: %d, getppid: %d\n",
(int)child, (int)getpid(), (int)getppid());
#ifndef DO_NOT_WAIT_FOR_CHILD
int status;
int corpse = wait(&status);
printf("Child %d exited with status 0x%.4X\n", corpse, status);
#endif
}
return 0;
}
When compiled without -DDO_NOT_WAIT_FOR_CHILD, I got the sample output:
Main parent pid: 77646
Parent says: Child pid: 77647, getpid: 77646, getppid: 46383
A Child process is created, pid: 77647, ppid: 77646
Child 77647 exited with status 0x0000
When compiled with -DDO_NOT_WAIT_FOR_CHILD, I got the sample output:
Main parent pid: 77662
Parent says: Child pid: 77663, getpid: 77662, getppid: 46383
A Child process is created, pid: 77663, ppid: 1

Hung parent while reading stderr from child process through pipe in C++

I fork a child process which in turn spawns a grand-child process and returns. If there are any errors in spawning that grand-child, the child writes to stderr using fprintf statements and exits.
I am trying to read stderr from the child process in the parent. But, the parent gets hung in the while loop reading from child process. When I look at ps -ef the child is <defunct>.
Following is the code I wrote to accomplish this. I am new to this and the search on web does not give enough information about why the parent is hung when the child is
int pipe_out[2];
// Create the pipe
if (pipe(pipe_out) < 0) {
perror("Failed pipe");
exit(1);
}
// Create the child process
int status;
pid_t pid = fork();
switch(pid) {
case -1:
perror("Failed fork");
exit(1);
case 0: { // Child
close(pipe_out[0]); // close read end
// Make stderr go to pipe write end
dup2(pipe_out[1], STDERR_FILENO);
close(pipe_out[1]);
// start my process
execvp(inp_args[0], inp_args);
_exit(EXIT_FAILURE);
break;
}
default: { // Parent
close(pipe_out[1]); // close write end
// read from child
while( read(pipe_out[0], buffer, sizeof(buffer)) )
log(stdout, "%s\n",buffer);
}
// wait for end then close other end of pipe
waitpid(pid, &status, 0);
if (WIFSIGNALED(status))
log(stdout, "killed by signal %d\n", WTERMSIG(status));
close(pipe_out[0]);
}
}

Cannot detect if child process has been killed

I been reading a countless time on stackoverflow that to determine if a process is running, one should use kill(pid,0) but I cant make it work
here is my code, , it cannot detect when the child process has been killed and I dont understand why
(sorry for the ident, but hte code escaping on stackoverflow is just a pain for long pieces of codes)
#include <sys/signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main()
{
int pid = fork();
if (pid < 0)
{
printf("Forking failed\n");
}
else if (pid == 0) // child process
{
do
{
printf("child process\n");
sleep(1);
}while(1);
//execvp("ls", NULL); //launches the application
}
else //parent process
{
printf("parent process\n");
for(int i=0;i<10;i++)
{
if(i==5)
kill(pid,SIGTERM); //kills the child process
if(kill(pid, 0) == 0)
printf("process child %d is runnig\n",pid);
else if(kill(pid, 0) == -1)
{
switch(errno)
{
case ESRCH: printf("process child %d is not runnig\n",pid); break;
case EPERM: printf("process child %d cannot be killed\n",pid); break;
default: printf("%s\n",strerror(errno)); break;
}
}
sleep(1);
}
}
}
here is the output
parent process
process child 1918 is runnig
child process
process child 1918 is runnig
child process
process child 1918 is runnig
child process
process child 1918 is runnig
child process
process child 1918 is runnig
child process
process child 1918 is runnig
process child 1918 is runnig
process child 1918 is runnig
process child 1918 is runnig
process child 1918 is runnig
Until the killed child process gets reaped by wait(), its PID is still valid, and kill(pid, 0); will succeed, since the PID exists. Your code attempts to kill() the child process, but fails to wait() for it.
Note that even in the best case, kill(pid, 0); is not reliable. With only 32766 different PIDs, it doesn't take long before process IDs get recycled.
alright I finaly figured it out
kill(pid,SIGTERM); //kills the child process
do
{
pid = waitpid(-1, NULL, WNOHANG);
if(pid == 0)
sleep(1);
}while(pid<=0);

how to kill parent and child process through shell?

I have an application which is initiated by the shell and terminated by the shell. Now in my application I had created a fork to reduce the load of my application so currently two processes running on same name with different PID's. Now I want to terminate my program, and if I kill with the PID of my process in shell it only kills the parent process leaving it as a zombie process and the child process remains. So how to kill both child and parent processes through the shell?
See the command killall.
do ps -el you will get the following
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
get pid and ppid of your process do pkill -P <parent_pid_name> meaning your parent process id which has spawned children and followed by kill <signal number> <pid> In this case too, in place of pid you have to give the parent process id who has spawned all the children .
Your father process should trap SIGTERM and kill its child before exit.
I wrote this in C
int child;
void sighandler(int sig) {
if (sig == SIGTERM) {
if (child != -1) kill(child, SIGTERM);
}
}
int main() {
int i;
child = -1;
signal(SIGCHLD, SIG_IGN);
signal(SIGTERM, sighandler);
setsid();
setpgid(0,0);
i = fork();
switch(i) {
case -1:
break;
case 0: // child
sleep (100);
break;
default:
child = i;
sleep (100);
break;
}
return 0;
}
You can kill all processes with the same name with the "killall" command.
pkill command you can use to kill process. Also killall