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