Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / rx / rx_xmit_nt.c
1 /* Copyright 1998 - Transarc Corporation */
2
3
4 /* NT does not have uio structs, so we roll our own sendmsg and recvmsg.
5  *
6  * The dangerous part of this code is that it assumes that iovecs 0 and 1
7  * are contiguous and that all of 0 is used before any of 1.
8  * This is true if rx_packets are being sent, so we should be ok.
9  */
10
11 #include <afs/param.h>
12 #ifdef AFS_NT40_ENV
13
14 #include <winsock2.h>
15
16 #include "rx.h"
17 #include "rx_packet.h"
18 #include "rx_globals.h"
19 #include "rx_xmit_nt.h"
20 #include <malloc.h>
21 #include <errno.h>
22
23 int recvmsg(int socket, struct msghdr *msgP, int flags)
24 {
25     char rbuf[RX_MAX_PACKET_SIZE];
26     int size;
27     int code;
28     int off, i, n;
29     int allocd = 0;
30
31
32     size = rx_maxJumboRecvSize;
33     code = recvfrom((SOCKET)socket, rbuf, size, flags,
34                     (struct sockaddr*)(msgP->msg_name),
35                     &(msgP->msg_namelen));
36
37     if (code>0) {
38         size = code;
39         
40         for (off = i = 0; size > 0 && i<msgP->msg_iovlen; i++) {
41             if (msgP->msg_iov[i].iov_len) {
42                 if (msgP->msg_iov[i].iov_len < size) {
43                     n = msgP->msg_iov[i].iov_len;
44                 }
45                 else {
46                     n = size;
47                 }
48                 memcpy(msgP->msg_iov[i].iov_base, &rbuf[off], n);
49                 off += n;
50                 size -= n;
51             }
52         }
53
54         /* Accounts for any we didn't copy in to iovecs. */
55         code -= size;
56     }
57     else {
58         code = -1;
59     }
60
61     return code;
62 }
63
64 int sendmsg(int socket, struct msghdr *msgP, int flags)
65 {
66     char buf[RX_MAX_PACKET_SIZE];
67     char *sbuf=buf;
68     int size, tmp;
69     int code;
70     int off, i, n;
71     int allocd = 0;
72
73     for (size = i = 0; i<msgP->msg_iovlen; i++)
74         size += msgP->msg_iov[i].iov_len;
75          
76     if (msgP->msg_iovlen <= 2) {
77         sbuf = msgP->msg_iov[0].iov_base;
78     }
79     else {
80         /* Pack data into array from iovecs */
81         tmp = size;
82         for (off = i = 0; tmp > 0 && i<msgP->msg_iovlen; i++) {
83             if (msgP->msg_iov[i].iov_len > 0 ) {
84                 if (tmp > msgP->msg_iov[i].iov_len)
85                     n = msgP->msg_iov[i].iov_len;
86                 else
87                     n = tmp;
88                 memcpy(&sbuf[off], msgP->msg_iov[i].iov_base, n);
89                 off += n;
90                 tmp -= n;
91             }
92         }
93     }
94
95     code = sendto((SOCKET)socket, sbuf, size, flags,
96                   (struct sockaddr*)(msgP->msg_name), msgP->msg_namelen);
97
98     if (code == SOCKET_ERROR) {
99         code = WSAGetLastError();
100         switch (code) {
101         case WSAEINPROGRESS:
102         case WSAENETRESET:
103         case WSAEWOULDBLOCK:
104         case WSAENOBUFS:
105             errno = 0;
106             break;
107         default:
108             errno = EIO;
109             break;
110         }
111         code = -1;
112     }
113
114     if (code < size) {
115         errno = EIO;
116         code = -1;
117     }
118
119     return code;
120
121 }
122
123
124
125
126 #endif