Newsgroup: it.comp.lang.c
Titolo: Network programming ed eliminazione dei processi zombies

Ciao a tutti.
Avrei la necessita' di iniziare a programmare in C nell'ambito networking.
Cominciando da 0, esperti ed amici mi hanno suggerito un lavoro dedicato ad i principianti che fa una carrellata su udp e tcp: 
http://beej.us/guide/bgnet/
 .
E' un po che lo leggo e con fatica inizio a muovermi in questo ambito.
Adesso pero' mi sono arenato su di un costrutto che la guida non spiega e che non riesco proprio a capire.
Ho provato a chiedere ai prima citati esperti ed amici senza successo.
 
Chiederei allora qui se qualcuno poteva darmi dei chiarimenti.
 
Veniamo al codice: si tratta di un semplice esempio di server tcp che ad un certo
punto (da quando indicato dall'autore) deve fare il "reap" di tutti i processi zombies. Il codice e' server.c e di sotto riporto la parti che mi creano fastidio:
 
 
void sigchld_handler(int s)
{
	while(waitpid(-1, NULL, WNOHANG) > 0);
}
 
int main(void)
{
......
......
    struct sigaction sa;  
......
......
    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) 
    {
	perror("sigaction");
	exit(1);
    }
.....
......
 
Dubbio: la funzione sigchld_handler nel prototipo e' dichiarata void.
Cosa va a finire nella funzione sa.sa_handler.
 
Grazie
 

 
 
Il puntatore alla funzione.
Era questo il dubbio?
Ciao!


Non esattamente. Ho anche fatto un errore.
Quando chiedevo cosa va a finire in sa.sa_handler ho detto funzione invece e' un
campo di una struttura.
 
Provo a dirlo in altri termini
 
int sum(int a, int b)
{
   return (a+b);
}
 
.....
a=sum(5,7);
 
a che e' un intero riceve da sum un intero che e' il tipo di ritorno.
 
Nel caso precedente invece, 
 
void sigchld_handler(int s)
 
non restituisce niente. E' vero che anche malloc restituisce void ma
si effettua un cast sul tipo di interesse.
Quello che non capisco allora e'
come fa a restituire qualcosa sigchld_handler(int s) ed in particolare coas restituisce.
Grazie

 > sa.sa_handler = sigchld_handler; // reap all dead processes
 
sigchld_handler è il puntatore alla funzione e questo viene conservato 
nel campo sa_handler della struttura sa. Il rightvalue è un puntatore.

 Provo a dirlo in altri termini
 
Evidentemente non sai cos'è un puntatore a funzione.
Prova a cercarlo e in caso torna con altre domande!
Ti allego uno snippet, tanto per chiarire cosa penso non ti sia chiaro :)
 
#include <stdio.h>
void a(void) { printf("a\n"); }
void b(void) { printf("b\n"); }
int main(void)
{
    void(*p)(void);
    p = a;
    p();
    p = b;
    p();
    return 0;
}
 
Ciao!


Grazie ad Andrea per avermi fatto notare che in effetti si tratta di un inizializzazione del puntatore nel campo della struttura in quanto non ci sono le parentesi e grazie a fma per l'esempio di codice.
Avete perfettamente ragione: sapevo che i puntatori a funzione esistevano ma non li avevo mai incontrati.
Faccio ancora fatica a capire che ruolo giochi l'inizializzazione della struttura sa (di tipo sigaction con un puntattore a funzione) nella chiamata alla funzione sigaction (tanto per complicare le cose).
Googlando un po' in sostanza mi sono reso conto di essere incappato nella gestionie dei signal che a quanto pare non e' assolutamente banale.
 
Chiarito il dubbio grazie a voi, credo che quel pezzo di codice lo prendero' come dogma senza cercare di capirlo (decisamente cattiva abitudine) e rimando il tutto dopo che avro' sgrossato la network programming a quando potro' dedicarmi a capire la gestione dei signal.
 
Per il momento grazie ancora

 
 
Ti faccio giusto un appunto veloce.
I puntatori a funzione sono una caratteristica fondamentale e, se vogliamo,
semplice nonché utile del linguaggio. La programmazione di rete (o di sistema,
se maneggi i segnali unix) sono cose abbastanza complicate, anche per gli
esperti.
Non posso che consigliarti (e lo faccio perché non sarebbe la prima volta che
vedo una situazione simile) di vedere un po' di più le basi, prima di incappare
in qualche vicolo cieco a causa della mancanza della dimestichezza necessaria
nel linguaggio che hai scelto. La programmazione di rete è uno dei miei hobbys
preferiti (una volta ho anche scritto uno stack TCP/IP from scratch, per cui
fatti un idea di quanto mi piace), per cui so che lasciarsi abbattere da
questo tipo di difficoltà è un problema superabile con poco studio.
 
Best luck,
Ciao!


Grazie fma... (anche per l'incoraggiamento).
Se posso abusare della tua disponibilita', considerato che studiare (tempo permettendo) non e' un problema, mi potresti indirizzare verso una sorgente "autorevole" per colmare queste mie lacune? Internet offre tanto, a volte troppo, il rischio e' di perdersi tra tutto il materiale proposto.
Grazie ancora.

 
 
Come primo, per dovere, non posso non citare la bibbia di tutti i programmatori
C (vedrai che arriveranno altri post suggerendo la stessa cosa :) ): il
K&R (un link su amazon, ma lo trovi un po' ovunque 
http://www.amazon.com/C-Programming-Language-2nd-Edition/dp/0131103628/ref=sr_1_1?ie=UTF8&qid=1360421765&sr=8-1&keywords=kernigan+and+ritchie+c
)
 
Se il linguaggio non è un problema, e ti interessa la programmazione unix,
prima di vedere la programmazione di rete ti direi di leggere direttamente
il codice di alcune delle coreutils (less, cat, e compagni): alcune di queste
utility implementano degli algoritmi spiegati nel libro di cui sopra, ma sono
scritti "il meglio possibile", per cui ti puoi fare un'idea di che aspetto
ha un tipico programma *nix.
 
Il tutorial che stai leggendo per le basi delle reti è ottimo, a me piace
molto. Di libri sul TCP io ne ho due/tre e ne ho letti altri, e non saprei
dirti il migliore, ma probabilmente a te interessano protocolli di più alto
livello, come HTTP o FTP, che sono un discorso a parte.. Non sapendo il tuo
target per adesso glisso ;)
 
Ti arriveranno molti altri suggerimenti di ogni tipo, per cui io mi fermo
qui :)
 
Ciao!


Grazie ed attendo fiducioso