// vim: noet sw=4 ts=4: /* ================================================================================== Copyright (c) 2020 Nokia Copyright (c) 2020 AT&T Intellectual Property. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================================================== */ /* X ****************************************************************************** * * Mnemonic: SIclose * Abstract: This routine allows the user application to close a port * associated with a file descriptor. The port is unbound from * the transport providor even if it is marked as a listen * port. If the fd passed in is less than 0 this routine assumes * that the UDP port opened during init is to be closed (user never * receives a fd on this one). * Parms: gptr - The pointer to the ginfo block (SIHANDLE to the user) * fd - FD to close. * Returns: SI_OK if all goes well, SI_ERROR with SIerrno set if there is * a problem. * 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 ****************************************************************************** */ #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 ); } if( tpptr != NULL ) { gptr->sierr = SI_ERR_TP; 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 ) ) ; } 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 } // SIclose