Gli eseguibili (Linux 32/64 bit e OS X) sono disponibili al seguente link. Le istruzioni vengono mostrate quando eseguite il programma.
Una possibile soluzione (commentata) della verifica è la seguente:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define PIPEIN "pipePongIn"
#define PIPEOUT "pipePongOut"
#define BUFSIZE 10
#define LEFT "l"
#define RIGHT "r"
int main() {
int i, fd_in, fd_out, ballx, position, num_moves;
char stop, buffer[BUFSIZE], *direction;
/* Crea le due pipe (se già non esistono) ed apri:
* - pipePongIn in scrittura, per inviare le mosse all'altro programma;
* - pipePongOut in lettura, per leggere la posizione corrente della pallina. */
mkfifo(PIPEOUT, 0666);
mkfifo(PIPEIN, 0666);
fd_in = open(PIPEOUT, O_RDONLY);
fd_out = open(PIPEIN, O_WRONLY);
if (fd_in < 0 || fd_out < 0) {
perror("Errore nell'apertura delle pipe");
exit(EXIT_FAILURE);
}
/* Flag usata per la terminazione della partita. */
stop = 0;
/* La posizione iniziale della racchetta è 10, al centro del campo. */
position = 10;
/* Inizia la partita! */
write(fd_out, "g", 1);
while(!stop) {
/* Leggi la posizione della pallina. */
i = 0;
while(i < BUFSIZE-1 && read(fd_in, &buffer[i], 1) && buffer[i] != ',') {
i++;
}
if (i == 0) {
/* In questo caso la partita è finita (l'altro programma ha chiuso la pipe e read
* ha restituito zero). */
stop = 1;
} else if (i == BUFSIZE-1) {
/* Qui non ci dovremmo mai arrivare, ma è sempre bene gestire eventuali overflow. */
fprintf(stderr, "Non dovrei essere qui. BOOM!\n");
exit(EXIT_FAILURE);
} else {
/* Estrai la posizione dalla stringa letta dal buffer. */
buffer[i+1] = '\0';
sscanf(buffer, "%d,", &ballx);
/* Vai a sinistra o a destra del numero di mosse necessarie per muovere la
* racchetta nella stessa posizione della pallina. */
direction = ballx < position ? LEFT : RIGHT;
num_moves = abs(ballx - position);
while (num_moves > 0) {
write(fd_out, direction, 1);
num_moves--;
}
position = ballx;
}
}
/* Chiudi entrambe le pipe (la rimozione dal filesystem con 'unlink' viene già
* fatta dall'altro programma). */
close(fd_in);
close(fd_out);
return EXIT_SUCCESS;
}