diff --git a/exercises/chapter1-exo1-ping.c b/exercises/chapter1-exo1-ping.c new file mode 100644 index 0000000..9201ee8 --- /dev/null +++ b/exercises/chapter1-exo1-ping.c @@ -0,0 +1,76 @@ +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <sys/wait.h> +#include <time.h> +#include <stdlib.h> + +#define BILLION 1000000000L +#define MILLION 1000000L +#define THOUSAND 1000L + +void get_time_ts(struct timespec *t0) { + if (clock_gettime(CLOCK_REALTIME, t0) == -1) { + perror("clock_gettime"); + exit(1); + } +} + +long long duration_ns(struct timespec t0, struct timespec t1) { + return ((t1.tv_sec - t0.tv_sec)*BILLION) + (t1.tv_nsec - t0.tv_nsec); +} + +void print_time_ns(long long time) { + printf("%llds %lldms %lldĀµs %lldns\n" + , time/BILLION + , (time/MILLION)%THOUSAND + , (time/THOUSAND)%THOUSAND + , time%THOUSAND + ); +} + +#define BUFSIZE 1024 +int main (int argc, char **argv) { + struct timespec t0, t1; + long long duration; + long long max_duration = 0; + + int parent_to_child[2]; + int child_to_parent[2]; + + if ( -1 == pipe(parent_to_child) ) return 1; + if ( -1 == pipe(child_to_parent) ) return 1; + + char msg1[] = "ping"; + char bufchild[BUFSIZE] = {0} ; + int nbytes; + + int pid = fork(); + switch ( pid ) { + case -1: return 2; + case 0: /*child*/ + close(child_to_parent[0]); + close(parent_to_child[1]); + while((nbytes = read(parent_to_child[0], bufchild, BUFSIZE)) > 0) { + write(child_to_parent[1], bufchild, nbytes); + } + break; + default: /*parent*/ + close(parent_to_child[0]); + close(child_to_parent[1]); + while (max_duration < BILLION) { + get_time_ts(&t0); + write(parent_to_child[1], msg1, strlen(msg1) + 1); + nbytes = read(child_to_parent[0], bufchild, BUFSIZE); + get_time_ts(&t1); + duration = duration_ns(t0, t1); + printf("read: %s\n", bufchild); + print_time_ns(duration); + max_duration += duration; + } + close(parent_to_child[0]); + close(parent_to_child[1]); + wait(NULL); + } + return 0; +}