
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <semaphore.h>

static void usage(const char *prog_name) {
    fprintf(stderr, "usage: %s [-a]\n", prog_name);
    exit(1);
}

void do_something(void) {
    printf("Hello World!\n");
    void *mem = malloc(123);
    if (mem == NULL) {
        fprintf(stderr, "Unable to malloc: %s\n", strerror(errno));
        exit(1);
    }
    printf("%p\n", mem);
    free(mem);
}

void do_sem(void) {

    sem_t sem;
    sem_init(&sem, 0, 1);

    sem_post(&sem);

    while (sem_wait(&sem) == -1) {
        if (errno != EINTR) {
            fprintf(stderr, "Unable to sem_wait: %s\n", strerror(errno));
            exit(1);
        }
    }

    for (int i = 0; i < 8; i++) {
        if (i & 1) {
            sem_post(&sem);
        } else {
            sem_post(&sem);
        }
    }

    do_something();

    sem_wait(&sem);

    do_something();

    sem_destroy(&sem);

}

int main(const int argc, char *const argv[]) {
    for (int ch; (ch = getopt(argc, argv, "a")) != -1;) {
        switch (ch) {
            case 'a':
                break;
            default:
                usage(argv[0]);
        }
    }
    if (optind != argc)
        usage(argv[0]);

    do_something();
    do_something();
    do_something();
    do_sem();
}
