/*********************************************************************/
/* UDP Signal Driven server                                          */
/*                                                                   */
/* The signal driven programming is based on loading the signal      */
/* SIGIO after the socket returns a sockfd and when data is ready    */
/* to be read from the file descriptor, the appropriate function     */
/* is called.                                                        */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*********************************************************************/
 

    void io_handler(int); /*This is the main I/O procedure */

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    /* #include <netdb.h> */
    #include <fcntl.h>
    #include <signal.h>
    #include <stdio.h>

    #include <sys/wait.h>
    #include <sys/time.h>

    #define MYPORT 3490    /* the port users will be sending to */
    #define MAXBUFLEN 100

    int sock;
    char buf[MAXBUFLEN];



int main()
{
	int length;
	struct sockaddr_in server;


	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) {
		perror("opening datagram socket");
		exit(1);
	}


	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(MYPORT);

	if (bind(sock, (struct sockaddr *)&server, sizeof server) <0 ){
		perror("binding datagram socket");
		exit(1);
	}

	length = sizeof(server);
	if (getsockname(sock, (struct sockaddr *)&server, &length) < 0){
		perror("getting socket name");
		exit(1);
	}
	printf("Socket port #%d\n", ntohs(server.sin_port));


	// first: set up a SIGIO signal handler by use of the signal call()
	signal(SIGIO,io_handler);


	// second: set the process id or process group id that is to receive
	// notification of pending input to its own process id or process 
	// group id
	if (fcntl(sock,F_SETOWN, getpid()) < 0){
		perror("fcntl F_SETOWN");
		exit(1);
	}

	// third: allow receipt of asynchronous I/O signals
	if (fcntl(sock,F_SETFL,FASYNC) <0 ){
		perror("fcntl F_SETFL, FASYNC");
		exit(1);
	}


	for(;;)
	;
	/* Actually here was suppose to come the rest of the code (not dealing with comm) */

	}


void io_handler(int signal)
{
	int 			numbytes;	/* Number of bytes recieved from client */
        int 			addr_len;	/* Address size of the sender		*/
        struct sockaddr_in 	their_addr;	/* connector's address information	*/
	
	printf("The recvfrom proc. !\n");

        if ((numbytes=recvfrom(sock, buf, MAXBUFLEN, 0, \
                    (struct sockaddr *)&their_addr, &addr_len)) == -1) {
                perror("recvfrom");
                exit(1);
        }
	
	buf[numbytes]='\0';
        printf("got from %s --->%s \n  ",inet_ntoa(their_addr.sin_addr),buf);
	return;
}