X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fconnect.c;h=eeb4eb288f9a9d7b5782d8a93b14c28a0486d445;hp=9a402769ca2ec429e2ecbef6ff806ffb8709a998;hb=d9fea91a0a319e348adb504bd3edff148ff3d8a0;hpb=0716c335a0d38c09ade6f05be17bffa0d586b3da diff --git a/src/connect.c b/src/connect.c index 9a402769..eeb4eb28 100644 --- a/src/connect.c +++ b/src/connect.c @@ -735,6 +735,16 @@ sock_poll (int fd, double timeout, int wait_for) return select_fd (fd, timeout, wait_for); } +static int +sock_peek (int fd, char *buf, int bufsize) +{ + int res; + do + res = recv (fd, buf, bufsize, MSG_PEEK); + while (res == -1 && errno == EINTR); + return res; +} + static void sock_close (int fd) { @@ -760,6 +770,7 @@ struct transport_info { fd_reader_t reader; fd_writer_t writer; fd_poller_t poller; + fd_peeker_t peeker; fd_closer_t closer; void *ctx; }; @@ -773,7 +784,8 @@ struct transport_info { void fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer, - fd_poller_t poller, fd_closer_t closer, void *ctx) + fd_poller_t poller, fd_peeker_t peeker, + fd_closer_t closer, void *ctx) { struct transport_info *info; @@ -786,6 +798,7 @@ fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer, info->reader = reader; info->writer = writer; info->poller = poller; + info->peeker = peeker; info->closer = closer; info->ctx = ctx; if (!transport_map) @@ -819,36 +832,60 @@ fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer, } \ } while (0) -/* Read no more than BUFSIZE bytes of data from FD, storing them to - BUF. If TIMEOUT is non-zero, the operation aborts if no data is - received after that many seconds. If TIMEOUT is -1, the value of - opt.timeout is used for TIMEOUT. */ - -int -fd_read (int fd, char *buf, int bufsize, double timeout) +static int +poll_internal (int fd, struct transport_info *info, int wf, double timeout) { - struct transport_info *info; - LAZY_RETRIEVE_INFO (info); if (timeout == -1) timeout = opt.read_timeout; if (timeout) { int test; if (info && info->poller) - test = info->poller (fd, timeout, WAIT_FOR_READ, info->ctx); + test = info->poller (fd, timeout, wf, info->ctx); else - test = sock_poll (fd, timeout, WAIT_FOR_READ); + test = sock_poll (fd, timeout, wf); if (test == 0) errno = ETIMEDOUT; if (test <= 0) - return -1; + return 0; } + return 1; +} + +/* Read no more than BUFSIZE bytes of data from FD, storing them to + BUF. If TIMEOUT is non-zero, the operation aborts if no data is + received after that many seconds. If TIMEOUT is -1, the value of + opt.timeout is used for TIMEOUT. */ + +int +fd_read (int fd, char *buf, int bufsize, double timeout) +{ + struct transport_info *info; + LAZY_RETRIEVE_INFO (info); + if (!poll_internal (fd, info, WAIT_FOR_READ, timeout)) + return -1; if (info && info->reader) return info->reader (fd, buf, bufsize, info->ctx); else return sock_read (fd, buf, bufsize); } +/* The same as xread, but don't actually read the data, just copy it + instead. */ + +int +fd_peek (int fd, char *buf, int bufsize, double timeout) +{ + struct transport_info *info; + LAZY_RETRIEVE_INFO (info); + if (!poll_internal (fd, info, WAIT_FOR_READ, timeout)) + return -1; + if (info && info->peeker) + return info->peeker (fd, buf, bufsize, info->ctx); + else + return sock_peek (fd, buf, bufsize); +} + /* Write the entire contents of BUF to FD. If TIMEOUT is non-zero, the operation aborts if no data is received after that many seconds. If TIMEOUT is -1, the value of opt.timeout is used for @@ -860,26 +897,14 @@ fd_write (int fd, char *buf, int bufsize, double timeout) int res; struct transport_info *info; LAZY_RETRIEVE_INFO (info); - if (timeout == -1) - timeout = opt.read_timeout; /* `write' may write less than LEN bytes, thus the loop keeps trying it until all was written, or an error occurred. */ res = 0; while (bufsize > 0) { - if (timeout) - { - int test; - if (info && info->poller) - test = info->poller (fd, timeout, WAIT_FOR_WRITE, info->ctx); - else - test = sock_poll (fd, timeout, WAIT_FOR_WRITE); - if (test == 0) - errno = ETIMEDOUT; - if (test <= 0) - return -1; - } + if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout)) + return -1; if (info && info->writer) res = info->writer (fd, buf, bufsize, info->ctx); else