Discussion:
codigo misterioso
(demasiado antiguo para responder)
Àngel
2003-08-24 11:54:06 UTC
Permalink
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;
}
znôrt
2003-08-24 12:23:33 UTC
Permalink
Post by Àngel
Saludos.
En un ejemplo de programación de redes donde se implementa un pequeño
sa.sa_handler = sigchld_handler;
donde "sa" es una struct sigaction y "sigchld_handler" es una función
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
1- ¿De que sirve el parámetro de "sigchld_handler(int s)" si no hace
nada en la función?
Esa función se utiliza como manejador para controlar los signals de un
proceso hijo. Se invocará con el "signal" emitido como parámetro, pero
en este caso, como no se quiere hacer nada con él, pues no se usa.
Post by Àngel
2- ¿Como puede usarse una funcion que no retorna nunca nada en una
asignación?
Como no lleva paréntesis, no está asignando el valor de retorno de la
función, si no la dirección de la propia función. La función aquí ni
se evalua, simplemente se almacena su dirección en un campo de la
estructura. Esta estructura se pasará a la función sigaction(), que a
su vez provocará que se llame a sa_handler en su momento.
Post by Àngel
3- ¿Por qué el compilador no lanza siquiera un miserable aviso y compila
a la perfección?(uso el gcc 3.3)
Porque es código perfectamente legal? :-)

Mírate
http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html

La verdad, yo estas funciones no las conozco mucho, entiendo que lo
que está haciendo es consumir los signals del proceso hijo, para que
no queden pendientes, lo cual deja al proceso colgado por ahí en lo
que se llama estado "zombie".

saludos
znôrt
Julián Albo
2003-08-24 13:12:55 UTC
Permalink
servidor.cpp:83: error: invalid conversion from `int*' to `socklen_t*'
Fallo mio grabarlo como .cpp en vez de .c :D

Salu2
franci72
2003-08-24 15:59:19 UTC
Permalink
Post by Àngel
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?
la función que espera la estructura sigaction es del tipo

void sigchld_handler(int s)

Esto quiere decir que es lo que tu has de pasarle por tanto ha de
tener el parametro te guste o no, aunque no lo usemos para nada pero
esto es indiferente. El parametro esta para darnos la posibilidad de
usarlo, no para que obligatoriamento lo usemos.
Post by Àngel
3- ¿Por qué el compilador no lanza siquiera un miserable aviso y compila
a la perfección?(uso el gcc 3.3)
Porque puede que el parametro sea obligatorio para la funcion que lo
llama y no necesario para la funcion en si, por ejemplo porque sea una
funcion que se llame dinamicamente y substitulla a otra, ...
Si cantara siempre en estos casos el numero de warnings en muchas
librerias seria brutal.

----------------------------------------------------------------------
Me he comparado unos kilos de uranio en africa para hacer unas armas
nucleares y ponerselas a bush, a blair y su amigo ansar, perdon aznar.
(Es mentira, pero ya lo usaran los tres amigos para hacer guerras).
Loading...