cb5cf36ac7c906f0fbb036b8bf28d5cf6966d778
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / siclose.c
1 // vim: noet sw=4 ts=4:
2 /*
3 ==================================================================================
4     Copyright (c) 2020 Nokia
5     Copyright (c) 2020 AT&T Intellectual Property.
6
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
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
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 ==================================================================================
19 */
20
21 /* X
22 ******************************************************************************
23 *
24 *  Mnemonic: SIclose
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)
32 *            fd   - FD to close.
33 *  Returns:  SI_OK if all goes well, SI_ERROR with SIerrno set if there is
34 *            a problem.
35 *  Date:     3 February 1995
36 *  Author:   E. Scott Daniels
37 *
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 ******************************************************************************
42 */
43 #include "sisetup.h"
44
45 extern int SIclose( struct ginfo_blk *gptr, int fd )
46 {
47
48  struct tp_blk *tpptr;      //  pointer into tp list 
49  int status = SI_ERROR;     //  status of processing 
50
51  gptr->sierr = SI_ERR_HANDLE;
52  if( gptr->magicnum == MAGICNUM )   //  good cookie at the gptr address? 
53   {
54    gptr->sierr = SI_ERR_SESSID;
55
56    if( fd >= 0 )     //  if caller knew the fd number 
57     {
58      for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != fd;
59           tpptr = tpptr->next );   //  find the tppblock to close 
60     }
61    else  //  user did not know the fd - find first Listener or UDP tp blk 
62    {
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 );   
65         else
66                 for( tpptr = gptr->tplist; tpptr != NULL && tpptr->type != SOCK_DGRAM; tpptr = tpptr->next );
67    }
68
69    if( tpptr != NULL )
70     {
71      gptr->sierr = SI_ERR_TP;
72
73      if( tpptr->squeue == NULL )   //  if nothing is queued to send... 
74       {
75        tpptr->flags |= TPF_UNBIND;   //  ensure port is unbound from tp 
76         tpptr->flags |= TPF_DELETE;
77         {
78                 int x = 1;
79
80                 setsockopt(tpptr->fd, SOL_SOCKET, SO_LINGER, (char *)&x, sizeof( x ) ) ;
81         }
82         close( tpptr->fd );
83         tpptr->fd = -1;
84         tpptr->type = -1;
85                         //  siterm now called in build poll if tp is marked delete 
86        // SIterm( gptr, gptr, tpptr );*/        /* cleanup and remove from the list 
87       }
88      else                               //  stuff queued to send - mark port to drain 
89       tpptr->flags |= TPF_DRAIN;   //  and we will term the port when q empty 
90
91      status = SI_OK;               //  give caller a good status 
92     }                              //  end if we found a tpptr 
93   }                                //  end if the handle was good 
94
95  return( status );                 //  send the status back to the caller 
96 }                                  //  SIclose