fix-netreceive-memleak-20030130
[openafs.git] / src / rx / DARWIN / rx_knet.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 RCSID("$Header$");
14
15 #include "rx/rx_kcommon.h"
16
17 int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
18                    int nvecs, int *alength)
19 {
20     struct socket *asocket = (struct socket *)so;
21     struct uio u;
22     int i;
23     struct iovec iov[RX_MAXIOVECS];
24     struct sockaddr *sa = NULL;
25     int code;
26
27     int haveGlock = ISAFS_GLOCK();
28     /*AFS_STATCNT(osi_NetReceive);*/
29
30     if (nvecs > RX_MAXIOVECS)
31         osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
32
33     for (i = 0 ; i < nvecs ; i++)
34         iov[i] = dvec[i];
35
36     u.uio_iov = &iov[0];
37     u.uio_iovcnt = nvecs;
38     u.uio_offset = 0;
39     u.uio_resid = *alength;
40     u.uio_segflg = UIO_SYSSPACE;
41     u.uio_rw = UIO_READ;
42     u.uio_procp = NULL;
43
44     if (haveGlock)
45         AFS_GUNLOCK();
46 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
47     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
48 #endif
49     code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
50 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
51     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
52 #endif
53     if (haveGlock)
54         AFS_GLOCK();
55
56     if (code)
57         return code;
58     *alength -= u.uio_resid;
59     if (sa) {
60         if (sa->sa_family == AF_INET) {
61             if (addr)
62                 *addr = *(struct sockaddr_in *) sa;
63         } else
64             printf("Unknown socket family %d in NetReceive\n", sa->sa_family);
65         FREE(sa, M_SONAME);
66     }
67     return code;
68 }
69
70 extern int rxk_ListenerPid;
71 void osi_StopListener(void)
72 {
73     struct proc *p;
74
75 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
76     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
77 #endif
78     soclose(rx_socket);
79 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
80     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
81 #endif
82     p=pfind(rxk_ListenerPid); 
83     if (p)
84         psignal(p, SIGUSR1);
85 }
86
87 int 
88 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
89             struct iovec *dvec, int nvecs, afs_int32 alength, int istack)
90 {
91     register afs_int32 code;
92     int i;
93     struct iovec iov[RX_MAXIOVECS];
94     struct uio u;
95     int haveGlock = ISAFS_GLOCK();
96
97     AFS_STATCNT(osi_NetSend);
98     if (nvecs > RX_MAXIOVECS)
99         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
100
101     for (i = 0 ; i < nvecs ; i++)
102         iov[i] = dvec[i];
103
104     u.uio_iov = &iov[0];
105     u.uio_iovcnt = nvecs;
106     u.uio_offset = 0;
107     u.uio_resid = alength;
108     u.uio_segflg = UIO_SYSSPACE;
109     u.uio_rw = UIO_WRITE;
110     u.uio_procp = NULL;
111
112     addr->sin_len = sizeof(struct sockaddr_in);
113
114     if (haveGlock)
115         AFS_GUNLOCK();
116 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
117     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
118 #endif
119     code = sosend(asocket, (struct sockaddr *) addr, &u, NULL, NULL, 0);
120 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
121     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
122 #endif
123     if (haveGlock)
124         AFS_GLOCK();
125     return code;
126 }