/*
* Compile instructions (your choice):
* gcc nowinch.c -o nowinch
* clang nowinch.c -o nowinch
*
* Originally written to deal with gunicorn inside tmux: gunicorn kills worker
* processes when it receives a SIGWINCH, and tmux sends these whenever the
* window size changes.
*
*/
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <unistd.h>
void usage() {
fprintf(stderr, "Usage: [--help | -h] [--quiet | -q] <command> [arg [ arg ... ]\n\n");
fprintf(stderr, "This is a wrapper command that suppresses SIGWINCH signals.\n\n");
fprintf(stderr, "When you run 'nowinch somecommand arg1 arg2' the wrapper will launch\n");
fprintf(stderr, "`somecommand` with all the given argments while intercepting SIGWINCH\n");
fprintf(stderr, "signals: they will not reach your program.\n");
}
void terminate_with_missing_command() {
usage();
fprintf(stderr, "\nProblem: Missing command\n");
exit(1);
}
int main(int argc, char **argv)
{
if (argc <= 1) terminate_with_missing_command();
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
usage();
exit(0);
}
bool quiet = false;
int command_offset = 1;
if (strcmp(argv[1], "--quiet") == 0 || strcmp(argv[1], "-q") == 0) {
quiet = true;
command_offset++;
}
if (command_offset >= argc) terminate_with_missing_command();
if (!quiet) fprintf(stderr, "<< SIGWINCH will be ignored from now on >>\n");
char **cmd = argv + command_offset;
sigset_t sigset;
sigemptyset (&sigset);
sigaddset(&sigset, SIGWINCH);
sigprocmask(SIG_BLOCK, &sigset, NULL);
if (execvp(*cmd, cmd) == -1) {
fprintf(stderr, "There was a problem spawning your program: error code %i\n", errno);
exit(1);
}
}