Skip to content

Instantly share code, notes, and snippets.

@ADKaster
Last active March 1, 2020 18:54
Show Gist options
  • Save ADKaster/38f0f1cac4f63d1de1e28d40d91a7c98 to your computer and use it in GitHub Desktop.
Save ADKaster/38f0f1cac4f63d1de1e28d40d91a7c98 to your computer and use it in GitHub Desktop.
Waiter program that waits on a sleeping child
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
extern char** environ;
int main(int argc, char* argv[])
{
if (argc != 3) {
puts("Usage: waiter <seconds to wait on child> <options>");
return 1;
}
char* fake_argv[] = {const_cast<char*>("/bin/sleep"), argv[1], nullptr};
pid_t child = fork();
if (!child) {
int rc = execve(fake_argv[0], const_cast<char* const*>(fake_argv), environ);
if (rc < 0) {
if (errno == ENOENT)
fprintf(stderr, "%s: Command not found.\n", argv[0]);
else
fprintf(stderr, "execvp(%s): %s\n", argv[0], strerror(errno));
_exit(1);
}
assert(false);
}
int wstatus = 0;
int options = atoi(argv[2]);
while(true) {
int rc = waitpid(child, &wstatus, options);
if (rc < 0 && errno != EINTR) {
if (errno != ECHILD)
perror("waitpid");
break;
}
if (WIFEXITED(wstatus)) {
if (WEXITSTATUS(wstatus) != 0)
printf("waiter : sleep(%d) exited with status %d", child, WEXITSTATUS(wstatus));
} else if (WIFSTOPPED(wstatus)) {
fprintf(stderr, "waiter: sleep(%d) stoped with signal %s\n", child, strsignal(WSTOPSIG(wstatus)));
} else {
if (WIFSIGNALED(wstatus)) {
printf("waiter: sleep(%d) exited due to signal '%s'\n", child, strsignal(WTERMSIG(wstatus)));
} else {
// Should use WIFCONTINUED but that's not supported in serenity :(
//printf("waiter: sleep(%d) %s\n", child, WIFCONTINUED(wstatus) ? "continued" : "funny business");
printf("waiter: sleep(%d) something else happened\n", child);
}
}
sleep(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment