]> sjero.net Git - wget/blob - src/connect.c
[svn] Use the new function retryable_socket_connect_error instead of the
[wget] / src / connect.c
1 /* Establishing and handling network connections.
2    Copyright (C) 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <assert.h>
39
40 #ifndef WINDOWS
41 # include <sys/socket.h>
42 # include <netdb.h>
43 # include <netinet/in.h>
44 # ifndef __BEOS__
45 #  include <arpa/inet.h>
46 # endif
47 #endif /* not WINDOWS */
48
49 #include <errno.h>
50 #ifdef HAVE_STRING_H
51 # include <string.h>
52 #else
53 # include <strings.h>
54 #endif /* HAVE_STRING_H */
55 #ifdef HAVE_SYS_SELECT_H
56 # include <sys/select.h>
57 #endif /* HAVE_SYS_SELECT_H */
58
59 #include "wget.h"
60 #include "utils.h"
61 #include "host.h"
62 #include "connect.h"
63 #include "hash.h"
64
65 #ifndef errno
66 extern int errno;
67 #endif
68
69 \f
70 /* Fill SA as per the data in IP and PORT.  SA shoult point to struct
71    sockaddr_storage if ENABLE_IPV6 is defined, to struct sockaddr_in
72    otherwise.  */
73
74 static void
75 sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
76 {
77   switch (ip->type)
78     {
79     case IPV4_ADDRESS:
80       {
81         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
82         sin->sin_family = AF_INET;
83         sin->sin_port = htons (port);
84         sin->sin_addr = ADDRESS_IPV4_IN_ADDR (ip);
85         break;
86       }
87 #ifdef ENABLE_IPV6
88     case IPV6_ADDRESS:
89       {
90         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
91         sin6->sin6_family = AF_INET6;
92         sin6->sin6_port = htons (port);
93         sin6->sin6_addr = ADDRESS_IPV6_IN6_ADDR (ip);
94 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
95         sin6->sin6_scope_id = ADDRESS_IPV6_SCOPE (ip);
96 #endif
97         break;
98       }
99 #endif /* ENABLE_IPV6 */
100     default:
101       abort ();
102     }
103 }
104
105 /* Get the data of SA, specifically the IP address and the port.  If
106    you're not interested in one or the other information, pass NULL as
107    the pointer.  */
108
109 static void
110 sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
111 {
112   switch (sa->sa_family)
113     {
114     case AF_INET:
115       {
116         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
117         if (ip)
118           {
119             ip->type = IPV4_ADDRESS;
120             ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr;
121           }
122         if (port)
123           *port = ntohs (sin->sin_port);
124         break;
125       }
126 #ifdef ENABLE_IPV6
127     case AF_INET6:
128       {
129         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
130         if (ip)
131           {
132             ip->type = IPV6_ADDRESS;
133             ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr;
134 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
135             ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id;
136 #endif
137           }
138         if (port)
139           *port = ntohs (sin6->sin6_port);
140         break;
141       }
142 #endif
143     default:
144       abort ();
145     }
146 }
147
148 /* Return the size of the sockaddr structure depending on its
149    family.  */
150
151 static socklen_t
152 sockaddr_size (const struct sockaddr *sa)
153 {
154   switch (sa->sa_family)
155     {
156     case AF_INET:
157       return sizeof (struct sockaddr_in);
158 #ifdef ENABLE_IPV6
159     case AF_INET6:
160       return sizeof (struct sockaddr_in6);
161 #endif
162     default:
163       abort ();
164       return 0;                 /* so the compiler shuts up. */
165     }
166 }
167 \f
168 static int
169 resolve_bind_address (struct sockaddr *sa)
170 {
171   struct address_list *al;
172
173   /* Make sure this is called only once.  opt.bind_address doesn't
174      change during a Wget run.  */
175   static int called, should_bind;
176   static ip_address ip;
177   if (called)
178     {
179       if (should_bind)
180         sockaddr_set_data (sa, &ip, 0);
181       return should_bind;
182     }
183   called = 1;
184
185   al = lookup_host_passive (opt.bind_address);
186   if (!al)
187     {
188       /* #### We should be able to print the error message here. */
189       logprintf (LOG_NOTQUIET,
190                  _("%s: unable to resolve bind address `%s'; disabling bind.\n"),
191                  exec_name, opt.bind_address);
192       should_bind = 0;
193       return 0;
194     }
195
196   /* Pick the first address in the list and use it as bind address.
197      Perhaps we should try multiple addresses in succession, but I
198      don't think that's necessary in practice.  */
199   ip = *address_list_address_at (al, 0);
200   address_list_release (al);
201
202   sockaddr_set_data (sa, &ip, 0);
203   should_bind = 1;
204   return 1;
205 }
206 \f
207 struct cwt_context {
208   int fd;
209   const struct sockaddr *addr;
210   socklen_t addrlen;
211   int result;
212 };
213
214 static void
215 connect_with_timeout_callback (void *arg)
216 {
217   struct cwt_context *ctx = (struct cwt_context *)arg;
218   ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
219 }
220
221 /* Like connect, but specifies a timeout.  If connecting takes longer
222    than TIMEOUT seconds, -1 is returned and errno is set to
223    ETIMEDOUT.  */
224
225 static int
226 connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
227                       double timeout)
228 {
229   struct cwt_context ctx;
230   ctx.fd = fd;
231   ctx.addr = addr;
232   ctx.addrlen = addrlen;
233
234   if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
235     {
236       errno = ETIMEDOUT;
237       return -1;
238     }
239   if (ctx.result == -1 && errno == EINTR)
240     errno = ETIMEDOUT;
241   return ctx.result;
242 }
243 \f
244 /* Connect to a remote endpoint whose IP address is known.  */
245
246 int
247 connect_to_ip (const ip_address *ip, int port, const char *print)
248 {
249   struct sockaddr_storage ss;
250   struct sockaddr *sa = (struct sockaddr *)&ss;
251   int sock = -1;
252
253   /* If PRINT is non-NULL, print the "Connecting to..." line, with
254      PRINT being the host name we're connecting to.  */
255   if (print)
256     {
257       const char *txt_addr = pretty_print_address (ip);
258       if (print && 0 != strcmp (print, txt_addr))
259         logprintf (LOG_VERBOSE,
260                    _("Connecting to %s|%s|:%d... "), print, txt_addr, port);
261       else
262         logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
263     }
264
265   /* Store the sockaddr info to SA.  */
266   sockaddr_set_data (sa, ip, port);
267
268   /* Create the socket of the family appropriate for the address.  */
269   sock = socket (sa->sa_family, SOCK_STREAM, 0);
270   if (sock < 0)
271     goto err;
272
273   /* For very small rate limits, set the buffer size (and hence,
274      hopefully, the kernel's TCP window size) to the per-second limit.
275      That way we should never have to sleep for more than 1s between
276      network reads.  */
277   if (opt.limit_rate && opt.limit_rate < 8192)
278     {
279       int bufsize = opt.limit_rate;
280       if (bufsize < 512)
281         bufsize = 512;          /* avoid pathologically small values */
282 #ifdef SO_RCVBUF
283       setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
284                   (void *)&bufsize, (socklen_t)sizeof (bufsize));
285 #endif
286       /* When we add limit_rate support for writing, which is useful
287          for POST, we should also set SO_SNDBUF here.  */
288     }
289
290   if (opt.bind_address)
291     {
292       /* Bind the client side of the socket to the requested
293          address.  */
294       struct sockaddr_storage bind_ss;
295       struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
296       if (resolve_bind_address (bind_sa))
297         {
298           if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
299             goto err;
300         }
301     }
302
303   /* Connect the socket to the remote endpoint.  */
304   if (connect_with_timeout (sock, sa, sockaddr_size (sa),
305                             opt.connect_timeout) < 0)
306     goto err;
307
308   /* Success. */
309   assert (sock >= 0);
310   if (print)
311     logprintf (LOG_VERBOSE, _("connected.\n"));
312   DEBUGP (("Created socket %d.\n", sock));
313   return sock;
314
315  err:
316   {
317     /* Protect errno from possible modifications by close and
318        logprintf.  */
319     int save_errno = errno;
320     if (sock >= 0)
321       xclose (sock);
322     if (print)
323       logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
324     errno = save_errno;
325     return -1;
326   }
327 }
328
329 /* Connect to a remote endpoint specified by host name.  */
330
331 int
332 connect_to_host (const char *host, int port)
333 {
334   int i, start, end;
335   struct address_list *al;
336   int sock = -1;
337
338  again:
339   al = lookup_host (host, 0);
340   if (!al)
341     return E_HOST;
342
343   address_list_get_bounds (al, &start, &end);
344   for (i = start; i < end; i++)
345     {
346       const ip_address *ip = address_list_address_at (al, i);
347       sock = connect_to_ip (ip, port, host);
348       if (sock >= 0)
349         /* Success. */
350         break;
351
352       address_list_set_faulty (al, i);
353
354       /* The attempt to connect has failed.  Continue with the loop
355          and try next address. */
356     }
357   address_list_release (al);
358
359   if (sock >= 0)
360     /* Mark a successful connection to one of the addresses. */
361     address_list_set_connected (al);
362
363   if (sock < 0 && address_list_connected_p (al))
364     {
365       /* We are unable to connect to any of HOST's addresses, although
366          we were previously able to connect to HOST.  That might
367          indicate that HOST is under dynamic DNS and the addresses
368          we're connecting to have expired.  Resolve it again.  */
369       forget_host_lookup (host);
370       goto again;
371     }
372
373   return sock;
374 }
375
376 int
377 test_socket_open (int sock)
378 {
379 #ifdef HAVE_SELECT
380   fd_set check_set;
381   struct timeval to;
382
383   /* Check if we still have a valid (non-EOF) connection.  From Andrew
384    * Maholski's code in the Unix Socket FAQ.  */
385
386   FD_ZERO (&check_set);
387   FD_SET (sock, &check_set);
388
389   /* Wait one microsecond */
390   to.tv_sec = 0;
391   to.tv_usec = 1;
392
393   /* If we get a timeout, then that means still connected */
394   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
395     {
396       /* Connection is valid (not EOF), so continue */
397       return 1;
398     }
399   else
400     return 0;
401 #else
402   /* Without select, it's hard to know for sure. */
403   return 1;
404 #endif
405 }
406
407 /* Create a socket, bind it to local interface BIND_ADDRESS on port
408    *PORT, set up a listen backlog, and return the resulting socket, or
409    -1 in case of error.
410
411    BIND_ADDRESS is the address of the interface to bind to.  If it is
412    NULL, the socket is bound to the default address.  PORT should
413    point to the port number that will be used for the binding.  If
414    that number is 0, the system will choose a suitable port, and the
415    chosen value will be written to *PORT.
416
417    Calling accept() on such a socket waits for and accepts incoming
418    TCP connections.  */
419
420 int
421 bind_local (const ip_address *bind_address, int *port)
422 {
423   int sock;
424   int family = AF_INET;
425   struct sockaddr_storage ss;
426   struct sockaddr *sa = (struct sockaddr *)&ss;
427
428   /* For setting options with setsockopt. */
429   int setopt_val = 1;
430   void *setopt_ptr = (void *)&setopt_val;
431   socklen_t setopt_size = sizeof (setopt_val);
432
433 #ifdef ENABLE_IPV6
434   if (bind_address->type == IPV6_ADDRESS) 
435     family = AF_INET6;
436 #endif
437
438   sock = socket (family, SOCK_STREAM, 0);
439   if (sock < 0)
440     return -1;
441
442 #ifdef SO_REUSEADDR
443   setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size);
444 #endif
445
446 #ifdef ENABLE_IPV6
447 # ifdef HAVE_IPV6_V6ONLY
448   if (family == AF_INET6)
449     setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, setopt_ptr, setopt_size);
450 # endif
451 #endif
452
453   xzero (ss);
454   sockaddr_set_data (sa, bind_address, *port);
455   if (bind (sock, sa, sockaddr_size (sa)) < 0)
456     {
457       xclose (sock);
458       return -1;
459     }
460   DEBUGP (("Local socket fd %d bound.\n", sock));
461
462   /* If *PORT is 0, find out which port we've bound to.  */
463   if (*port == 0)
464     {
465       socklen_t sa_len = sockaddr_size (sa);
466       if (getsockname (sock, sa, &sa_len) < 0)
467         {
468           /* If we can't find out the socket's local address ("name"),
469              something is seriously wrong with the socket, and it's
470              unusable for us anyway because we must know the chosen
471              port.  */
472           xclose (sock);
473           return -1;
474         }
475       sockaddr_get_data (sa, NULL, port);
476       DEBUGP (("binding to address %s using port %i.\n", 
477                pretty_print_address (bind_address), *port));
478     }
479   if (listen (sock, 1) < 0)
480     {
481       xclose (sock);
482       return -1;
483     }
484   return sock;
485 }
486
487 /* Like a call to accept(), but with the added check for timeout.
488
489    In other words, accept a client connection on LOCAL_SOCK, and
490    return the new socket used for communication with the client.
491    LOCAL_SOCK should have been bound, e.g. using bind_local().
492
493    The caller is blocked until a connection is established.  If no
494    connection is established for opt.connect_timeout seconds, the
495    function exits with an error status.  */
496
497 int
498 accept_connection (int local_sock)
499 {
500   int sock;
501
502   /* We don't need the values provided by accept, but accept
503      apparently requires them to be present.  */
504   struct sockaddr_storage ss;
505   struct sockaddr *sa = (struct sockaddr *)&ss;
506   socklen_t addrlen = sizeof (ss);
507
508 #ifdef HAVE_SELECT
509   if (opt.connect_timeout)
510     {
511       int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ);
512       if (test == 0)
513         errno = ETIMEDOUT;
514       if (test <= 0)
515         return -1;
516     }
517 #endif
518   sock = accept (local_sock, sa, &addrlen);
519   DEBUGP (("Accepted client at socket %d.\n", sock));
520   return sock;
521 }
522
523 /* Get the IP address associated with the connection on FD and store
524    it to IP.  Return 1 on success, 0 otherwise.
525
526    If ENDPOINT is ENDPOINT_LOCAL, it returns the address of the local
527    (client) side of the socket.  Else if ENDPOINT is ENDPOINT_PEER, it
528    returns the address of the remote (peer's) side of the socket.  */
529
530 int
531 socket_ip_address (int sock, ip_address *ip, int endpoint)
532 {
533   struct sockaddr_storage storage;
534   struct sockaddr *sockaddr = (struct sockaddr *)&storage;
535   socklen_t addrlen = sizeof (storage);
536   int ret;
537
538   if (endpoint == ENDPOINT_LOCAL)
539     ret = getsockname (sock, sockaddr, &addrlen);
540   else if (endpoint == ENDPOINT_PEER)
541     ret = getpeername (sock, sockaddr, &addrlen);
542   else
543     abort ();
544   if (ret < 0)
545     return 0;
546
547   switch (sockaddr->sa_family)
548     {
549 #ifdef ENABLE_IPV6
550     case AF_INET6:
551       {
552         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
553         ip->type = IPV6_ADDRESS;
554         ADDRESS_IPV6_IN6_ADDR (ip) = sa6->sin6_addr;
555 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
556         ADDRESS_IPV6_SCOPE (ip) = sa6->sin6_scope_id;
557 #endif
558         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
559         return 1;
560       }
561 #endif
562     case AF_INET:
563       {
564         struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
565         ip->type = IPV4_ADDRESS;
566         ADDRESS_IPV4_IN_ADDR (ip) = sa->sin_addr;
567         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
568         return 1;
569       }
570     default:
571       abort ();
572     }
573
574   return 0;
575 }
576
577 /* Return non-zero if the error from the connect code can be
578    considered retryable.  Wget normally retries after errors, but the
579    exception are the "unsupported protocol" type errors (possible on
580    IPv4/IPv6 dual family systems) and "connection refused".  */
581
582 int
583 retryable_socket_connect_error (int err)
584 {
585   /* Have to guard against some of these values not being defined.
586      Cannot use a switch statement because some of the values might be
587      equal.  */
588   if (0
589 #ifdef EAFNOSUPPORT
590       || err == EAFNOSUPPORT
591 #endif
592 #ifdef EPFNOSUPPORT
593       || err == EPFNOSUPPORT
594 #endif
595 #ifdef ESOCKTNOSUPPORT          /* no, "sockt" is not a typo! */
596       || err == ESOCKTNOSUPPORT
597 #endif
598 #ifdef EPROTONOSUPPORT
599       || err == EPROTONOSUPPORT
600 #endif
601 #ifdef ENOPROTOOPT
602       || err == ENOPROTOOPT
603 #endif
604       /* Apparently, older versions of Linux and BSD used EINVAL
605          instead of EAFNOSUPPORT and such.  */
606       || err == EINVAL
607       )
608     return 0;
609
610   if (err == ECONNREFUSED && !opt.retry_connrefused)
611     return 0;
612
613   return 1;
614 }
615
616 #ifdef HAVE_SELECT
617
618 /* Wait for file descriptor FD to be readable or writable or both,
619    timing out after MAXTIME seconds.  Returns 1 if FD is available, 0
620    for timeout and -1 for error.  The argument WAIT_FOR can be a
621    combination of WAIT_READ and WAIT_WRITE.
622
623    This is a mere convenience wrapper around the select call, and
624    should be taken as such.  */
625
626 int
627 select_fd (int fd, double maxtime, int wait_for)
628 {
629   fd_set fdset;
630   fd_set *rd = NULL, *wr = NULL;
631   struct timeval tmout;
632   int result;
633
634   FD_ZERO (&fdset);
635   FD_SET (fd, &fdset);
636   if (wait_for & WAIT_FOR_READ)
637     rd = &fdset;
638   if (wait_for & WAIT_FOR_WRITE)
639     wr = &fdset;
640
641   tmout.tv_sec = (long) maxtime;
642   tmout.tv_usec = 1000000L * (maxtime - (long) maxtime);
643
644   do
645     result = select (fd + 1, rd, wr, NULL, &tmout);
646   while (result < 0 && errno == EINTR);
647
648   return result;
649 }
650
651 #endif /* HAVE_SELECT */
652 \f
653 /* Basic socket operations, mostly EINTR wrappers.  */
654
655 #ifdef WINDOWS
656 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
657 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
658 # define close(fd) closesocket (fd)
659 #endif
660
661 #ifdef __BEOS__
662 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
663 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
664 #endif
665
666 static int
667 sock_read (int fd, char *buf, int bufsize)
668 {
669   int res;
670   do
671     res = read (fd, buf, bufsize);
672   while (res == -1 && errno == EINTR);
673   return res;
674 }
675
676 static int
677 sock_write (int fd, char *buf, int bufsize)
678 {
679   int res = 0;
680   do
681     res = write (fd, buf, bufsize);
682   while (res == -1 && errno == EINTR);
683   return res;
684 }
685
686 static int
687 sock_poll (int fd, double timeout, int wait_for)
688 {
689 #ifdef HAVE_SELECT
690   return select_fd (fd, timeout, wait_for);
691 #else
692   return 1;
693 #endif
694 }
695
696 static void
697 sock_close (int fd)
698 {
699   close (fd);
700   DEBUGP (("Closed fd %d\n", fd));
701 }
702 #undef read
703 #undef write
704 #undef close
705 \f
706 /* Reading and writing from the network.  We build around the socket
707    (file descriptor) API, but support "extended" operations for things
708    that are not mere file descriptors under the hood, such as SSL
709    sockets.
710
711    That way the user code can call xread(fd, ...) and we'll run read
712    or SSL_read or whatever is necessary.  */
713
714 static struct hash_table *extended_map;
715 static int extended_map_modified_tick;
716
717 struct extended_info {
718   xreader_t reader;
719   xwriter_t writer;
720   xpoller_t poller;
721   xcloser_t closer;
722   void *ctx;
723 };
724
725 /* Register the handlers for operations on FD.  This is meant
726    primarily for transport layers like SSL that piggyback on sockets,
727    but with their own readers, writers, etc.  */
728
729 void
730 register_extended (int fd, xreader_t reader, xwriter_t writer,
731                    xpoller_t poller, xcloser_t closer, void *ctx)
732 {
733   struct extended_info *info;
734
735   /* The file descriptor must be non-negative to be registered.
736      Negative values are ignored by xclose(), and -1 cannot be used as
737      hash key.  */
738   assert (fd >= 0);
739
740   info = xnew (struct extended_info);
741   info->reader = reader;
742   info->writer = writer;
743   info->poller = poller;
744   info->closer = closer;
745   info->ctx = ctx;
746   if (!extended_map)
747     extended_map = hash_table_new (0, NULL, NULL);
748   hash_table_put (extended_map, (void *) fd, info);
749   ++extended_map_modified_tick;
750 }
751
752 /* When xread/xwrite are called multiple times in a loop, they should
753    remember the INFO pointer instead of fetching it every time.  It is
754    not enough to compare FD to LAST_FD because FD might have been
755    closed and reopened.  modified_tick ensures that changes to
756    extended_map will not be unnoticed.
757
758    This is a macro because we want the static storage variables to be
759    per-function.  */
760
761 #define LAZY_RETRIEVE_INFO(info) do {                                   \
762   static struct extended_info *last_info;                               \
763   static int last_fd = -1, last_tick;                                   \
764   if (!extended_map)                                                    \
765     info = NULL;                                                        \
766   else if (last_fd == fd && last_tick == extended_map_modified_tick)    \
767     info = last_info;                                                   \
768   else                                                                  \
769     {                                                                   \
770       info = hash_table_get (extended_map, (void *) fd);                \
771       last_fd = fd;                                                     \
772       last_info = info;                                                 \
773       last_tick = extended_map_modified_tick;                           \
774     }                                                                   \
775 } while (0)
776
777 /* Read no more than BUFSIZE bytes of data from FD, storing them to
778    BUF.  If TIMEOUT is non-zero, the operation aborts if no data is
779    received after that many seconds.  If TIMEOUT is -1, the value of
780    opt.timeout is used for TIMEOUT.  */
781
782 int
783 xread (int fd, char *buf, int bufsize, double timeout)
784 {
785   struct extended_info *info;
786   LAZY_RETRIEVE_INFO (info);
787   if (timeout == -1)
788     timeout = opt.read_timeout;
789   if (timeout)
790     {
791       int test;
792       if (info && info->poller)
793         test = info->poller (fd, timeout, WAIT_FOR_READ, info->ctx);
794       else
795         test = sock_poll (fd, timeout, WAIT_FOR_READ);
796       if (test == 0)
797         errno = ETIMEDOUT;
798       if (test <= 0)
799         return -1;
800     }
801   if (info && info->reader)
802     return info->reader (fd, buf, bufsize, info->ctx);
803   else
804     return sock_read (fd, buf, bufsize);
805 }
806
807 /* Write the entire contents of BUF to FD.  If TIMEOUT is non-zero,
808    the operation aborts if no data is received after that many
809    seconds.  If TIMEOUT is -1, the value of opt.timeout is used for
810    TIMEOUT.  */
811
812 int
813 xwrite (int fd, char *buf, int bufsize, double timeout)
814 {
815   int res;
816   struct extended_info *info;
817   LAZY_RETRIEVE_INFO (info);
818   if (timeout == -1)
819     timeout = opt.read_timeout;
820
821   /* `write' may write less than LEN bytes, thus the loop keeps trying
822      it until all was written, or an error occurred.  */
823   res = 0;
824   while (bufsize > 0)
825     {
826       if (timeout)
827         {
828           int test;
829           if (info && info->poller)
830             test = info->poller (fd, timeout, WAIT_FOR_WRITE, info->ctx);
831           else
832             test = sock_poll (fd, timeout, WAIT_FOR_WRITE);
833           if (test == 0)
834             errno = ETIMEDOUT;
835           if (test <= 0)
836             return -1;
837         }
838       if (info && info->writer)
839         res = info->writer (fd, buf, bufsize, info->ctx);
840       else
841         res = sock_write (fd, buf, bufsize);
842       if (res <= 0)
843         break;
844       buf += res;
845       bufsize -= res;
846     }
847   return res;
848 }
849
850 /* Close the file descriptor FD.  */
851
852 void
853 xclose (int fd)
854 {
855   struct extended_info *info;
856   if (fd < 0)
857     return;
858
859   /* We don't need to be extra-fast here, so save some code by
860      avoiding LAZY_RETRIEVE_INFO. */
861   info = NULL;
862   if (extended_map)
863     info = hash_table_get (extended_map, (void *) fd);
864
865   if (info && info->closer)
866     info->closer (fd, info->ctx);
867   else
868     sock_close (fd);
869
870   if (info)
871     {
872       hash_table_remove (extended_map, (void *) fd);
873       xfree (info);
874       ++extended_map_modified_tick;
875     }
876 }