==================================================================================
*/
-/* X
+/*
******************************************************************************
*
* Mnemonic: SIclose
* Date: 3 February 1995
* Author: E. Scott Daniels
*
-* Modified: 19 Feb 1995 - To set TP blk to drain if output pending.
-* 10 May 1995 - To change SOCK_RAW to SOCK_DGRAM
-* 22 Feb 2002 - To accept TCP_LISTEN_PORT or UDP_PORT as fd
+* Modified:i 19 Feb 1995 - To set TP blk to drain if output pending.
+* 10 May 1995 - To change SOCK_RAW to SOCK_DGRAM
+* 22 Feb 2002 - To accept TCP_LISTEN_PORT or UDP_PORT as fd
******************************************************************************
*/
#include "sisetup.h"
-extern int SIclose( struct ginfo_blk *gptr, int fd )
-{
-
- struct tp_blk *tpptr; // pointer into tp list
- int status = SI_ERROR; // status of processing
-
- gptr->sierr = SI_ERR_HANDLE;
- if( gptr->magicnum == MAGICNUM ) // good cookie at the gptr address?
- {
- gptr->sierr = SI_ERR_SESSID;
-
- if( fd >= 0 ) // if caller knew the fd number
- {
- for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != fd;
- tpptr = tpptr->next ); // find the tppblock to close
- }
- else // user did not know the fd - find first Listener or UDP tp blk
- {
- if( fd == TCP_LISTEN_PORT ) // close first tcp listen port; else first udp
- for( tpptr = gptr->tplist; tpptr != NULL && !(tpptr->flags&& TPF_LISTENFD); tpptr = tpptr->next );
- else
- for( tpptr = gptr->tplist; tpptr != NULL && tpptr->type != SOCK_DGRAM; tpptr = tpptr->next );
- }
+extern int SIclose( struct ginfo_blk *gptr, int fd ) {
+ struct tp_blk *tpptr; // pointer into tp list
+ int status = SI_ERROR; // status of processing
- if( tpptr != NULL )
- {
- gptr->sierr = SI_ERR_TP;
+ if( gptr != NULL ) {
+ if( fd >= 0 ) { // if caller knew the fd number
+ if( fd < MAX_FDS ) { // straight from map if possible
+ tpptr = gptr->tp_map[fd];
+ } else {
+ // future: need to lock the list or switch to gmax hash
+ for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != fd; tpptr = tpptr->next ); // find the tppblock to close
+ }
+ } else { // user did not know the fd - find first Listener or UDP tp blk
+ if( fd == TCP_LISTEN_PORT ) { // close first tcp listen port; else first udp
+ for( tpptr = gptr->tplist; tpptr != NULL && !(tpptr->flags&& TPF_LISTENFD); tpptr = tpptr->next );
+ } else {
+ for( tpptr = gptr->tplist; tpptr != NULL && tpptr->type != SOCK_DGRAM; tpptr = tpptr->next );
+ }
+ }
- if( tpptr->squeue == NULL ) // if nothing is queued to send...
- {
- tpptr->flags |= TPF_UNBIND; // ensure port is unbound from tp
- tpptr->flags |= TPF_DELETE;
- {
- int x = 1;
-
- setsockopt(tpptr->fd, SOL_SOCKET, SO_LINGER, (char *)&x, sizeof( x ) ) ;
+ if( tpptr != NULL ) {
+ if( tpptr->squeue == NULL ) { // if nothing is queued to send...
+ tpptr->flags |= TPF_UNBIND; // ensure port is unbound from tp
+ tpptr->flags |= TPF_DELETE;
+ {
+ int x = 1;
+ setsockopt(tpptr->fd, SOL_SOCKET, SO_LINGER, (char *)&x, sizeof( x ) ) ;
+ }
+
+ SIterm( gptr, tpptr ); // close the fd and mark the block as deletable
+ } else {
+ tpptr->flags |= TPF_DRAIN; // stuff on queue, must drain before closing
+ }
+
+ status = SI_OK; // give caller a good status
+ } // end if we found a tpptr
}
- close( tpptr->fd );
- tpptr->fd = -1;
- tpptr->type = -1;
- // siterm now called in build poll if tp is marked delete
- // SIterm( gptr, gptr, tpptr );*/ /* cleanup and remove from the list
- }
- else // stuff queued to send - mark port to drain
- tpptr->flags |= TPF_DRAIN; // and we will term the port when q empty
-
- status = SI_OK; // give caller a good status
- } // end if we found a tpptr
- } // end if the handle was good
- return( status ); // send the status back to the caller
+ return status; // send the status back to the caller
} // SIclose
+