I am creating a child process with fork in my shell, and assigned this child process to execute a cmd, for example : "ls -lR /", with 'execve()' like u see in my code, when i receive SIGTSTP, i want to stop this child process with kill(child_process, SIGTSTP)
, and when you type "fg" command i have to reset this child runing with kill(child_process, SIGCONT)
, problem is wait(&status)
after i receive SIGTSTP never return is still waiting child to end,
-- so how i can do that ??
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int child_pid;
int parn_pid;
void func1(int sig)
{
kill(child_pid, SIGTSTP);
}
int main()
{
int sig;
int status;
char *argv[] = {"ls", "-lR", "/", NULL};
signal(SIGTSTP, func1);
child_pid = fork();
if (child_pid == 0)
{
child_pid = getpid();
execve("/bin/ls", argv, NULL);
exit (1);
}
else
{
parn_pid = getpid();
waitpid(child_pid, &status, WUNTRACED);
printf("\nsuspended\n");
if (WIFSTOPPED(status))
{
sleep(2);
kill(child_pid, SIGCONT);
wait(&status);
}
}
return (0);
}
You need to use waitpid()
rather than wait()
. Using wait()
will wait for a child process to be terminated, which means the processes must have exited, for example from SIGKILL or SIGSEGV. You are trying to wait for the process to be stopped, which is not the same thing. Stopping a process just pauses it and it allows it to be continued later. It doesn't exit.
You need to use the WUNTRACED
flag with waitpid()
to wait for a child processes to be terminated or stopped. Such as waitpid(child_pid, &status, WUNTRACED)
or waitpid(-1, &status, WUNTRACED)
.
There is another flaw related to this. WIFSIGNALLED()
and WTERMSIG()
also apply only to a processing which was terminated by a signal. You should instead use WIFSTOPPED()
and WSTOPSIG()
to detect if the child was stopped.
Also note:
SIGSTOP
can also stop a processes.SIGTSTP
anytime after the signal handler is set, which could be before child_pid
is assigned a value.wait()
and friends can return -1 with errno
set to EINTR
if your processes is interrupted by a signal.