Skip to content

Instantly share code, notes, and snippets.

@ADKaster
Created February 29, 2020 08:02
Show Gist options
  • Save ADKaster/e157ce4efdd66dd312927b22a129ae3a to your computer and use it in GitHub Desktop.
Save ADKaster/e157ce4efdd66dd312927b22a129ae3a to your computer and use it in GitHub Desktop.
Waiter program that waits on a sleeping child (Serenity only)
#include <AK/Assertions.h>
#include <AK/LogStream.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_NOT_REACHED();
}
int wstatus = 0;
int options = atoi(argv[2]);
do {
int rc = waitpid(child, &wstatus, options);
if (rc < 0 && errno != EINTR) {
if (errno != ECHILD)
perror("waitpid");
break;
}
if (WIFEXITED(wstatus)) {
if (WEXITSTATUS(wstatus) != 0)
dbg() << "waiter : sleep(" << child << ") exited with status " << WEXITSTATUS(wstatus);
} else if (WIFSTOPPED(wstatus)) {
fprintf(stderr, "watier: 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 {
printf("waiter: sleep(%d) exited abnormally\n", child);
}
}
} while (errno == EINTR);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment