kannan@b.cs.wvu.wvnet.edu (Raman Kannan) (04/18/89)
The problem I am trying to solve is to be interrupted when there is something to read from a socket. I am using signal (SIGIO, handler_function). Within that handler I do the following: reset my interrupt accept --- check for errors and get the file descriptor read on the fd. -- check for errors return ; hoping to get back to place where the main was interrupted. The trouble I am having: It does not return to the main after the call to accept. OBSERVED: Multiple interrupts trigger the handler function. I put some print stmts to check it. If I return before the accept call, the main loop comes back to life. Can soemone point out the problem. Thank you very much in advance. ---==== The following is the source /* sock header has socket and fcntl include and a couple of int definitions */ #include "sock_header.h" #include <signal.h> /* this code listens on a socket and writes out on stdio. Quits when the message recd is ENDING ALL CONNECTIONS */ int rval, sock , msgsock , length ; struct sockaddr_in name ; int buf_count ; /***************** THIS IS COMMON BLOCK *****************/ /* the kb_buffer holds the recd message until it is processed */ char kb_buffer [10] [1024] ; /* the r_id indicates the next buffer to be used for reading the w_id indicates the next buffer to ne used for writing the kbstatus indicates the current status of the next buffer 0 => has been read and can be written over 1 => has been written and must be read before writing */ int r_id , w_id , kbstatus [10] ; /***************** END OF COMMON BLOCK *****************/ char buf [1024], rd_buf [1024] ; /* set all buffers to be written A buffer can be written only if the content has been read */ initialize_buffers () { int i = 0 ; for (; i < 10 ; ) kbstatus [i++] = HAS_BEEN_READ ; r_id = w_id = 0 ; } int io_handler () { /* when a signal is raised it resets to default so set it back to our handler */ signal ( SIGIO, io_handler ) ; if ( kbstatus[w_id] ) { printf ("\n all buffers full "); return ;} msgsock = accept ( sock , (struct sockaddr *)0 , (int *) 0) ; buf_count = 0 ; if ( msgsock == -1 ) { perror ("accept") ; exit (1) ; } /* a connection has been accepted clear the next write buffer */ bzero ( kb_buffer[w_id] , LCM_BLOCK_SIZE ) ; printf ("\n In INTERRUPT HANDLER\n"); bzero ( rd_buf , LCM_BLOCK_SIZE ) ; if ( (rval = read ( msgsock , rd_buf, LCM_BLOCK_SIZE ))< 0 ) { perror ("READING STREAM SOCKET") ; exit (0) ; } else if ( rval != 0 ) { /* place it in a buffer for processing by the main module */ strcat ( kb_buffer[w_id] , rd_buf ) ; printf ("\n<%s>", rd_buf ) ; printf ("\n<kb_buffer =>%s>", kb_buffer[w_id]); buf_count += rval ; /* printf ("\n--> %s \n",rd_buf ) ;*/ } /* indicate that this buffer buffer is not yet read */ printf ("\nbuffer being written is <%d>",w_id); kbstatus [w_id] = 1 ; /* next buffer */ if ( ++w_id == 10 ) w_id = 0 ; close (msgsock ) ; printf ("\nreturning from interrupt"); return rval ; }/* returning from interrrupt */ main () { initialize_buffers () ; sock = socket ( AF_INET , SOCK_STREAM , 0 ) ; if ( sock < 0 ) { perror ( "opening SOCK_STREAM socket"); exit (1) ; } name.sin_family = AF_INET ; name.sin_addr.s_addr = INADDR_ANY ; name.sin_port = READ_SOCK ; if ( bind ( sock ,(struct sockaddr *) &name , sizeof name ) < 0 ) { perror ("binding STREAM SOCKET"); exit (1) ; } /* set up interrupt for reading on sock */ signal ( SIGIO, io_handler ) ; /* set th eprocess receving the SIGIO/SIGURG signal to us */ if ( fcntl ( sock , F_SETOWN , getpid () ) < 0 ) { perror ("COULDNT SET OWNER FOR THE SIGURG"); exit (1) ; } /* allow receipt of asynchrouns I/O signal */ if ( fcntl ( sock , F_SETFL , FASYNC ) < 0 ) { perror ("COULDNT SET asynchrnous I/O"); exit (1) ; } listen ( sock , 5 ) ; do { /* the r_id refers to next buffer in the ring if it is the end of the ring reset it to the beginning of the buffer */ if ( r_id == 10 ) r_id = 0 ; printf ("\n< MAIN LOOP WORKING>\n"); printf ("\nbuffer being checked is <%d>",r_id); if ( kbstatus [ r_id ] ) { /* something has been written into this buffer let us process it */ printf ("\n< SOMETHING CAME IN THE SOCKET>\n\n"); printf ("The string recd <%s>",kb_buffer [r_id ]); if ( strcmp ( kb_buffer[r_id] , "END ALL CONNECTION")) printf ("Ending this connection \n") ; else { printf ("\n--> ENDING ALL CONNECTIONS" ) ; exit (1) ; } /* reset the buffer */ kbstatus [r_id++] = 0 ; } sleep (5) ; } while ( 1 ) ; } ----====END OF SOURCE --kannan Concurrent Engineering Research Center, West Virginia University, Morgantown.