changeset 144:8b9366fc1361 noffle

[svn] Added timeout to Prt_getLn to avoid Noffle hanging if the connection breaks down during a fetch.
author enz
date Sat, 23 Sep 2000 11:40:35 +0100
parents 7400a8e9d5ba
children deb2320befd7
files Makefile.in configure docs/Makefile.in src/client.c src/protocol.c src/protocol.h src/server.c
diffstat 7 files changed, 65 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Sat Sep 23 11:37:01 2000 +0100
+++ b/Makefile.in	Sat Sep 23 11:40:35 2000 +0100
@@ -265,7 +265,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
--- a/configure	Sat Sep 23 11:37:01 2000 +0100
+++ b/configure	Sat Sep 23 11:40:35 2000 +0100
@@ -2030,7 +2030,7 @@
 int main() {
 
 /* Ultrix mips cc rejects this.  */
-typedef int charset[2]; const charset x;
+typedef int charset[2]; const charset x = {0,0};
 /* SunOS 4.1.1 cc rejects this.  */
 char const *const *ccp;
 char **p;
--- a/docs/Makefile.in	Sat Sep 23 11:37:01 2000 +0100
+++ b/docs/Makefile.in	Sat Sep 23 11:40:35 2000 +0100
@@ -185,7 +185,7 @@
 	@for file in $(DISTFILES); do \
 	  d=$(srcdir); \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
--- a/src/client.c	Sat Sep 23 11:37:01 2000 +0100
+++ b/src/client.c	Sat Sep 23 11:40:35 2000 +0100
@@ -1,7 +1,7 @@
 /*
   client.c
 
-  $Id: client.c 191 2000-08-09 21:26:28Z bears $
+  $Id: client.c 217 2000-09-23 10:40:35Z enz $
 */
 
 #if HAVE_CONFIG_H
@@ -87,7 +87,7 @@
 {
     Bool r;
 
-    r = Prt_getLn( line, client.in );
+    r = Prt_getLn( line, client.in, Cfg_connectTimeout() );
     if ( ! r )
         logBreakDown();
     return r; 
@@ -98,7 +98,7 @@
 {
     Bool r;
 
-    r = Prt_getTxtLn( line, err, client.in );
+    r = Prt_getTxtLn( line, err, client.in, Cfg_connectTimeout() );
     if ( *err )
         logBreakDown();
     return r; 
--- a/src/protocol.c	Sat Sep 23 11:37:01 2000 +0100
+++ b/src/protocol.c	Sat Sep 23 11:40:35 2000 +0100
@@ -1,7 +1,7 @@
 /*
   protocol.c
 
-  $Id: protocol.c 183 2000-07-25 12:14:54Z bears $
+  $Id: protocol.c 217 2000-09-23 10:40:35Z enz $
 */
 
 #if HAVE_CONFIG_H
@@ -11,8 +11,10 @@
 #include <stdio.h> 
 #include <ctype.h> 
 #include <netdb.h>
+#include <signal.h>
 #include <sys/types.h>
 #include <sys/utsname.h>
+#include <unistd.h>
 #include "common.h"
 #include "dynamicstring.h"
 #include "log.h"
@@ -21,20 +23,61 @@
 #include "protocol.h"
 #include "portable.h"
 
+static void
+readAlarm( int sig )
+{
+    UNUSED( sig );
+    
+    return;
+}
+
+static sig_t
+installSignalHandler( int sig, sig_t handler )
+{
+    struct sigaction act, oldAct;
+
+    act.sa_handler = handler;
+    sigemptyset( &act.sa_mask );
+    act.sa_flags = 0;
+    if ( sig == SIGALRM )
+        act.sa_flags |= SA_INTERRUPT;
+    else
+        act.sa_flags |= SA_RESTART;
+    if ( sigaction( sig, &act, &oldAct ) < 0 )
+        return SIG_ERR;
+    return oldAct.sa_handler;
+}
+
 Bool
-Prt_getLn( Str line, FILE *f )
+Prt_getLn( Str line, FILE *f, int timeoutSeconds )
 {
     size_t len;
+    char *ret;
+    sig_t oldHandler = NULL;
 
+    if ( timeoutSeconds >= 0 )
+    {
+        oldHandler = installSignalHandler( SIGALRM, readAlarm );
+        if ( oldHandler == SIG_ERR )
+        {
+            Log_err( "Prt_getLn: signal failed." );
+            return FALSE;
+        }
+        if ( alarm( timeoutSeconds ) != 0 )
+            Log_err( "Prt_getLn: Alarm was already set." );
+    }
     /*
       We also accept lines ending with "\n" instead of "\r\n", some
       clients wrongly send such lines.
     */
-    if ( ! fgets( line, MAXCHAR, f ) )
+    ret = fgets( line, MAXCHAR, f );
+    if ( timeoutSeconds >= 0 )
     {
-	Log_dbg( "Prt_getLn failed" );
+        alarm( 0 );
+        installSignalHandler( SIGALRM, oldHandler );
+    }
+    if ( ret == NULL )
         return FALSE;
-    }
     len = strlen( line );
     if ( line[ len - 1 ] == '\n' )
     {
@@ -47,11 +90,11 @@
 }
 
 Bool
-Prt_getTxtLn( Str line, Bool *err, FILE *f )
+Prt_getTxtLn( Str line, Bool *err, FILE *f, int timeoutSeconds  )
 {
     Str buf;
 
-    if ( ! Prt_getLn( buf, f ) )
+    if ( ! Prt_getLn( buf, f, timeoutSeconds ) )
     {
         Log_err( "Cannot get text line" );
         *err = TRUE;
--- a/src/protocol.h	Sat Sep 23 11:37:01 2000 +0100
+++ b/src/protocol.h	Sat Sep 23 11:40:35 2000 +0100
@@ -4,7 +4,7 @@
   Functions related with the NNTP protocol which are useful for both
   the server and the client.
 
-  $Id: protocol.h 155 2000-06-24 20:28:01Z bears $
+  $Id: protocol.h 217 2000-09-23 10:40:35Z enz $
 */
 
 #ifndef PRT_H
@@ -58,16 +58,18 @@
 /* 
    Read next line from f into Str, up to "\n" or "\r\n". Don't save "\n"
    or "\r\n" in line. Terminate with '\0'. 
+   If timeoutSeconds < 0, no timeout alarm is used.
 */
 Bool
-Prt_getLn( Str line, FILE *f );
+Prt_getLn( Str line, FILE *f, int timeoutSeconds );
 
 /*
   Read a text line from server. Returns TRUE if line != ".", removes
   leading '.' otherwise.
+   If timeoutSeconds < 0, no timeout alarm is used.
 */
 Bool
-Prt_getTxtLn( Str line, Bool *err, FILE *f );
+Prt_getTxtLn( Str line, Bool *err, FILE *f, int timeoutSeconds );
 
 /*
   Write text line to f. Escape "." at the beginning with another ".".
--- a/src/server.c	Sat Sep 23 11:37:01 2000 +0100
+++ b/src/server.c	Sat Sep 23 11:40:35 2000 +0100
@@ -1,7 +1,7 @@
 /*
   server.c
 
-  $Id: server.c 183 2000-07-25 12:14:54Z bears $
+  $Id: server.c 217 2000-09-23 10:40:35Z enz $
 */
 
 #if HAVE_CONFIG_H
@@ -246,7 +246,7 @@
     /* Special case - no timeout. */
     if ( timeoutSeconds == 0 )
     {
-	r = Prt_getLn( line, stdin );
+	r = Prt_getLn( line, stdin, -1 );
 	return ( r ) ? 1 : -1;
     }
 
@@ -259,7 +259,7 @@
     }
     if ( alarm( ( unsigned int ) timeoutSeconds ) != 0 )
         Log_err( "server.c:waitCmdLn: Alarm was already set." );
-    r = Prt_getLn( line, stdin );
+    r = Prt_getLn( line, stdin, -1 );
     alarm( 0 );
     installSignalHandler( SIGALRM, oldHandler );
     if ( server.readAlarmFlag )
@@ -272,7 +272,7 @@
 static Bool
 getTxtLn( Str line, Bool *err )
 {
-    return Prt_getTxtLn( line, err, stdin );
+    return Prt_getTxtLn( line, err, stdin, -1 );
 }
 
 static Bool