#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

typedef struct cmd {
  char **cmd;
  size_t len;

  struct cmd *next;
  struct cmd *prev;
} cmd_t;

int parse(cmd_t *list, int argc, char *argv[]) {
  size_t len = 0;
  while (len < argc && strcmp(argv[len], "//") != 0)
    ++len;
  if (len == 0)
    return -1;
  cmd_t *e = malloc(sizeof(cmd_t));
  e->cmd = malloc(sizeof(char *) * (len + 1));
  e->len = len;

  for (size_t i = 0; i < len; ++i)
    e->cmd[i] = argv[i];
  e->cmd[len] = NULL;

  // tail insert
  e->prev = list->prev;
  e->next = list;
  list->prev->next = e;
  list->prev = e;
  return len + 1;
}

int main(int argc, char *argv[]) {
  cmd_t head = {NULL, 0};
  head.next = &head;
  head.prev = &head;
  if (argc < 2) {
    printf("Usage: %s [...CMD1] // [...CMD2]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  size_t pos = 1, inc = 0;
  while (pos < argc && (inc = parse(&head, argc - pos, &argv[pos])) != -1)
    pos += inc;

  cmd_t *it = head.next;
  while (it != &head) {
    pid_t p;
    switch ((p = fork())) {
    case -1:
      perror("fork");
      exit(EXIT_FAILURE);
      break;
    case 0:;
      // child
      execvp(it->cmd[0], it->cmd);
      break;
    }
    it = it->next;
  }

  while (wait(NULL) > 0)
    ;

  // free
  it = head.next;
  while (it != &head) {
    cmd_t *tmp = it->next;
    free(it->cmd);
    free(it);
    it = tmp;
  }

  exit(EXIT_SUCCESS);
}