diff src/protocol.c @ 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 3c71e28c8eef
children 1c7303c71f66
line wrap: on
line diff
--- 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;