#include	<stdio.h>
#include	<stdlib.h>
#include	<unistd.h>

#define	__USE_GNU																											// struct sockaddr_in
#include <arpa/inet.h>
#include	<fcntl.h>
#include	<signal.h>

#include	<string.h>
#include	<errno.h>

int	sa_sigaction_SIGHUP_count = 0;

void	sa_sigaction_SIGHUP(int signo, siginfo_t *info, void *ucontext)
{
	fprintf(stdout, "SERVER SIGHUP 4 NOW\n"); fflush(stdout);

	sa_sigaction_SIGHUP_count++;
}

int	main()
{
	int				sock[2];																								// server sockets
	int				temp;
	
	//	---	signaling
	
	sigset_t				sa_mask;				sigfillset(&sa_mask); sigdelset(&sa_mask, SIGHUP);

	struct	sigaction		sigaction_SIGHUP;
					sigaction_SIGHUP.sa_handler	= NULL;
					sigaction_SIGHUP.sa_sigaction	= sa_sigaction_SIGHUP;
					sigaction_SIGHUP.sa_flags		= SA_SIGINFO;
					sigaction_SIGHUP.sa_mask		= sa_mask;

					temp				= sigaction(SIGHUP, &sigaction_SIGHUP, NULL);		if	(temp    == -1)	{ printf("Error calling sigaction(): %s\n", strerror(errno)); };

	//	---	handshake
	
					sock[0]				= socket	(AF_INET, SOCK_STREAM, 0);				if	(sock[0] == -1)	{ printf("Error calling socket()   : %s\n", strerror(errno)); };

					temp				= fcntl	(sock[0], F_SETSIG, SIGHUP);			if	(temp    == -1)	{ printf("Error calling fcntl()    : %s\n", strerror(errno)); };
					temp				= fcntl	(sock[0], F_SETOWN, getpid());			if	(temp    == -1)	{ printf("Error calling fcntl()    : %s\n", strerror(errno)); };
					temp				= fcntl	(sock[0], F_GETFL);				if	(temp    == -1)	{ printf("Error calling fcntl()    : %s\n", strerror(errno)); };
					temp				= fcntl	(sock[0], F_SETFL, temp | O_ASYNC);			if	(temp    == -1)	{ printf("Error calling fcntl()    : %s\n", strerror(errno)); };
		
	struct	sockaddr_in		faddrs;				memset(&faddrs, 0, sizeof(struct sockaddr_in));

					faddrs.sin_family			= AF_INET;
					faddrs.sin_addr.s_addr		= (uint32_t) inet_addr("127.0.0.1");
					faddrs.sin_port			= (uint16_t) htons(1024);
		
					temp				= bind	(sock[0], &faddrs, sizeof(struct sockaddr_in));	if	(temp    == -1)	{ printf("Error calling bind()     : %s\n", strerror(errno)); };
					temp				= listen	(sock[0], 1);					if	(temp    == -1)	{ printf("Error calling listen()   : %s\n", strerror(errno)); };
					sock[1]				= accept	(sock[0], NULL, NULL);				if	(sock[1] == -1)	{ printf("Error calling accept()   : %s\n", strerror(errno)); };
						  								
	while	(sa_sigaction_SIGHUP_count == 0)				usleep(1000);																			// client first to close connection and prevent linger

 	if	(sock[1] != -1)	{	temp				= close	(sock[1]);					if	(temp    == -1)	{ printf("Error calling close()    : %s\n", strerror(errno)); }; };
	if	(sock[0] != -1)	{	temp				= close	(sock[0]);					if	(temp    == -1)	{ printf("Error calling close()    : %s\n", strerror(errno)); }; };
			
	exit(EXIT_SUCCESS);
}

