Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Closing sockets in forked process

Status
Not open for further replies.

danielhozac

Programmer
Aug 21, 2001
2,058
SE
I am currently working a server which [tt]fork[/tt]s processes to handle incoming connections. However, since the sockets are [tt]accept[/tt]ed in the main server loop, I can't seem to close it in the child. I thought that I could handle it in a signal handler, but since the file which does the [tt]fork[/tt]ing is built as a shared library and I [tt]dlopen[/tt] it in the server, I get segmentation faults every time I use the [tt]siginfo_t[/tt] structure in the signal handler.

Here is some code:
Code:
int sockets[MAX_SOCKETS];
int initialize()
{
	struct sigaction sa;

	sa.sa_flags = SA_RESTART;
	sigfillset(&sa.sa_mask);
	sa.sa_sigaction = signalHandler;
	if (sigaction(SIGCHLD, &sa, NULL) == -1)
		return -1;
	return 0;
}
void signalHandler(int signal, siginfo_t *info, void *context)
{
	if (sockets[info->si_pid] != 0)
		close(sockets[info->si_pid]);
}

I ran [tt]gdb[/tt] on my program, and it receives the [tt]SIGSEGV[/tt] as it enters the [tt]signalHandler[/tt] function.

Environment: Linux 2.4.21, glibc 2.2.93 and gcc 3.2

//Daniel
 
One idea: have you thought of using select() for this?
It might simplify things considerably.
 
Yes, but I [tt]select()[/tt] uses a considerable amount of processor time.

//Daniel
 
What does your socket code look like? It should look something like this:

Code:
int listening_socket, accepted_socket;
struct sockaddr_in sin;
struct sockaddr sa;
int sa_len;
int id;

/* set up sin variable */
listening_socket=socket(AF_INET,SOCK_STREAM,0);
bind(listening_socket,(struct sockaddr *)&sin,sizeof(sin))
listen(listening_socket,5)
sa_len=sizeof(sa);
accepted_socket=accept(listening_socket,&sa,&sa_len);
if ((id=fork())<0) {
  perror(&quot;fork failed&quot;)
} else if (id>0) {
  /* do parent process tasks */
  close(accepted_socket);
} else {
  /* do child process tasks */
  close(listening_socket);}
}

After forking off the child process, the parent should close the socket descriptor associated with the accepted socket, and the child should close the socket descriptor associated with the listening socket.

Is this what's causing you the problem?

Dennis
 
The problem is that I am unable to get the parent process to close the socket. The only way to have the parent process notified, as I see it, is to use a signal handler. But, as I said in my first post, using a signal handler throws a segmentation fault.

Everything works fine with my POSIX threads module, so I'm considering to just scrap the forking module at the moment.

//Daniel
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top