Skip to content

Instantly share code, notes, and snippets.

@spraints
Last active September 18, 2024 18:28
Show Gist options
  • Save spraints/5f07f32c0d41789cdfafb7ea819f5cbb to your computer and use it in GitHub Desktop.
Save spraints/5f07f32c0d41789cdfafb7ea819f5cbb to your computer and use it in GitHub Desktop.
Miscellanous little test programs
sigset-die
sigset-live
all: sigset-die sigset-live
sigset-die: sigset.c
cc -o $@ -D DIE_ON_SIGUSR1 $<
sigset-live: sigset.c
cc -o $@ $<
// Synopsis:
// $ make
// $ ./sigset-live
// $ kill -USR1 (either of the pids shown)
// ==> both processes survive
// $ ./sigset-die
// $ kill -USR1 (pid)
// ==> process dies
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <spawn.h>
#include <string.h>
#include <stddef.h>
char **environ;
void setupsigmask()
{
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
}
static void *sig_thread(void *arg)
{
const char *msg = arg;
int s, sig;
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGUSR1);
for (;;) {
s = sigwait(&signal_mask, &sig);
if (s != 0)
{
printf("error: %d\n", s);
exit(1);
}
printf("%s: got signal %d\n", msg, sig);
}
}
char *make_exe_path(char *this_exe, char *other_exe_name)
{
char *other_exe;
ptrdiff_t dirnamelen, otherexelen;
char *slash;
slash = strrchr(this_exe, '/');
if (!slash) {
return other_exe_name;
}
dirnamelen = slash - this_exe;
otherexelen = strlen(other_exe_name);
other_exe = malloc(dirnamelen + otherexelen + 2);
memcpy(other_exe, this_exe, dirnamelen);
other_exe[dirnamelen] = '/';
memcpy(&other_exe[dirnamelen+1], other_exe_name, otherexelen);
other_exe[dirnamelen + 1 + otherexelen + 1] = '\0';
return other_exe;
}
void main(int argc, char *argv[])
{
pthread_t thread;
pid_t child_pid;
char *child_argv[2];
char *child_exe;
printf("pid: %d\n", getpid());
// When setupsigmask happens first, USR1 will not kill this process.
// When the child thread is spawned first, USR1 will kill this process.
#ifndef DIE_ON_SIGUSR1
setupsigmask();
#endif
pthread_create(&thread, NULL, &sig_thread, "thread");
#ifdef DIE_ON_SIGUSR1
setupsigmask();
#else
child_exe = make_exe_path(argv[0], "sigset-die");
child_argv[0] = child_exe;
child_argv[1] = NULL;
printf("(spawn %s)\n", child_exe);
posix_spawnp(&child_pid, child_exe, NULL, NULL, &child_argv[0], environ);
#endif
pause();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment