Allow AFS to shutdown on Solaris (and subsequently be reloaded
[openafs.git] / src / rx / SOLARIS / 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 #ifdef AFS_SUN5_ENV
16 #include "../rx/rx_kcommon.h"
17
18
19 #ifdef AFS_SUN56_ENV
20
21 #include "../inet/common.h"
22 #include "../sys/tiuser.h"
23 #include "../sys/t_kuser.h"
24 #include "../sys/stropts.h"
25 #include "../sys/stream.h"
26 #include "../sys/tihdr.h"
27 #include "../sys/fcntl.h"
28 #ifdef AFS_SUN58_ENV
29 #include "../netinet/ip6.h"
30 #define ipif_local_addr ipif_lcl_addr
31 #ifndef V4_PART_OF_V6
32 #define V4_PART_OF_V6(v6)       v6.s6_addr32[3]
33 #endif
34 #endif
35 #include "../inet/ip.h"
36 #include "../inet/ip_if.h"
37 #include "../netinet/udp.h"
38
39 /*
40  * Function pointers for kernel socket routines
41  */
42 struct sonode *(*sockfs_socreate)
43     (vnode_t *, int, int, int, int, struct sonode *, int *) = NULL;
44 struct vnode *(*sockfs_solookup)
45     (int, int, int, char *, int *) = NULL;
46 int (*sockfs_sobind)
47     (struct sonode *, struct sockaddr *, int, int, int) = NULL;
48 int (*sockfs_sorecvmsg)
49     (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
50 int (*sockfs_sosendmsg)
51     (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
52 int (*sockfs_sosetsockopt)
53     (struct sonode *, int, int, void *, int) = NULL;
54 int (*sockfs_sounbind)
55     (struct sonode *, int);
56 void (*sockfs_sockfree)
57     (struct sonode *);
58
59 static afs_uint32 myNetAddrs[ADDRSPERSITE];
60 static int myNetMTUs[ADDRSPERSITE];
61 static int numMyNetAddrs = 0;
62
63 int
64 rxi_GetIFInfo()
65 {
66     int i = 0;
67     int different = 0;
68
69     ill_t *ill;
70     ipif_t *ipif;
71     int rxmtu, maxmtu;
72
73     int mtus[ADDRSPERSITE];
74     afs_uint32 addrs[ADDRSPERSITE];
75     afs_uint32 ifinaddr;
76
77     memset(mtus, 0, sizeof(mtus));
78     memset(addrs, 0, sizeof(addrs));
79
80     for (ill = ill_g_head; ill; ill = ill->ill_next) {
81 #ifdef AFS_SUN58_ENV
82         /* Make sure this is an IPv4 ILL */
83         if (ill->ill_isv6) continue;
84 #endif
85
86         /* Iterate over all the addresses on this ILL */
87         for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
88             if (i >= ADDRSPERSITE) break;
89
90             /* Ignore addresses which are down.. */
91             if (!(ipif->ipif_flags & IFF_UP)) continue;
92
93             /* Compute the Rx interface MTU */
94             rxmtu = (ipif->ipif_mtu - RX_IPUDP_SIZE);
95
96             ifinaddr = ntohl(ipif->ipif_local_addr);
97             if (myNetAddrs[i] != ifinaddr)
98                 different++;
99
100             /* Copy interface MTU and address; adjust maxmtu */
101             mtus[i] = rxmtu;
102             rxmtu = rxi_AdjustIfMTU(rxmtu);
103             maxmtu = rxmtu * rxi_nRecvFrags + ((rxi_nRecvFrags-1) *
104                                                UDP_HDR_SIZE);
105             maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
106             addrs[i] = ifinaddr;
107             i++;
108
109             if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
110                 rx_maxReceiveSize = MIN( RX_MAX_PACKET_SIZE, maxmtu);
111                 rx_maxReceiveSize = MIN( rx_maxReceiveSize,
112                                          rx_maxReceiveSizeUser);
113             }
114         }
115     }
116
117     rx_maxJumboRecvSize = RX_HEADER_SIZE +
118                           rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
119                           (rxi_nDgramPackets-1) * RX_JUMBOHEADERSIZE;
120     rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
121
122     if (different) {
123         int j;
124
125         for (j = 0; j < i; j++) {
126             myNetMTUs[j] = mtus[j];
127             myNetAddrs[j] = addrs[j];
128         }
129     }
130
131     return different;
132 }
133
134 int
135 rxi_FindIfMTU(addr)
136     afs_uint32 addr;
137 {
138     ill_t *ill;
139     ipif_t *ipif;
140     afs_uint32 myAddr, netMask;
141     int match_value = 0;
142     int mtu = -1;
143
144     if (numMyNetAddrs == 0)
145         rxi_GetIFInfo();
146     myAddr = ntohl(addr);
147
148     if      (IN_CLASSA(myAddr)) netMask = IN_CLASSA_NET;
149     else if (IN_CLASSB(myAddr)) netMask = IN_CLASSB_NET;
150     else if (IN_CLASSC(myAddr)) netMask = IN_CLASSC_NET;
151     else                       netMask = 0;
152
153     for (ill = ill_g_head; ill; ill = ill->ill_next) {
154 #ifdef AFS_SUN58_ENV
155         /* Make sure this is an IPv4 ILL */
156         if (ill->ill_isv6) continue;
157 #endif
158
159         /* Iterate over all the addresses on this ILL */
160         for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
161             afs_uint32 thisAddr, subnetMask;
162             int thisMtu;
163
164             thisAddr   = ipif->ipif_local_addr;
165             subnetMask = ipif->ipif_net_mask;
166             thisMtu    = ipif->ipif_mtu;
167
168             if ((myAddr & netMask) == (thisAddr & netMask)) {
169                 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
170                     if (myAddr == thisAddr) {
171                         match_value = 4;
172                         mtu = thisMtu;
173                     }
174
175                     if (match_value < 3) {
176                         match_value = 3;
177                         mtu = thisMtu;
178                     }
179                 }
180
181                 if (match_value < 2) {
182                     match_value = 2;
183                     mtu = thisMtu;
184                 }
185             }
186         }
187     }
188
189     return mtu;
190 }
191
192 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
193  * afs_osinet.c. 
194  */
195
196 struct sockaddr_in rx_sockaddr;
197
198 /* Allocate a new socket at specified port in network byte order. */
199 struct osi_socket *rxk_NewSocket(short aport)
200 {
201     vnode_t *accessvp;
202     struct sonode *so;
203     struct sockaddr_in addr;
204     int error;
205     int len;
206
207     AFS_STATCNT(osi_NewSocket);
208
209     if (sockfs_solookup == NULL) {
210         sockfs_solookup = (struct vnode *(*)())modlookup("sockfs", "solookup");
211         if (sockfs_solookup == NULL) {
212             return NULL;
213         }
214     }
215     if (sockfs_socreate == NULL) {
216         sockfs_socreate = (struct sonode *(*)())modlookup("sockfs", "socreate");
217         if (sockfs_socreate == NULL) {
218             return NULL;
219         }
220     }
221     if (sockfs_sobind == NULL) {
222         sockfs_sobind = (int (*)())modlookup("sockfs", "sobind");
223         if (sockfs_sobind == NULL) {
224             return NULL;
225         }
226     }
227     if (sockfs_sosetsockopt == NULL) {
228         sockfs_sosetsockopt = (int (*)())modlookup("sockfs", "sosetsockopt");
229         if (sockfs_sosetsockopt == NULL) {
230             return NULL;
231         }
232     }
233     if (sockfs_sosendmsg == NULL) {
234         sockfs_sosendmsg = (int (*)())modlookup("sockfs", "sosendmsg");
235         if (sockfs_sosendmsg == NULL) {
236             return NULL;
237         }
238     }
239     if (sockfs_sorecvmsg == NULL) {
240         sockfs_sorecvmsg = (int (*)())modlookup("sockfs", "sorecvmsg");
241         if (sockfs_sorecvmsg == NULL) {
242             return NULL;
243         }
244     }
245     if (sockfs_sounbind == NULL) {
246         sockfs_sounbind = (int (*)())modlookup("sockfs", "sounbind");
247         if (sockfs_sounbind == NULL)
248             return NULL;
249     }
250     if (sockfs_sockfree == NULL) {
251         sockfs_sockfree = (void (*)())modlookup("sockfs", "sockfree");
252         if (sockfs_sockfree == NULL)
253             return NULL;
254     }
255
256     accessvp = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, "/dev/udp", &error);
257     if (accessvp == NULL) {
258         return NULL;
259     }
260
261     so = sockfs_socreate(accessvp, AF_INET, SOCK_DGRAM, 0,
262                          SOV_STREAM, NULL, &error);
263     if (so == NULL) {
264         return NULL;
265     }
266
267     addr.sin_family = AF_INET;
268     addr.sin_port = aport;
269     addr.sin_addr.s_addr = INADDR_ANY;
270     error = sockfs_sobind(so, (struct sockaddr *)&addr, sizeof(addr), 0, 0);
271     if (error != 0) {
272         return NULL;
273     }
274
275     len = rx_UdpBufSize;
276     error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len));
277     if (error != 0) {
278         return NULL;
279     }
280
281     len = rx_UdpBufSize;
282     error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
283     if (error != 0) {
284         return NULL;
285     }
286
287     return (struct osi_socket *)so;
288 }
289
290 int osi_FreeSocket(asocket)
291     register struct osi_socket *asocket; 
292 {
293     extern int rxk_ListenerPid;
294     struct sonode *so = (struct sonode *)asocket;
295     vnode_t *vp = SOTOV(so);
296
297     AFS_STATCNT(osi_FreeSocket);
298     while (rxk_ListenerPid) {
299         kill(rxk_ListenerPid, SIGUSR1);
300         afs_osi_Sleep(&rxk_ListenerPid);
301     }
302
303     sockfs_sounbind(so, 0);
304     sockfs_sockfree(so);
305     return 0;
306 }
307
308 int osi_NetSend(asocket, addr, dvec, nvecs, asize, istack) 
309     struct osi_socket *asocket;
310     struct sockaddr_in *addr; 
311     struct iovec dvec[];
312     int nvecs;
313     afs_int32 asize;
314     int istack;
315 {
316     struct sonode *so = (struct sonode *)asocket;
317     struct nmsghdr msg;
318     struct uio uio;
319     struct iovec iov[RX_MAXIOVECS];
320     int error;
321     int i;
322  
323     if (nvecs > RX_MAXIOVECS) {
324         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
325     }
326
327     msg.msg_name = (struct sockaddr *)addr;
328     msg.msg_namelen = sizeof(struct sockaddr_in);
329     msg.msg_iov = dvec;
330     msg.msg_iovlen = nvecs;
331     msg.msg_control = NULL;
332     msg.msg_controllen = 0;
333     msg.msg_flags = 0;
334
335     for (i = 0 ; i < nvecs ; i++) {
336         iov[i].iov_base = dvec[i].iov_base;
337         iov[i].iov_len = dvec[i].iov_len;
338     }
339     uio.uio_iov = &iov[0];
340     uio.uio_iovcnt = nvecs;
341     uio.uio_loffset = 0;
342     uio.uio_segflg = UIO_SYSSPACE;
343     uio.uio_fmode = FREAD|FWRITE;
344     uio.uio_limit = 0;
345     uio.uio_resid = asize;
346
347     error = sockfs_sosendmsg(so, &msg, &uio);
348
349     return error;
350 }
351
352 int osi_NetReceive(asocket, addr, dvec, nvecs, alength)
353     struct osi_socket *asocket;
354     struct sockaddr_in *addr;
355     struct iovec *dvec;
356     int nvecs;
357     int *alength;
358 {
359     struct sonode *so = (struct sonode *)asocket;
360     struct nmsghdr msg;
361     struct uio uio;
362     struct iovec iov[RX_MAXIOVECS];
363     int error;
364     int i;
365  
366     if (nvecs > RX_MAXIOVECS) {
367         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
368     }
369
370     msg.msg_name = NULL;
371     msg.msg_namelen = sizeof(struct sockaddr_in);
372     msg.msg_iov = NULL;
373     msg.msg_iovlen = 0;
374     msg.msg_control = NULL;
375     msg.msg_controllen = 0;
376     msg.msg_flags = 0;
377
378     for (i = 0 ; i < nvecs ; i++) {
379         iov[i].iov_base = dvec[i].iov_base;
380         iov[i].iov_len = dvec[i].iov_len;
381     }
382     uio.uio_iov = &iov[0];
383     uio.uio_iovcnt = nvecs;
384     uio.uio_loffset = 0;
385     uio.uio_segflg = UIO_SYSSPACE;
386     uio.uio_fmode = 0;
387     uio.uio_limit = 0;
388     uio.uio_resid = *alength;
389
390     error = sockfs_sorecvmsg(so, &msg, &uio);
391     if (error == 0) {
392         if (msg.msg_name == NULL) {
393             error = -1;
394         } else {
395             memcpy(addr, msg.msg_name, msg.msg_namelen);
396             kmem_free(msg.msg_name, msg.msg_namelen);
397             *alength = *alength - uio.uio_resid;
398         }
399     }
400
401     if (error == EINTR && ISSIG(curthread, FORREAL)) {
402         klwp_t *lwp = ttolwp(curthread);
403         proc_t *p = ttoproc(curthread);
404         int sig = lwp->lwp_cursig;
405
406         if (sig == SIGKILL) {
407             mutex_enter(&p->p_lock);
408             p->p_flag &= ~SKILLED;
409             mutex_exit(&p->p_lock);
410         }
411         lwp->lwp_cursig = 0;
412         if (lwp->lwp_curinfo) {
413             siginfofree(lwp->lwp_curinfo);
414             lwp->lwp_curinfo = NULL;
415         }
416     }
417
418     return error;
419 }
420
421 void shutdown_rxkernel(void)
422 {
423 }
424
425 void osi_StopListener(void)
426 {
427     osi_FreeSocket(rx_socket);
428 }
429
430 #else /* AFS_SUN56_ENV */
431
432 #include "../inet/common.h"
433 #include "../sys/tiuser.h"
434 #include "../sys/t_kuser.h"
435 #include "../sys/ioctl.h"
436 #include "../sys/stropts.h"
437 #include "../sys/stream.h"
438 #include "../sys/strsubr.h"
439 #include "../sys/vnode.h"
440 #include "../sys/stropts.h"
441 #include "../sys/tihdr.h"
442 #include "../sys/timod.h"
443 #include "../sys/fcntl.h"
444 #include "../sys/debug.h"
445 #include "../inet/common.h"
446 #include "../inet/mi.h"
447 #include "../netinet/udp.h"
448
449 extern dev_t afs_udp_rdev;
450
451
452 int rxi_GetIFInfo()
453 {
454     return 0;
455 }
456
457
458 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
459  * afs_osinet.c. 
460  */
461
462 dev_t afs_udp_rdev = (dev_t)0;
463
464 /* Allocate a new socket at specified port in network byte order. */
465 struct osi_socket *rxk_NewSocket(short aport)
466 {
467     TIUSER *udp_tiptr;
468     struct t_bind *reqp, *rspp;
469     afs_int32 code;
470     struct sockaddr_in *myaddrp;
471     struct stdata *stp;
472     struct queue *q;
473
474     AFS_STATCNT(osi_NewSocket);
475     afs_udp_rdev = makedevice(11 /*CLONE*/, ddi_name_to_major("udp"));
476     code = t_kopen(NULL, afs_udp_rdev, FREAD|FWRITE, &udp_tiptr, CRED());
477     if (code) {
478         return (struct osi_socket *)0;
479     }
480
481     code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&reqp);
482     if (code) {
483         t_kclose(udp_tiptr, 0);
484     }
485     code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&rspp);
486     if (code) {
487         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
488         t_kclose(udp_tiptr, 0);
489         return (struct osi_socket *)0;
490     }
491
492     reqp->addr.len = sizeof(struct sockaddr_in);
493     myaddrp = (struct sockaddr_in *) reqp->addr.buf;
494     myaddrp->sin_family = AF_INET;
495     myaddrp->sin_port = aport;
496     myaddrp->sin_addr.s_addr = INADDR_ANY;      /* XXX Was 0 XXX */
497
498     code = t_kbind(udp_tiptr, reqp, rspp);
499     if (code) {
500         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
501         t_kfree(udp_tiptr, (char *)rspp, T_BIND);
502         t_kclose(udp_tiptr, 0);
503         return (struct osi_socket *)0;
504     }
505     if (memcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
506         t_kfree(udp_tiptr, (char *)reqp, T_BIND);
507         t_kfree(udp_tiptr, (char *)rspp, T_BIND);
508         t_kclose(udp_tiptr, 0);
509         return (struct osi_socket *)0;
510     }
511     t_kfree(udp_tiptr, (char *)reqp, T_BIND);
512     t_kfree(udp_tiptr, (char *)rspp, T_BIND);
513
514     /*
515      * Set the send and receive buffer sizes.
516      */
517     stp = udp_tiptr->fp->f_vnode->v_stream;
518     q = stp->sd_wrq;
519     q->q_hiwat = rx_UdpBufSize;
520     q->q_next->q_hiwat = rx_UdpBufSize;
521     RD(q)->q_hiwat = rx_UdpBufSize;
522
523     return (struct osi_socket *) udp_tiptr;
524 }
525
526
527 int osi_FreeSocket(asocket)
528     register struct osi_socket *asocket; 
529 {
530     extern int rxk_ListenerPid;
531     TIUSER *udp_tiptr = (TIUSER *) asocket;    
532     AFS_STATCNT(osi_FreeSocket);
533
534     if (rxk_ListenerPid) {
535         kill(rxk_ListenerPid, SIGUSR1);
536         afs_osi_Sleep(&rxk_ListenerPid);
537     }
538     return 0;
539 }
540
541
542 int osi_NetSend(asocket, addr, dvec, nvecs, asize, istack) 
543     register struct osi_socket *asocket;
544     struct iovec dvec[];
545     int nvecs;
546     register afs_int32 asize;
547     struct sockaddr_in *addr; 
548     int istack;
549 {
550     int i;
551     int code;
552     TIUSER *udp_tiptr = (TIUSER *) asocket;    
553     struct t_kunitdata *udreq;
554     struct sockaddr_in sin;
555     mblk_t *bp;
556     mblk_t *dbp;
557
558     /*
559      * XXX We don't do any checking on the family since it's assumed to be
560      * AF_INET XXX
561      */
562     sin.sin_family = AF_INET;
563     sin.sin_addr.s_addr = addr->sin_addr.s_addr;
564     sin.sin_port = addr->sin_port;
565
566     /*
567      * Get a buffer for the RX header
568      */
569     if (nvecs < 1) {
570         osi_Panic("osi_NetSend, nvecs=%d\n", nvecs);
571     }
572     while (!(bp = allocb(dvec[0].iov_len, BPRI_LO))) {
573         if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
574             return (ENOSR);
575         }
576     }
577
578     /* Copy the data into the buffer */
579     memcpy((char *)bp->b_wptr, (char *)dvec[0].iov_base, dvec[0].iov_len);
580     bp->b_datap->db_type = M_DATA;
581     bp->b_wptr += dvec[0].iov_len;
582
583     /*
584      * Append each element in the iovec to the buffer
585      */
586     for (i = 1 ; i < nvecs ; i++) {
587         /* Get a buffer for the next chunk */
588         while (!(dbp = allocb(dvec[i].iov_len, BPRI_LO))) {
589             if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
590                 freeb(bp);
591                 return (ENOSR);
592             }
593         }
594
595         /* Copy the data into the buffer */
596         memcpy((char *)dbp->b_wptr, (char *)dvec[i].iov_base, dvec[i].iov_len);
597         dbp->b_datap->db_type = M_DATA;
598         dbp->b_wptr += dvec[i].iov_len;
599
600         /* Append it to the message buffer */
601         linkb(bp, dbp);
602     }
603
604     /*
605      * Allocate and format the unitdata structure.
606      */
607     code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
608     if (code) {
609         freeb(bp);
610         printf("osi_NetSend: t_kalloc failed %d\n", code);
611         return code;
612     }
613     udreq->addr.len = sizeof(struct sockaddr_in);
614     udreq->addr.maxlen = sizeof(struct sockaddr_in);
615     udreq->addr.buf = (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
616     udreq->opt.len = 0;
617     udreq->opt.maxlen = 0;
618     memcpy(udreq->addr.buf, (char *)&sin, sizeof(struct sockaddr_in));
619     udreq->udata.udata_mp = bp;
620     udreq->udata.len = asize;
621
622     code = t_ksndudata(udp_tiptr, udreq, NULL);
623     if (code) {
624         printf("osi_NetSend: t_ksndudata failed %d\n", code);
625     }
626
627     t_kfree(udp_tiptr, (caddr_t)udreq, T_UNITDATA);
628     return code;
629 }
630
631
632 int osi_NetReceive(asocket, addr, dvec, nvecs, alength)
633     struct osi_socket *asocket;
634     struct sockaddr_in *addr;
635     struct iovec *dvec;
636     int nvecs;
637     int *alength;
638 {
639     int i;
640     TIUSER *udp_tiptr = (TIUSER *) asocket;    
641     struct t_kunitdata *udreq;
642     mblk_t *dbp;
643     char *phandle;
644     short sport;
645     int code = 0;
646     int length;
647     int tlen;
648     int blen;
649     char *tbase;
650     int type;
651     int error;
652     int events;
653
654     /*
655      * Allocate the unitdata structure.
656      */
657     code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
658     if (code) {
659         printf("osi_NetReceive: t_kalloc failed %d\n", code);
660         return code;
661     }
662     udreq->addr.len = sizeof(struct sockaddr_in);
663     udreq->addr.maxlen = sizeof(struct sockaddr_in);
664     udreq->addr.buf = (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
665     udreq->opt.len = 0;
666     udreq->opt.maxlen = 0;
667
668     /*
669      * Loop until we get an error or receive some data.
670      */
671     while(1) {
672         /*
673          * Wait until there is something to do
674          */
675         code = t_kspoll(udp_tiptr, -1, READWAIT, &events);
676         if (events == 0) {
677             osi_Panic("osi_NetReceive, infinite t_kspoll timed out\n");
678         }
679         /*
680          * If there is a message then read it in
681          */
682         if (code == 0) {
683             code = t_krcvudata(udp_tiptr, udreq, &type, &error);
684         }
685
686         /*
687          * Block attempts to kill this thread
688          */
689         if (code == EINTR && ISSIG(curthread, FORREAL)) {
690             klwp_t *lwp = ttolwp(curthread);
691             proc_t *p = ttoproc(curthread);
692             int sig = lwp->lwp_cursig;
693
694             if (sig == SIGKILL) {
695                 mutex_enter(&p->p_lock);
696                 p->p_flag &= ~SKILLED;
697                 mutex_exit(&p->p_lock);
698             }
699             lwp->lwp_cursig = 0;
700             if (lwp->lwp_curinfo) {
701                 kmem_free((caddr_t)lwp->lwp_curinfo, sizeof(*lwp->lwp_curinfo));
702                 lwp->lwp_curinfo = NULL;
703             }
704         }
705
706         if (code) {
707             break;
708         }
709
710         /*
711          * Ignore non-data message types
712          */
713         if (type != T_DATA) {
714             continue;
715         }
716
717         /*
718          * Save the source address
719          */
720         memcpy((char *)addr, udreq->addr.buf, sizeof(struct sockaddr_in));
721
722         /*
723          * Copy out the message buffers, take care not to overflow
724          * the I/O vector.
725          */
726         dbp = udreq->udata.udata_mp;
727         length = *alength;
728         for (i = 0 ; dbp != NULL && length > 0 && i < nvecs ; i++) {
729             tlen = dvec[i].iov_len;
730             tbase = dvec[i].iov_base;
731             if (tlen > length) {
732                 tlen = length;
733             }
734             while (dbp != NULL && tlen > 0) {
735                 blen = dbp->b_wptr - dbp->b_rptr;
736                 if (blen > tlen) {
737                     memcpy(tbase, (char *)dbp->b_rptr, tlen);
738                     length -= tlen;
739                     dbp->b_rptr += tlen;
740                     tlen = 0;
741                 } else {
742                     memcpy(tbase, (char *)dbp->b_rptr, blen);
743                     length -= blen;
744                     tlen -= blen;
745                     tbase += blen;
746                     dbp = dbp->b_cont;
747                 }
748             }
749         }
750         *alength = *alength - length;
751         break;
752     }
753
754     t_kfree(udp_tiptr, (caddr_t)udreq, T_UNITDATA);
755     return code;
756 }
757
758
759 void osi_StopListener(void)
760 {
761     osi_FreeSocket(rx_socket);
762 }
763
764
765 void shutdown_rxkernel(void)
766 {
767 }
768
769
770 #endif /* AFS_SUN56_ENV */
771 #endif /* AFS_SUN5_ENV */