Minor Problem With Fork And Listen [Archive] - C Board

PDA

View Full Version : Minor Problem With Fork And Listen


DeepBlackMagic
09-18-2003, 08:31 PM
I am having 2 problems with the following C code. First of which is reguardless to which port number i assign it, it always trys to bind to port 2586. The second problem is that over time it builds up debunked processes (Z) that never terminate until the parent is terminated. Any help, or general suggestions would be greatly appreciated.



#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>


int terminate=0;

void signalhd(int senal);


int main()
{
struct sockaddr_in sin, fsin;
int s, ssock, alen;
char *ipaddress;

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = 6666;

if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Cant create socket");
exit(1);
}

if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0)
{
perror("Cant assign addres");
exit(2);
}

if (listen(s, 5) < 0)
{
perror("Cant turn to listening mode");
exit(3);
}

signal (SIGCHLD, SIG_IGN);
signal (SIGINT,signalhd);

while (1)
{
if (terminate==1)
{
close(s);
exit(0);
}
alen = sizeof(fsin);
if ((ssock=accept(s, (struct sockaddr *)&fsin, &alen)) < 0)
{
if (errno == EINTR) continue;
perror("Accept failed");
exit(4);
}

switch (fork()) {
case -1:{
perror ("Forking error");
exit (5);
}
case 0: {
close(s);
exit(0);
}
default: {
ipaddress=(char *)inet_ntoa(fsin.sin_addr);
write(ssock, ipaddress, strlen(ipaddress));
close(ssock);
break;
}
}
}
return 0;
}

void signalhd(int senal){
if (senal==SIGINT){
printf("...Interrupt...\n");
terminate=1;
}
}

Onkel BeBu
09-19-2003, 03:52 AM
The port issue is simple to solve, you hace to convert it to networkbyte order, just like you did it with the ip:

sin.sin_port = htons(6666);

For your processes you can add following sigaction:


void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}

int main()
{
struct sigaction sa;
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
}

DeepBlackMagic
09-19-2003, 04:08 PM
Yes, thanks it was 4am and i kinda forgot about that with the port, that part is fixed, however the defunct processes arent.

I added

struct sigaction sa;
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

right after main, and added the appropiate function proto and function. It all compiles ok but there are still a dozen processes that never terminate.

USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
slitwrist 29622 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29623 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29624 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29625 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29626 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29627 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29628 0.0 0.0 0 0 p1 Z 4:54PM 0:00.00 (echoipdfork)
slitwrist 29615 0.0 0.1 860 372 p1 S 4:53PM 0:00.01 ./echoipdfork
slitwrist 29619 0.0 0.0 0 0 p1 Z 4:53PM 0:00.00 (echoipdfork)

Onkel BeBu
09-19-2003, 06:27 PM
Sorry forgot to say that this line signal (SIGCHLD, SIG_IGN);
has to be removed. In POSIX stands you must not use sigchld with sig_ign. Dont know anymore why, you can just dig for yourself or accept it and remove the line. Then should work. On my Linx box it works flawless without the line.

DeepBlackMagic
09-19-2003, 08:19 PM
Thanks alot, that fixed it.