when I do
pid_t pid = fork();
...
if (pid == 0)
execvp(...);
...
if (pid > 0) {
kill(pid, SIGTERM);
}
it kills the child , that's okay , but it kills parent process too (not sure that is important but parent process has custom sig handlers) .
is it right behavior ? or I do something wrong? how to prevent a killing of parent process?
expected logic is to stop the child if parent doesn't receive some notifications during predefined time range. then run new child instance again
It works fine for me:
int main(void)
{
pid_t child_pid = fork();
if (child_pid == -1)
{
perror("fork failed");
exit(1);
}
else if (child_pid == 0)
{
// In the child process
printf("Child process started with PID %d\n", getpid());
while (1)
{
printf("Child is running...\n");
fflush(stdout);
usleep(1000);
}
}
else
{
// In the parent process
printf("Parent process with PID %d created child with PID %d\n", getpid(), child_pid);
fflush(stdout);
// Give the child some time to run
usleep(35000);
// Terminate the child process
printf("Parent is killing the child process...\n");
kill(child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
printf("Child process terminated. Parent continues...\n");
// The parent process continues running
}
return 0;
}
https://godbolt.org/z/G7YzqsvYn
Try also this for testing. It does not work on Godbolt - most likely it does not allow the execution of other programs.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
int main(void)
{
pid_t child_pid = fork();
if (child_pid == -1)
{
perror("fork failed");
exit(1);
}
else if (child_pid == 0)
{
printf("Child process (PID %d) locating 'sleep' command...\n", getpid());
int pipefd[2];
if (pipe(pipefd) == -1)
{
perror("pipe failed");
exit(1);
}
pid_t which_pid = fork();
if (which_pid == -1)
{
perror("fork failed");
exit(1);
}
if (which_pid == 0)
{
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
execlp("which", "which", "sleep", (char *)NULL);
perror("whick execlp failed");
exit(1);
}
else
{
close(pipefd[1]);
waitpid(which_pid, NULL, 0);
char sleep_path[256];
ssize_t bytes_read = read(pipefd[0], sleep_path, sizeof(sleep_path) - 1);
if (bytes_read > 0)
{
sleep_path[bytes_read] = '\0';
printf("Location of 'sleep': %s", sleep_path);
}
else
{
perror("failed to read from pipe");
}
close(pipefd[0]);
sleep_path[strcspn(sleep_path, "\n")] = '\0'; // Trim newline
char *args[] = { sleep_path, "10", NULL };
printf("Path: %s\n", args[0]);
execvp(args[0], args);
perror("execvp failed");
exit(1);
}
}
else
{
printf("Parent process (PID %d) created child (PID %d)\n", getpid(), child_pid);
sleep(3);
printf("Parent is sending SIGTERM to child...\n");
kill(child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
printf("Child process terminated. Parent continues...\n");
}
return 0;
}
I can confirm - it works (I just added printing paths to found sleep):
Parent process (PID 6017) created child (PID 6028)
Child process (PID 6028) locating 'sleep' command...
Location of 'sleep': /usr/bin/sleep
Path: /usr/bin/sleep
Parent is sending SIGTERM to child...
Child process terminated. Parent continues...