Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Consider the following simple server in the internet domain using TCP. How I can

ID: 3851175 • Letter: C

Question

Consider the following simple server in the internet domain using TCP. How I can add a SIGCHLD to reap zombie processes in C?

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno, clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     pid_t pid;
     int status;
  
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided ");
         exit(1);
     }
  
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
   if (sockfd < 0)
        error("ERROR opening socket");
   
   bzero((char *) &serv_addr, sizeof(serv_addr));
   
   portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
  
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0)
              error("ERROR on binding");
          
     listen(sockfd,5);
  
     clilen = sizeof(cli_addr);

     while (1) {
     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
  
     if (newsockfd < 0)
          error("ERROR on accept");
   
   if((pid=fork())== -1)
   {
   pid = wait(&status);
   close(newsockfd);
   continue;
   }
   else if(pid>0)
   {
   //wait(NULL);
   close(newsockfd);
   continue;
   }

     while(1) {
      
     bzero(buffer,256);

     n = read(newsockfd,buffer,255);
  
     if (n < 0) error("ERROR reading from socket");

     if (n == 0) {printf("This Client is gone "); break;}
  
     printf("Here is the message: %s ",buffer);

     n = write(newsockfd, buffer, strlen(buffer));
   
     if (n < 0) error("ERROR writing to socket");
     }
     }
     return 0;
}

Explanation / Answer

// I have added the code to reap zombie processes using SIGCHLD please check the code below

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>   /* for the waitpid() system call */
#include <signal.h>        /* added for signal handling */
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

void sigchld_handler(int s)
{
    while(waitpid(-1, NULL, WNOHANG) > 0);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno, clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     pid_t pid;
     int status;
     struct sigaction sa; // added struct sigaction for signal SIGCHLD
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided ");
         exit(1);
     }
  
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
     if (sockfd < 0)
        error("ERROR opening socket");
   
     bzero((char *) &serv_addr, sizeof(serv_addr));
   
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
  
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0)
              error("ERROR on binding");
            
     listen(sockfd,5);
  
     clilen = sizeof(cli_addr);


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


     while (1) {
     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
  
     if (newsockfd < 0)
          error("ERROR on accept");
   
    if((pid=fork())== -1)
    {
    pid = wait(&status);
    close(newsockfd);
    continue;
    }
    else if(pid>0)
    {
    //wait(NULL);
    close(newsockfd);
    continue;
    }

     while(1) {
        
     bzero(buffer,256);

     n = read(newsockfd,buffer,255);
  
     if (n < 0) error("ERROR reading from socket");

     if (n == 0) {printf("This Client is gone "); break;}
  
     printf("Here is the message: %s ",buffer);

     n = write(newsockfd, buffer, strlen(buffer));
   
     if (n < 0) error("ERROR writing to socket");
     }
     }
     return 0;
}