Published in <sxsk7raj1t2.fsf@florida.arsdigita.de>.
+2002-04-14 Hrvoje Niksic <hniksic@arsdigita.com>
+
+ * http.c (gethttp): Ditto.
+
+ * retr.c (retrieve_url): Initialize variables to appease the
+ compiler.
+
+ * gen_sslfunc.c (ssl_iread): Don't handle EINTR when calling
+ select_fd.
+ (ssl_iwrite): Ditto.
+
+ * connect.c (select_fd): Rewrite to handle EINTR. Set errno to
+ ETIMEDOUT in case of timeout.
+ (iread): No need to handle EINTR when calling select_fd.
+ (iwrite): Ditto.
+
2002-04-14 Hrvoje Niksic <hniksic@arsdigita.com>
* retr.c (retrieve_url): Make sure that POST is not honored for
}
#ifdef HAVE_SELECT
-/* Wait for file descriptor FD to be readable, MAXTIME being the
- timeout in seconds. If WRITEP is non-zero, checks for FD being
- writable instead.
+/* Wait for file descriptor FD to be available, timing out after
+ MAXTIME seconds. "Available" means readable if writep is 0,
+ writeable otherwise.
+
+ Returns 1 if FD is available, 0 for timeout and -1 for error. */
- Returns 1 if FD is accessible, 0 for timeout and -1 for error in
- select(). */
int
select_fd (int fd, int maxtime, int writep)
{
- fd_set fds, exceptfds;
- struct timeval timeout;
+ fd_set fds;
+ fd_set *rd = NULL, *wrt = NULL;
+ struct timeval tmout;
+ int result;
FD_ZERO (&fds);
FD_SET (fd, &fds);
- FD_ZERO (&exceptfds);
- FD_SET (fd, &exceptfds);
- timeout.tv_sec = maxtime;
- timeout.tv_usec = 0;
- /* HPUX reportedly warns here. What is the correct incantation? */
- return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
- &exceptfds, &timeout);
+ *(writep ? &wrt : &rd) = &fds;
+
+ tmout.tv_sec = maxtime;
+ tmout.tv_usec = 0;
+
+ do
+ result = select (fd + 1, rd, wrt, NULL, &tmout);
+ while (result < 0 && errno == EINTR);
+
+ /* When we've timed out, set errno to ETIMEDOUT for the convenience
+ of the caller. */
+ if (result == 0)
+ errno = ETIMEDOUT;
+
+ return result;
}
#endif /* HAVE_SELECT */
and uses select() to timeout the stale connections (a connection is
stale if more than OPT.TIMEOUT time is spent in select() or
read()). */
+
int
iread (int fd, char *buf, int len)
{
int res;
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout)
- {
- do
- {
- res = select_fd (fd, opt.timeout, 0);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- /* #### Potentially evil! */
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout)
+ if (select_fd (fd, opt.timeout, 0) <= 0)
+ return -1;
#endif
- res = READ (fd, buf, len);
- }
+ do
+ res = READ (fd, buf, len);
while (res == -1 && errno == EINTR);
return res;
}
/* Write LEN bytes from BUF to FD. This is similar to iread(), but
- doesn't bother with select(). Unlike iread(), it makes sure that
- all of BUF is actually written to FD, so callers needn't bother
- with checking that the return value equals to LEN. Instead, you
- should simply check for -1. */
+ unlike iread(), it makes sure that all of BUF is actually written
+ to FD, so callers needn't bother with checking that the return
+ value equals to LEN. Instead, you should simply check for -1. */
+
int
iwrite (int fd, char *buf, int len)
{
innermost loop deals with the same during select(). */
while (len > 0)
{
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout)
- {
- do
- {
- res = select_fd (fd, opt.timeout, 1);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout)
+ if (select_fd (fd, opt.timeout, 1) <= 0)
+ return -1;
#endif
- res = WRITE (fd, buf, len);
- }
+ do
+ res = WRITE (fd, buf, len);
while (res == -1 && errno == EINTR);
if (res <= 0)
break;
return ocerr;
}
-/* SSL version of iread. Only exchanged read for SSL_read
- Read at most LEN bytes from FD, storing them to BUF. This is
- virtually the same as read(), but takes care of EINTR braindamage
- and uses select() to timeout the stale connections (a connection is
- stale if more than OPT.TIMEOUT time is spent in select() or
- read()). */
+/* SSL version of iread. Only exchanged read for SSL_read Read at
+ most LEN bytes from FD, storing them to BUF. */
+
int
ssl_iread (SSL *con, char *buf, int len)
{
- int res;
- int fd;
+ int res, fd;
BIO_get_fd (con->rbio, &fd);
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout && !SSL_pending (con))
- {
- do
- {
- res = select_fd (fd, opt.timeout, 0);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- /* #### Potentially evil! */
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout && !SSL_pending (con))
+ if (select_fd (fd, opt.timeout, 0) <= 0)
+ return -1;
#endif
- res = SSL_read (con, buf, len);
- }
+ do
+ res = SSL_read (con, buf, len);
while (res == -1 && errno == EINTR);
return res;
}
-/* SSL version of iwrite. Only exchanged write for SSL_write
- Write LEN bytes from BUF to FD. This is similar to iread(), but
- doesn't bother with select(). Unlike iread(), it makes sure that
- all of BUF is actually written to FD, so callers needn't bother
- with checking that the return value equals to LEN. Instead, you
- should simply check for -1. */
+/* SSL version of iwrite. Only exchanged write for SSL_write Write
+ LEN bytes from BUF to FD. */
+
int
ssl_iwrite (SSL *con, char *buf, int len)
{
- int res = 0;
- int fd;
+ int res = 0, fd;
BIO_get_fd (con->rbio, &fd);
/* `write' may write less than LEN bytes, thus the outward loop
keeps trying it until all was written, or an error occurred. The
innermost loop deals with the same during select(). */
while (len > 0)
{
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout)
- {
- do
- {
- res = select_fd (fd, opt.timeout, 1);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- /* #### Potentially evil! */
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout)
+ if (select_fd (fd, opt.timeout, 1) <= 0)
+ return -1;
#endif
- res = SSL_write (con, buf, len);
- }
+ do
+ res = SSL_write (con, buf, len);
while (res == -1 && errno == EINTR);
if (res <= 0)
break;
post_file (int sock, void *ssl, const char *file_name, long promised_size)
{
static char chunk[8192];
- int written = 0;
+ long written = 0;
int write_error;
FILE *fp;
goto pad;
while (written < promised_size)
{
- long towrite;
+ int towrite;
int length = fread (chunk, 1, sizeof (chunk), fp);
if (length == 0)
break;
written += towrite;
}
fclose (fp);
+
pad:
if (written < promised_size)
{
- DEBUGP (("padding ... "));
/* This highly unlikely case can happen only if the file has
- shrunk while we weren't looking. To uphold the promise, pad
- the remaining data with zeros. #### Should we abort
- instead? */
+ shrunk under us. To uphold the promise that exactly
+ promised_size bytes would be delivered, pad the remaining
+ data with zeros. #### Should we abort instead? */
+ DEBUGP (("padding %ld bytes ... ", promised_size - written));
memset (chunk, '\0', sizeof (chunk));
while (written < promised_size)
{
- long towrite = WMIN (promised_size - written, sizeof (chunk));
+ int towrite = WMIN (promised_size - written, sizeof (chunk));
#ifdef HAVE_SSL
if (ssl)
write_error = ssl_iwrite (ssl, chunk, towrite);
/* Headers sent when using POST. */
char *post_content_type, *post_content_length;
- long post_data_size;
+ long post_data_size = 0;
#ifdef HAVE_SSL
/* initialize ssl_ctx on first run */
int redirection_count = 0;
int post_data_suspended = 0;
- char *saved_post_data;
- char *saved_post_file_name;
+ char *saved_post_data = NULL;
+ char *saved_post_file_name = NULL;
/* If dt is NULL, just ignore it. */
if (!dt)