Rcompat.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:6k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. static const char rcsid[] =
  45. "$Id: Rcompat.c,v 1.12 1999/05/14 13:58:19 michaels Exp $";
  46. int
  47. Rselect(nfds, readfds, writefds, exceptfds, timeout)
  48. int nfds;
  49. fd_set *readfds;
  50. fd_set *writefds;
  51. fd_set *exceptfds;
  52. struct timeval *timeout;
  53. {
  54. return select(nfds, readfds, writefds, exceptfds, timeout);
  55. }
  56. int
  57. Rlisten(s, backlog)
  58. int s;
  59. int backlog;
  60. {
  61. return listen(s, backlog);
  62. }
  63. ssize_t
  64. Rwrite(d, buf, nbytes)
  65. int d;
  66. const void *buf;
  67. size_t nbytes;
  68. {
  69. return Rsend(d, buf, nbytes, 0);
  70. }
  71. ssize_t
  72. Rwritev(d, iov, iovcnt)
  73. int d;
  74. const struct iovec *iov;
  75. int iovcnt;
  76. {
  77. static const struct msghdr msginit;
  78. struct msghdr msg;
  79. msg = msginit;
  80. /* LINTED operands have incompatible pointer types */
  81. msg.msg_iov = (const struct iovec *)iov;
  82. msg.msg_iovlen = iovcnt;
  83. return Rsendmsg(d, &msg, 0);
  84. }
  85. ssize_t
  86. Rsend(s, msg, len, flags)
  87. int s;
  88. const void *msg;
  89. size_t len;
  90. int flags;
  91. {
  92. static const struct msghdr msghdrinit;
  93. struct msghdr msghdr;
  94. struct iovec iov;
  95. /* LINTED operands have incompatible pointer types */
  96. iov.iov_base = (const void *)msg;
  97. iov.iov_len = len;
  98. msghdr = msghdrinit;
  99. msghdr.msg_iov = &iov;
  100. msghdr.msg_iovlen = 1;
  101. return Rsendmsg(s, &msghdr, flags);
  102. }
  103. ssize_t
  104. Rsendmsg(s, msg, flags)
  105. int s;
  106. const struct msghdr *msg;
  107. int flags;
  108. {
  109. size_t sent, ioc;
  110. ssize_t rc;
  111. struct sockaddr name;
  112. socklen_t namelen;
  113. namelen = sizeof(name);
  114. if (getsockname(s, &name, &namelen) == -1) {
  115. errno = 0;
  116. return writev(s, msg->msg_iov, (int)msg->msg_iovlen);
  117. }
  118. switch (name.sa_family) {
  119. case AF_INET:
  120. break;
  121. #ifdef AF_INET6
  122. case AF_INET6:
  123. break;
  124. #endif /* AF_INET6 */
  125. default:
  126. return sendmsg(s, msg, flags);
  127. }
  128. for (sent = ioc = rc = 0; ioc < msg->msg_iovlen; ++ioc) {
  129. /* LINTED pointer casts may be troublesome */
  130. if ((rc = Rsendto(s, msg->msg_iov[ioc].iov_base,
  131. msg->msg_iov[ioc].iov_len, flags, (struct sockaddr *)msg->msg_name,
  132. msg->msg_namelen)) == -1)
  133. break;
  134. sent += rc;
  135. if (rc != (ssize_t)msg->msg_iov[ioc].iov_len)
  136. break;
  137. }
  138. if (sent == 0)
  139. return rc;
  140. return sent;
  141. }
  142. ssize_t
  143. Rread(d, buf, nbytes)
  144. int d;
  145. void *buf;
  146. size_t nbytes;
  147. {
  148. return Rrecv(d, buf, nbytes, 0);
  149. }
  150. ssize_t
  151. Rreadv(d, iov, iovcnt)
  152. int d;
  153. const struct iovec *iov;
  154. int iovcnt;
  155. {
  156. static const struct msghdr msghdrinit;
  157. struct msghdr msg;
  158. msg = msghdrinit;
  159. /* LINTED operands have incompatible pointer types */
  160. msg.msg_iov = (const struct iovec *)iov;
  161. msg.msg_iovlen = iovcnt;
  162. return Rrecvmsg(d, &msg, 0);
  163. }
  164. ssize_t
  165. Rrecv(s, msg, len, flags)
  166. int s;
  167. void *msg;
  168. size_t len;
  169. int flags;
  170. {
  171. static const struct msghdr msghdrinit;
  172. struct msghdr msghdr;
  173. struct iovec iov;
  174. /* LINTED cast discards 'const' from pointer target type */
  175. iov.iov_base = (void *)msg;
  176. iov.iov_len = len;
  177. msghdr = msghdrinit;
  178. msghdr.msg_iov = &iov;
  179. msghdr.msg_iovlen = 1;
  180. return Rrecvmsg(s, &msghdr, flags);
  181. }
  182. ssize_t
  183. Rrecvmsg(s, msg, flags)
  184. int s;
  185. struct msghdr *msg;
  186. int flags;
  187. {
  188. size_t received, ioc;
  189. ssize_t rc;
  190. struct sockaddr name;
  191. socklen_t namelen;
  192. namelen = sizeof(name);
  193. if (getsockname(s, &name, &namelen) == -1) {
  194. errno = 0;
  195. return readv(s, msg->msg_iov, (int)msg->msg_iovlen);
  196. }
  197. switch (name.sa_family) {
  198. case AF_INET:
  199. break;
  200. #ifdef AF_INET6
  201. case AF_INET6:
  202. break;
  203. #endif /* AF_INET6 */
  204. default:
  205. return recvmsg(s, msg, flags);
  206. }
  207. for (received = ioc = rc = 0; ioc < msg->msg_iovlen; ++ioc) {
  208. /* LINTED pointer casts may be troublesome */
  209. if ((rc = Rrecvfrom(s, msg->msg_iov[ioc].iov_base,
  210. msg->msg_iov[ioc].iov_len, flags, (struct sockaddr *)msg->msg_name,
  211. &msg->msg_namelen)) == -1)
  212. break;
  213. received += rc;
  214. if (rc != (ssize_t)msg->msg_iov[ioc].iov_len)
  215. break;
  216. }
  217. if (received == 0)
  218. return rc;
  219. return received;
  220. }