Skip to content

Instantly share code, notes, and snippets.

@mscdex
Last active January 6, 2026 20:53
Show Gist options
  • Select an option

  • Save mscdex/c175bc9afb2b9aa1f249c50dde0ff1fa to your computer and use it in GitHub Desktop.

Select an option

Save mscdex/c175bc9afb2b9aa1f249c50dde0ff1fa to your computer and use it in GitHub Desktop.
Check if the process identified by a passed pidfd is still alive with node.js
'use strict';
// The pidfd fd passed to this process
const pidfd = 3;
const { openSync, read } = require('fs');
const { join } = require('path');
const RE_PID = /(?:^|\n)Pid:[ \t]*([-0-9]+)/;
const sleep = (t) => new Promise((resolve, reject) => setTimeout(resolve, t));
(async() => {
const procfd = openSync(join('/proc/self/fdinfo', pidfd.toString()));
const isProcessAlive = (() => {
const buffer = Buffer.allocUnsafe(512);
const options = {
buffer,
offset: 0,
length: buffer.length,
position: 0,
};
const executor = (resolve, reject) => {
read(procfd, options, (err, nb, buf) => {
if (err)
return reject(err);
const m = RE_PID.exec(buf.latin1Slice(0, nb));
if (!m)
return reject(new Error('Non-pidfd file descriptor'));
resolve(m[1] !== '-1');
});
};
return () => new Promise(executor);
})();
// ...
for (;;) {
if (await isProcessAlive()) {
console.log('process alive');
} else {
console.log('process dead');
break;
}
await sleep(1000);
}
})();
#define _GNU_SOURCE
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static int pidfd_open(pid_t pid, unsigned int flags) {
return syscall(SYS_pidfd_open, pid, flags);
}
int main(int argc, char *argv[]) {
int pidfd;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
exit(EXIT_SUCCESS);
}
pidfd = pidfd_open(atoi(argv[1]), 0);
if (pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
pid_t child_pid;
char* child_argv[] = {"node", "node.js", NULL};
posix_spawn_file_actions_t file_actions;
if (posix_spawn_file_actions_init(&file_actions) != 0) {
perror("posix_spawn_file_actions_init");
exit(EXIT_FAILURE);
}
if (posix_spawn_file_actions_adddup2(&file_actions, pidfd, 3) != 0) {
perror("posix_spawn_file_actions_adddup2");
exit(EXIT_FAILURE);
}
int status = posix_spawnp(
&child_pid, "node", &file_actions, NULL, child_argv, environ
);
if (status == 0) {
printf("Child process spawned with PID: %i\n", child_pid);
if (waitpid(child_pid, &status, 0) != -1) {
printf("Child exited with status %i\n", WEXITSTATUS(status));
} else {
perror("waitpid");
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr, "posix_spawn error: %s\n", strerror(status));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
`gcc -O2 parent.c -o parent`
<spawn a process to monitor>
`./parent <monitored process pid>`
<kill monitored process>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment