Patch to work around flaky pop3 server behaviour
- From: Thomas Fitzsimmons <fitzsim cygnus com>
- To: balsa-list gnome org
- Subject: Patch to work around flaky pop3 server behaviour
- Date: Fri, 8 Jun 2001 18:42:30 -0400
This patch makes pop3 mail retrieval more robust.
It uses a non-blocking read function when retrieving characters from the
server, so that the mail retrieval thread doesn't hang when the server
fails to send an expected response.
I believe this resolves bug #55091.
Just this morning I discovered another issue that should be addressed: when
the pop3 server goes down, the mail retrieval thread hangs. I'll turn the
BALSA_TEST_POP3 code on, so that if the server goes down again, I'll know
what happened.
BTW, Neil Padgett <npadgett@redhat.com> helped with the attached patch.
To apply:
$(BALSA_SOURCE)/patch -p 1 < balsa-safe-read.patch
Keep up the great work on Balsa,
Tom
diff -c -r balsa-1.1.4/libbalsa/pop3.c balsa-1.1.4-modified/libbalsa/pop3.c
*** balsa-1.1.4/libbalsa/pop3.c Thu Nov 16 14:43:13 2000
--- balsa-1.1.4-modified/libbalsa/pop3.c Wed Jun 6 18:46:32 2001
***************
*** 32,37 ****
--- 32,39 ----
#include <netdb.h>
#include <string.h>
+ #include <errno.h>
+ #include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <gnome.h>
***************
*** 61,72 ****
return _(errmsgs[status]);
}
static int getLine (int fd, char *s, int len)
{
char ch;
int bytes = 0;
! while (read (fd, &ch, 1) > 0) {
*s++ = ch;
bytes++;
if (ch == '\n') {
--- 63,113 ----
return _(errmsgs[status]);
}
+ #define NUMBER_OF_RETRIES 20
+
+ /* safe_read_char:
+ Reads a character, without blocking indefinitely until a character
+ is available to be read. Retry NUMBER_OF_RETRIES times before
+ returning with an error.
+ */
+ static int
+ safe_read_char(int fd, char *ch)
+ {
+ int i = 0;
+ int retval = 0;
+
+ /* make read non-blocking */
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+ retval = read (fd, ch, 1);
+ /* make read blocking again */
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) ^ O_NONBLOCK);
+
+ if (retval == -1) {
+
+ if (errno == EAGAIN) {
+ /* pause one second before trying again */
+ sleep(1);
+ } else return -1;
+
+ if(i < NUMBER_OF_RETRIES) {
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+ retval = read (fd, ch, 1);
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) ^ O_NONBLOCK);
+ } else return -1;
+
+ i++;
+ } else return retval;
+
+ /* make gcc happy */
+ return retval;
+ }
+
static int getLine (int fd, char *s, int len)
{
char ch;
int bytes = 0;
! while (safe_read_char (fd, &ch) > 0) {
*s++ = ch;
bytes++;
if (ch == '\n') {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]