Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Sep 1998 01:14:31 +0200
From:      Purrcat <K.Staring@UCI.KUN.NL>
To:        questions@FreeBSD.ORG
Subject:   sockets, forking and zombies
Message-ID:  <35FEF4D7.D9D54D84@uci.kun.nl>

next in thread | raw e-mail | index | archive | help
I'm having some trouble with a program I'm writing. After the program
connects a socket to a port, and start to listen, the program should
accept incoming telnets (for example) on port 4000. The program should
fork and continue listening; while the child handles the connection (in
the included program, say "Heyup" and close the connection). When the
child is done saying "Heyup", it exits (in my example, it exits with
errorcode -1, but errorcode 0 does exactly the same). But the child
doesn't exit normally; it becomes a zombie. I have included a
signalhandler: "(void) signal(SIGCHLD, SIG_IGN);" which should say that
the parent should ignore everything the child wants to say to the
parent. Still, the zombie process emerges... Does anyone know what I am
doing wrong? It could be that the child tries to close a socket which it
'does not own' or something, but even if I comment these lines out, the
problem stays. I'm using FreeBSD 2.2.6 (which does not really matter)
and gcc (which also should not be a problem).

------------------ Program starts here
----------------------------------------

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

void dostuff();


main()
{
  int s_in, s_out, rmtlen, bindport, pid;
  struct sockaddr_in lcl, rmt;

/* Ignore child thingies; so no zombies emerge (NOT!) */
  (void) signal(SIGCHLD, SIG_IGN);

  if((s_in = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    printf("socket: %d\n", errno);
    exit(-1);
  }
  bzero((char *)&lcl, sizeof(lcl));
  lcl.sin_family = AF_INET;
  lcl.sin_port = htons(4000); /* bind to port #4000 */
  lcl.sin_addr.s_addr = htons(INADDR_ANY);
  if(bind(s_in, (struct sockaddr *)&lcl, sizeof(lcl)) < 0) {
    printf("bind: %d\n", errno);
    exit(-1);
  }
  if(listen(s_in, 5) < 0) {
    printf("listen: %d\n", errno);
    exit(-1);
  }

/* accept loop. */
  while(1) {
    if((s_out = accept(s_in, (struct sockaddr *)&rmt, &rmtlen)) < 0) {
      printf("accept: %d\n", errno);
      exit(-1);
    }
    if(!fork()) {
      close(s_in);
      dostuff(s_out);
      close(s_out);
      exit(-1);
    }
    close(s_out);
  }
}

void dostuff(int s)
{
/* write some stuff to connected port */
  write(s, "Heyup..\n", 8);
}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35FEF4D7.D9D54D84>