1 // vim: noet sw=4 ts=4:
3 ==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
22 ******************************************************************************
25 * Abstract: This routine allows the user application to close a port
26 * associated with a file descriptor. The port is unbound from
27 * the transport providor even if it is marked as a listen
28 * port. If the fd passed in is less than 0 this routine assumes
29 * that the UDP port opened during init is to be closed (user never
30 * receives a fd on this one).
31 * Parms: gptr - The pointer to the ginfo block (SIHANDLE to the user)
33 * Returns: SI_OK if all goes well, SI_ERROR with SIerrno set if there is
35 * Date: 3 February 1995
36 * Author: E. Scott Daniels
38 * Modified: 19 Feb 1995 - To set TP blk to drain if output pending.
39 * 10 May 1995 - To change SOCK_RAW to SOCK_DGRAM
40 * 22 Feb 2002 - To accept TCP_LISTEN_PORT or UDP_PORT as fd
41 ******************************************************************************
45 extern int SIclose( struct ginfo_blk *gptr, int fd )
48 struct tp_blk *tpptr; // pointer into tp list
49 int status = SI_ERROR; // status of processing
51 gptr->sierr = SI_ERR_HANDLE;
52 if( gptr->magicnum == MAGICNUM ) // good cookie at the gptr address?
54 gptr->sierr = SI_ERR_SESSID;
56 if( fd >= 0 ) // if caller knew the fd number
58 for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != fd;
59 tpptr = tpptr->next ); // find the tppblock to close
61 else // user did not know the fd - find first Listener or UDP tp blk
63 if( fd == TCP_LISTEN_PORT ) // close first tcp listen port; else first udp
64 for( tpptr = gptr->tplist; tpptr != NULL && !(tpptr->flags&& TPF_LISTENFD); tpptr = tpptr->next );
66 for( tpptr = gptr->tplist; tpptr != NULL && tpptr->type != SOCK_DGRAM; tpptr = tpptr->next );
71 gptr->sierr = SI_ERR_TP;
73 if( tpptr->squeue == NULL ) // if nothing is queued to send...
75 tpptr->flags |= TPF_UNBIND; // ensure port is unbound from tp
76 tpptr->flags |= TPF_DELETE;
80 setsockopt(tpptr->fd, SOL_SOCKET, SO_LINGER, (char *)&x, sizeof( x ) ) ;
85 // siterm now called in build poll if tp is marked delete
86 // SIterm( gptr, gptr, tpptr );*/ /* cleanup and remove from the list
88 else // stuff queued to send - mark port to drain
89 tpptr->flags |= TPF_DRAIN; // and we will term the port when q empty
91 status = SI_OK; // give caller a good status
92 } // end if we found a tpptr
93 } // end if the handle was good
95 return( status ); // send the status back to the caller