Skip to content

Instantly share code, notes, and snippets.

@vrs
Last active May 30, 2018 17:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vrs/8c2cb7509e404da67d12 to your computer and use it in GitHub Desktop.
Save vrs/8c2cb7509e404da67d12 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
int forkstatus;
int exitstatus = 0;
void catch_sigterm () {
if (forkstatus != 0)
kill(0, SIGTERM);
_exit(exitstatus);
}
int main (int argc, char *const argv[]) {
if (argc < 3) {
printf("usage: spawnwithpid <pid> <cmd>\n");
return 1;
}
int wantpid = atoi(argv[1]);
if (!(0 < wantpid && wantpid < 32768)) { // ignoring pid_max
printf("invalid pid %s.\n", argv[1]);
return 2;
}
// note: if we get lucky on the first try, we actually won't succeed
// too lazy to fix this
int procstatus = kill(wantpid, 0);
if (!(procstatus == -1 && errno == ESRCH)) {
printf("pid already taken or other error. (%s)\n", argv[1]);
return 3;
}
signal(SIGTERM, catch_sigterm);
// spawn children until pid is hit, then exit
// children: wait until parent exits
do {
forkstatus = fork();
} while (forkstatus > 0 && forkstatus != wantpid);
if (forkstatus == -1) {
// common problems
if (errno == EAGAIN) {
// observation: linux seems to stop spawning short of full exhaustion,
// making this fail every second call during debugging
printf("could not fork anymore, reason: out of pids (EAGAIN). Retrying usually helps.\n");
exitstatus = 5;
kill(0, SIGTERM);
} else {
printf("could not fork for unexpected reason %d\n", errno);
exitstatus = 4;
kill(0, SIGTERM);
}
} else if (forkstatus == 0) {
// children
if (wantpid == getpid()) {
// success
printf("got pid %d!\n", wantpid);
setsid();
kill(getppid(), SIGTERM);
execvp(argv[2], &argv[2]);
} else {
// dud
pause();
}
} else if (forkstatus == wantpid) {
// parent
pause();
}
return 99;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment