Àngel
2003-08-24 11:54:06 UTC
Saludos.
En un ejemplo de programación de redes donde se implementa un pequeño
sevidor he encontrado la siguiente linea de código:
sa.sa_handler = sigchld_handler;
donde "sa" es una struct sigaction y "sigchld_handler" es una función
como la que sigue:
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
Como novato se me plantean las siguientes dudas:
1- ¿De que sirve el parámetro de "sigchld_handler(int s)" si no hace
nada en la función?
2- ¿Como puede usarse una funcion que no retorna nunca nada en una
asignación?
3- ¿Por qué el compilador no lanza siquiera un miserable aviso y compila
a la perfección?(uso el gcc 3.3)
Gracias.
A continuación expongo el código completo puesto que es breve.
/* Exemple de servidor de sockets de fluxe */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define MYPORT 3490 /* port al que conectarán els usuaris */
#define BACKLOG 10 /* conexións pendents que es mantindran a la cua */
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
int main(void)
{
int sockfd, new_fd; /*escoltar a sockfd les noves connexions a new_fd*/
struct sockaddr_in my_addr; /* info sobre la direccio local */
struct sockaddr_in their_addr; /* info sobre la direccio client */
struct sigaction sa;
int sin_size;
int yes=1;
/*obtindre socket + comprobacio d'errors*/
if((sockfd = socket(AF_INET, SOCK_STREAM,0)) == 1)
{
perror("socket"); exit(1);
}
/*estblir la opcio del socket a SO_REUSEADDR, que no se que es,
pero cal*/
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
{
perror("setsockopt"); exit(1);
}
my_addr.sin_family = AF_INET; /*ordenacio de bits de la maquina */
my_addr.sin_port = htons(MYPORT); /*ordenacio de bits de la máquina */
my_addr.sin_addr.s_addr = INADDR_ANY; /*rellenar con ip local */
memset(&(my_addr.sin_zero),'\0',8); /*poner a 0 el resto de la struct*/
/*asociar socket amb port*/
if(bind(sockfd,(struct sockaddr*)&my_addr, sizeof(struct
sockaddr))== -1)
{
perror("bind"); exit(1);
}
/* establir tamany de cua de peticions de conexio*/
if(listen(sockfd, BACKLOG)== -1)
{
perror("listen"); exit(1);
}
/* activat modus "acto de fe" */
sa.sa_handler = sigchld_handler; /* eliminar procesos morts */
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_RESTART;
if(sigaction(SIGCHLD, &sa, NULL) == -1)
{
perror("sigaction"); exit(1);
}
/* desactivat modus "acto de fe" */
while(1) /* bucle per fer molts accepts */
{
sin_size = sizeof(struct sockaddr_in);
/* obtenir socket per llegir del socket que escolta el port MYPORT*/
if((new_fd=accept(sockfd,(struct
sockaddr*)&their_addr,&sin_size))==-1)
{
perror("accept"); continue;
}
printf("servidor: conectat a %s \n",inet_ntoa(their_addr.sin_addr));
/*la mara dels ous!!
ara cridem un fork perque un proces fill s'ocupi de envia la
resposta
al client, així el proces papa queda lliure per acceptar mes petis */
if(!fork())
{ /*aquest es proces fill*/
close(sockfd); /* al fill no li cal */
/* manda misstage */
if(send(new_fd,"Güenassss. Soc el sevidor!",26,0)==-1) perror("send");
close(new_fd);
exit(0);
}
close(new_fd); /*al proces pare no li cal*/
}
return 0;
}
En un ejemplo de programación de redes donde se implementa un pequeño
sevidor he encontrado la siguiente linea de código:
sa.sa_handler = sigchld_handler;
donde "sa" es una struct sigaction y "sigchld_handler" es una función
como la que sigue:
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
Como novato se me plantean las siguientes dudas:
1- ¿De que sirve el parámetro de "sigchld_handler(int s)" si no hace
nada en la función?
2- ¿Como puede usarse una funcion que no retorna nunca nada en una
asignación?
3- ¿Por qué el compilador no lanza siquiera un miserable aviso y compila
a la perfección?(uso el gcc 3.3)
Gracias.
A continuación expongo el código completo puesto que es breve.
/* Exemple de servidor de sockets de fluxe */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define MYPORT 3490 /* port al que conectarán els usuaris */
#define BACKLOG 10 /* conexións pendents que es mantindran a la cua */
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
int main(void)
{
int sockfd, new_fd; /*escoltar a sockfd les noves connexions a new_fd*/
struct sockaddr_in my_addr; /* info sobre la direccio local */
struct sockaddr_in their_addr; /* info sobre la direccio client */
struct sigaction sa;
int sin_size;
int yes=1;
/*obtindre socket + comprobacio d'errors*/
if((sockfd = socket(AF_INET, SOCK_STREAM,0)) == 1)
{
perror("socket"); exit(1);
}
/*estblir la opcio del socket a SO_REUSEADDR, que no se que es,
pero cal*/
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
{
perror("setsockopt"); exit(1);
}
my_addr.sin_family = AF_INET; /*ordenacio de bits de la maquina */
my_addr.sin_port = htons(MYPORT); /*ordenacio de bits de la máquina */
my_addr.sin_addr.s_addr = INADDR_ANY; /*rellenar con ip local */
memset(&(my_addr.sin_zero),'\0',8); /*poner a 0 el resto de la struct*/
/*asociar socket amb port*/
if(bind(sockfd,(struct sockaddr*)&my_addr, sizeof(struct
sockaddr))== -1)
{
perror("bind"); exit(1);
}
/* establir tamany de cua de peticions de conexio*/
if(listen(sockfd, BACKLOG)== -1)
{
perror("listen"); exit(1);
}
/* activat modus "acto de fe" */
sa.sa_handler = sigchld_handler; /* eliminar procesos morts */
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_RESTART;
if(sigaction(SIGCHLD, &sa, NULL) == -1)
{
perror("sigaction"); exit(1);
}
/* desactivat modus "acto de fe" */
while(1) /* bucle per fer molts accepts */
{
sin_size = sizeof(struct sockaddr_in);
/* obtenir socket per llegir del socket que escolta el port MYPORT*/
if((new_fd=accept(sockfd,(struct
sockaddr*)&their_addr,&sin_size))==-1)
{
perror("accept"); continue;
}
printf("servidor: conectat a %s \n",inet_ntoa(their_addr.sin_addr));
/*la mara dels ous!!
ara cridem un fork perque un proces fill s'ocupi de envia la
resposta
al client, així el proces papa queda lliure per acceptar mes petis */
if(!fork())
{ /*aquest es proces fill*/
close(sockfd); /* al fill no li cal */
/* manda misstage */
if(send(new_fd,"Güenassss. Soc el sevidor!",26,0)==-1) perror("send");
close(new_fd);
exit(0);
}
close(new_fd); /*al proces pare no li cal*/
}
return 0;
}