Thread: Minor Problem With Fork And Listen

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    265

    Minor Problem With Fork And Listen

    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.

    Code:
    #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;
    	}
    }

  2. #2
    Registered User
    Join Date
    Jul 2003
    Posts
    17
    The port issue is simple to solve, you hace to convert it to networkbyte order, just like you did it with the ip:

    Code:
    sin.sin_port = htons(6666);
    For your processes you can add following sigaction:

    Code:
    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);
            }
    }

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    265
    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
    Code:
            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.
    Code:
    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)

  4. #4
    Registered User
    Join Date
    Jul 2003
    Posts
    17
    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.

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    265
    Thanks alot, that fixed it.

Popular pages Recent additions subscribe to a feed