#include "basic.h" /*************************************************************************** * gestisci_zombie * chiama waitpid per eliminare gli zombie. * Deve essere registrata con signal per il segnale SIGCHLD ***************************************************************************/ void gestisci_zombie(int signo) { pid_t pid; int stat; while ( (pid = waitpid(-1,&stat,WNOHANG)) > 0) { printf("Child %d terminated\n",pid); } } /*************************************************************************** * reti_read * legge tutti i dati disponibili nel buffer in una sola volta e poi li * esamina un byte per volta. La read, invece, legge un byte per volta. ***************************************************************************/ ssize_t reti_read(int fd, char *ptr) { static int read_cnt = 0; /* numero di byte letti */ static char read_buf[MAXLINE]; /* buffer per mantenere i dati letti */ static char *read_ptr; /* puntatore al prossimo byte da leggere */ if (read_cnt <= 0) { /* se non ci sono byte disponibili nel buffer chiama la read. */ while ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) /* se la read fallisce perchè non ci sono sufficienti dati riprova, altrimenti esce. */ if (errno != EINTR) return(-1); if (read_cnt == 0) return(0); read_ptr = read_buf; } /* legge il prossimo byte dal buffer e decrementa il numero dei byte disponibili */ read_cnt--; *ptr = *read_ptr++; return(1); } /*************************************************************************** * reti_readline * legge un'intera riga utilizzando la reti_read ***************************************************************************/ ssize_t reti_readline(int fd, void *vptr, size_t maxlen) { int n, rc; char c, *ptr; ptr = vptr; for (n = 1; n < maxlen; n++) { if ( (rc = reti_read(fd, &c)) == 1) { *ptr++ = c; if (c == '\n') break; /* legge il newline, come la fgets() */ } else if (rc == 0) { if (n == 1) return(0); /* EOF, non ha letto nulla */ else break; /* EOF, ha letto qualcosa */ } else return(-1); /* errore, errno settato dalla read() */ } *ptr = 0; /* inserisce uno 0 per indicare la fine dell'input, coma la fgets() */ return(n); /* restituisce il numero di byte letti */ } /*************************************************************************** * reti_writen * scrive n byte sul descrittore fd. Riprova fino a quando i dati non * vengono effettivamenti scritti. ***************************************************************************/ ssize_t reti_writen(int fd, const void *vptr, size_t n) { size_t nleft; /* byte anora da scrivere */ ssize_t nwritten; /* byte scritti dall'ultima write */ const char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { if ( (nwritten = write(fd, ptr, nleft)) <= 0) { if (errno == EINTR) /* richiama la write se la funzione è fallita perchè nel buffer ptr non ci sono sufficienti byte. */ nwritten = 0; else return(-1); } nleft -= nwritten; ptr += nwritten; } return(n); /* restituisce il numero di byte scritti. */ }