Skip to content

Instantly share code, notes, and snippets.

@hqhs
Last active May 3, 2021 12:11
Show Gist options
  • Save hqhs/29349126a9a8671550860b4a756da395 to your computer and use it in GitHub Desktop.
Save hqhs/29349126a9a8671550860b4a756da395 to your computer and use it in GitHub Desktop.
wait child process to receive signal
/**
Author: Dmitry Afanasyev
Compiler version:
gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Compile:
gcc main.c -o test && ./test
PHP version:
php --version
PHP 7.4.3 (cli)
Full test suite:
$ cat actual-work.php
<?php
pcntl_alarm(5);
echo "alarm() call executed\n";
for ($i = 0; $i < 10; $i++) {
echo "doing actual work in php script\n";
sleep(1);
}
$ gcc main.c -o test
$ ./test > log.txt
$ cat log.txt
alarm() call executed
doing actual work in php script
doing actual work in php script
doing actual work in php script
doing actual work in php script
doing actual work in php script
WATCHDOG DEBUG parent waits child to change it's status...
WATCHDOG ERROR child exited by receiving signal: 14
*/
#include <sys/wait.h> // wait
#include <unistd.h> // alarm
#include <stdio.h> // printf
int main()
{
pid_t child;
int status;
child = fork();
if (child < 0)
{
// error, no child process created,
printf("WATCHDOG ERROR failed to create child process, exiting...\n");
return -1;
} else if (child == 0)
{
// I'm the child now
// NOTE: if you want to add arguments to script, just add them to array, e.g.: {"/foo/bar/baz" , "-foo" , "-bar" , NULL};
// ALSO NOTE: all paths MUST be absolute, obviously, on your system paths would be different
const char *arguments[64] = {"/usr/bin/php", "/home/dmitry/fun/ar-help/actual-work.php", NULL};
printf("WATCHDOG DEBUG calling php script...\n");
// system() call is considered problematic, exec* family is better
if (-1 == execve(arguments[0], (char **) arguments, NULL))
{
printf("WATCHDOG ERROR execve() script failed, exiting...");
return -1;
}
} else
{
// I'm the parent now
printf("WATCHDOG DEBUG parent waits child to change it's status...\n");
wait(&status);
if (WIFEXITED(status))
{
// child exited normally, calling exit(3)
printf("WATCHDOG INFO child finished normally\n");
} else if (WIFSIGNALED(status))
{
// child exited by receiving signal
int signal_id = WTERMSIG(status);
printf("WATCHDOG ERROR child exited by receiving signal: %d\n", signal_id);
}
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment