#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>

volatile sig_atomic_t shutdown_flag = 0;

void handle_sigint(int sig) {
  shutdown_flag = 1;
}

int main(int argc, char *argv[]) {
  struct sigaction sa;
  sa.sa_handler = handle_sigint;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  sigaction(SIGINT, &sa, NULL);

  FILE *input = stdin;
  int buffer_size = 4096;

  // Parse command line arguments
  // -f filename (optional)
  // b buffer_size (optional)
  char opt;
  while ((opt = getopt(argc, argv, "f:b:")) != -1) {
    switch (opt) {
    case 'f':
      input = fopen(optarg, "r");
      if (input == NULL) {
        fprintf(stderr, "Error: Could not open input file\n");
        return EXIT_FAILURE;
      }
      break;
    case 'b':
      buffer_size = atoi(optarg); break;
    default:
      printf("Usage: %s [-f filename] [-b buffer_size]\n", argv[0]);
      return 1;
    }
  }

  // Allocate buffer
  char *buffer = malloc(buffer_size);

  // Read from input and write to stdout
  while (fgets(buffer, buffer_size, input) != NULL) {
    fwrite(buffer, sizeof(char), strlen(buffer), stdout);

    // Handle shutdown
    if (shutdown_flag) {
      fprintf(stderr, "Cancelled\n");
      return 1;
    }
  }

  // Cleanup
  free(buffer);

  return 0;
}
