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

代理服务器

开发平台:

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: io.c,v 1.39 1999/09/02 10:41:37 michaels Exp $";
  46. /* this file defines the functions. */
  47. #undef select
  48. #undef close
  49. ssize_t
  50. readn(d, buf, nbytes)
  51. int d;
  52. void *buf;
  53. size_t nbytes;
  54. {
  55. ssize_t p;
  56. size_t left = nbytes;
  57. do {
  58. if ((p = read(d, &((char *)buf)[nbytes - left], left)) == -1) {
  59. #if SOCKS_SERVER
  60. if (errno == EINTR)
  61. continue;
  62. #endif
  63. break;
  64. }
  65. else if (p == 0)
  66. break;
  67. left -= p;
  68. } while (left > 0);
  69. if (left == nbytes)
  70. return p; /* nothing read. */
  71. return nbytes - left;
  72. }
  73. ssize_t
  74. writen(d, buf, nbytes)
  75. int d;
  76. const void *buf;
  77. size_t nbytes;
  78. {
  79. ssize_t p;
  80. size_t left = nbytes;
  81. do {
  82. if ((p = write(d, &((const char *)buf)[nbytes - left], left)) == -1) {
  83. #if SOCKS_SERVER
  84. if (errno == EINTR)
  85. continue;
  86. #endif
  87. break;
  88. }
  89. left -= p;
  90. } while (left > 0);
  91. if (left == nbytes)
  92. return p; /* nothing written. */
  93. return nbytes - left;
  94. }
  95. ssize_t
  96. recvmsgn(s, msg, flags, len)
  97. int s;
  98. struct msghdr *msg;
  99. int flags;
  100. size_t len;
  101. {
  102. size_t left = len;
  103. ssize_t p;
  104. while ((p = recvmsg(s, msg, flags)) == -1 && errno == EINTR)
  105. #if SOCKS_SERVER
  106. ;
  107. #else
  108. return -1;
  109. #endif
  110. #if HAVE_SOLARIS_BUGS
  111. if (p == -1 && (errno == EMFILE || errno == ENFILE)) {
  112. /*
  113.  * Even if solaris (2.5.1) fails on recvmsg() it may still have
  114.  * gotten a descriptor or more as ancillary data which it neglects
  115.  * to get rid of, so we have to check for it ourselves and close it,
  116.  * else it just gets lost in the void.
  117.  */
  118. int i, leaked;
  119. caddr_t mem;
  120. mem = msg->msg_accrights;
  121. for (i = 0; i * sizeof(leaked) < msg->msg_accrightslen; ++i) {
  122. memcpy(&leaked, mem, sizeof(leaked));
  123. mem += sizeof(leaked);
  124. close(leaked);
  125. }
  126. }
  127. #endif /* HAVE_SOLARIS_BUGS */
  128. if (p <= 0)
  129. return p;
  130. left -= p;
  131. if (left > 0) {
  132. size_t i, count, done;
  133. /*
  134.  * Can't call recvmsg() again since we could be getting ancillary data,
  135.  * read the elements one by one.
  136.  */
  137. SASSERTX(p >= 0);
  138. done = p;
  139. i = count = p = 0;
  140. while (i < msg->msg_iovlen && left > 0) {
  141. const struct iovec *io = &msg->msg_iov[i];
  142. count += io->iov_len;
  143. if (count > done) {
  144. if ((p = readn(s, &((char *)(io->iov_base))[io->iov_len -
  145. (count - done)], count - done)) != ((ssize_t)(count - done)))
  146. break;
  147. left -= p;
  148. done += p;
  149. }
  150. ++i;
  151. }
  152. }
  153. if (left == len)
  154. return p; /* nothing read. */
  155. return len - left;
  156. }
  157. int
  158. closen(d)
  159. int d;
  160. {
  161. int rc;
  162. while ((rc = close(d)) == -1 && errno == EINTR)
  163. ;
  164. #if DIAGNOSTIC
  165. SASSERT(rc == 0 || d >= 0);
  166. #endif
  167. return rc;
  168. }
  169. int
  170. selectn(nfds, readfds, writefds, exceptfds, timeout)
  171. int nfds;
  172. fd_set *readfds;
  173. fd_set *writefds;
  174. fd_set *exceptfds;
  175. struct timeval *timeout;
  176. {
  177. /* const */ fd_set rset = readfds == NULL ? rset : *readfds;
  178. /* const */ fd_set wset = writefds == NULL ? wset : *writefds;
  179. /* const */ fd_set eset = exceptfds == NULL ? eset : *exceptfds;
  180. /* const */ struct timeval tout = timeout == NULL ? tout : *timeout;
  181. int rc;
  182. while ((rc = select(nfds, readfds, writefds, exceptfds, timeout)) == -1
  183. && errno == EINTR) {
  184. if (readfds != NULL)
  185. *readfds = rset;
  186. if (writefds != NULL)
  187. *writefds = wset;
  188. if (exceptfds != NULL)
  189. *exceptfds = eset;
  190. if (timeout != NULL)
  191. *timeout = tout;
  192. }
  193. return rc;
  194. }