/* * 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); } }