Index: tests/ftp.pm
===================================================================
RCS file: /cvsroot/curl/curl/tests/ftp.pm,v
retrieving revision 1.12
diff -U 5 -r1.12 ftp.pm
--- tests/ftp.pm	24 Apr 2007 21:30:39 -0000	1.12
+++ tests/ftp.pm	23 Apr 2008 19:14:35 -0000
@@ -3,11 +3,11 @@
 #  Project                     ___| | | |  _ \| |
 #                             / __| | | | |_) | |
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
 # are also available at http://curl.haxx.se/docs/copyright.html.
 #
@@ -82,6 +82,27 @@
             ftpkillslave ($id, $ext, $verbose);
         }
     }
 }
 
+
+sub set_advisor_read_lock {
+    my ($filename) = @_;
+
+    if(open(FILEH, ">$filename")) {
+        close(FILEH);
+        return;
+    }
+    printf "Error creating lock file $filename error: $!";
+}
+
+
+sub clear_advisor_read_lock {
+    my ($filename) = @_;
+
+    if(-f $filename) {
+        unlink($filename);
+    }
+}
+
+
 1;
Index: tests/ftpserver.pl
===================================================================
RCS file: /cvsroot/curl/curl/tests/ftpserver.pl,v
retrieving revision 1.93
diff -U 5 -r1.93 ftpserver.pl
--- tests/ftpserver.pl	23 Nov 2007 09:50:45 -0000	1.93
+++ tests/ftpserver.pl	23 Apr 2008 19:14:36 -0000
@@ -4,11 +4,11 @@
 #  Project                     ___| | | |  _ \| |
 #                             / __| | | | |_) | |
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
 # are also available at http://curl.haxx.se/docs/copyright.html.
 #
@@ -83,10 +83,12 @@
 my $grok_eprt;
 my $port = 8921; # just a default
 my $listenaddr = "127.0.0.1"; # just a default
 my $pidfile = ".ftpd.pid"; # a default, use --pidfile
 
+my $SERVERLOGS_LOCK="log/serverlogs.lock"; # server logs advisor read lock
+
 do {
     if($ARGV[0] eq "-v") {
         $verbose=1;
     }
     elsif($ARGV[0] eq "-s") {
@@ -119,10 +121,11 @@
 
 sub catch_zap {
     my $signame = shift;
     print STDERR "ftpserver.pl received SIG$signame, exiting\n";
     ftpkillslaves(1);
+    clear_advisor_read_lock($SERVERLOGS_LOCK);
     die "Somebody sent me a SIG$signame";
 }
 $SIG{INT} = \&catch_zap;
 $SIG{KILL} = \&catch_zap;
 
@@ -144,19 +147,21 @@
         ($fcaller, $lcaller) = (caller)[1,2];
         logmsg "Failed to read input\n";
         logmsg "Error: ftp$ftpdnum$ext sysread error: $!\n";
         kill(9, $sfpid);
         waitpid($sfpid, 0);
+        clear_advisor_read_lock($SERVERLOGS_LOCK);
         die "Died in sysread_or_die() at $fcaller " .
             "line $lcaller. ftp$ftpdnum$ext sysread error: $!\n";
     }
     elsif($result == 0) {
         ($fcaller, $lcaller) = (caller)[1,2];
         logmsg "Failed to read input\n";
         logmsg "Error: ftp$ftpdnum$ext read zero\n";
         kill(9, $sfpid);
         waitpid($sfpid, 0);
+        clear_advisor_read_lock($SERVERLOGS_LOCK);
         die "Died in sysread_or_die() at $fcaller " .
             "line $lcaller. ftp$ftpdnum$ext read zero\n";
     }
 
     return $result;
@@ -174,10 +179,11 @@
 
     if($pong !~ /^PONG/) {
         logmsg "Failed sockfilt command: $cmd\n";
         kill(9, $sfpid);
         waitpid($sfpid, 0);
+        clear_advisor_read_lock($SERVERLOGS_LOCK);
         die "Failed to start sockfilt!";
     }
 }
 
 # remove the file here so that if startsf() fails, it is very noticeable 
@@ -782,10 +788,12 @@
         logmsg "sockfilt said: $input";
         next;
     }
     logmsg "====> Client connect\n";
 
+    set_advisor_read_lock($SERVERLOGS_LOCK);
+
     # flush data:
     $| = 1;
 
     kill(9, $slavepid) if($slavepid);
     waitpid($slavepid, 0) if($slavepid);
@@ -886,10 +894,15 @@
             sendcontrol "500 $FTPCMD is not dealt with!\r\n";
         }
             
     } # while(1)
     logmsg "====> Client disconnected\n";
+
+    clear_advisor_read_lock($SERVERLOGS_LOCK);
 }
 
 print SFWRITE "QUIT\n";
 waitpid $sfpid, 0;
+
+clear_advisor_read_lock($SERVERLOGS_LOCK);
+
 exit;
Index: tests/runtests.pl
===================================================================
RCS file: /cvsroot/curl/curl/tests/runtests.pl,v
retrieving revision 1.292
diff -U 5 -r1.292 runtests.pl
--- tests/runtests.pl	21 Apr 2008 17:19:44 -0000	1.292
+++ tests/runtests.pl	23 Apr 2008 19:14:38 -0000
@@ -118,10 +118,11 @@
 my $LIBDIR="./libtest";
 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
+my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
 
 # Normally, all test cases should be run, but at times it is handy to
 # simply run a particular one:
 my $TESTCASES="all";
 
@@ -200,10 +201,14 @@
 my $sshdid;      # for socks server, ssh daemon version id
 my $sshdvernum;  # for socks server, ssh daemon version number
 my $sshdverstr;  # for socks server, ssh daemon version string
 my $sshderror;   # for socks server, ssh daemon version error
 
+my $EXP_big_delay = 300;
+my $EXP_max_delay = 0;
+my $EXP_max_testn = 0;
+
 #######################################################################
 # variables the command line options may set
 #
 
 my $short;
@@ -2094,10 +2099,31 @@
             runclient("$gdb --directory libtest -x log/gdbcmd2 -batch $DBGCURL core ");
      #       unlink("log/gdbcmd2");
         }
     }
 
+    # If a server logs advisor read lock file exists, it is an indication
+    # that the server has not yet finished writing out all its log files,
+    # including server request log files used for protocol verification.
+    # So, if the lock file exists the script waits here a certain amount
+    # of time until the server removes it, or the given time expires.
+    # Test harness ssh server does not have this synchronization mechanism,
+    # this implies that some ssh server based tests might need a small delay
+    # in the postcheck section to avoid false test failures.
+
+    my $lockretry = ($testnum == 190) ? 10 : $EXP_big_delay ;
+    while((-f $SERVERLOGS_LOCK) && $lockretry--) {
+        sleep(1);
+    }
+
+    if($testnum != 190) {
+        if($EXP_big_delay - $lockretry > $EXP_max_delay) {
+            $EXP_max_delay = $EXP_big_delay - $lockretry;
+            $EXP_max_testn = $testnum;
+        }
+    }
+
     # run the postcheck command
     my @postcheck= getpart("client", "postcheck");
     $cmd = $postcheck[0];
     chomp $cmd;
     subVariables \$cmd;
@@ -3118,8 +3144,11 @@
             }
         }
         logmsg ")\n";
     }
 }
+
+logmsg "EXPERIMENTAL: lock max delay ($EXP_max_delay seconds) for test # $EXP_max_testn \n";
+
 if($total && ($ok != $total)) {
     exit 1;
 }
Index: tests/data/test1001
===================================================================
RCS file: /cvsroot/curl/curl/tests/data/test1001,v
retrieving revision 1.6
diff -U 5 -r1.6 test1001
--- tests/data/test1001	22 Apr 2008 12:40:06 -0000	1.6
+++ tests/data/test1001	23 Apr 2008 19:14:38 -0000
@@ -69,13 +69,10 @@
 http://%HOSTIP:%HTTPPORT/1001 -u auser:apasswd --digest -T log/1001 -x  http://%HOSTIP:%HTTPPORT -C 2 -X GET
 </command>
 <file name="log/1001">
 test
 </file>
-<postcheck>
-%SRCDIR/libtest/delay.pl 1
-</postcheck>
 </client>
 
 # Verify data after the test has been "shot"
 <verify>
 <strip>
Index: tests/server/sws.c
===================================================================
RCS file: /cvsroot/curl/curl/tests/server/sws.c,v
retrieving revision 1.119
diff -U 5 -r1.119 sws.c
--- tests/server/sws.c	22 Apr 2008 13:07:27 -0000	1.119
+++ tests/server/sws.c	23 Apr 2008 19:14:39 -0000
@@ -986,10 +986,12 @@
     if (CURL_SOCKET_BAD == msgsock) {
       printf("MAJOR ERROR: accept() failed with error: %d\n", SOCKERRNO);
       break;
     }
 
+    set_advisor_read_lock(SERVERLOGS_LOCK);
+
 #ifdef CURL_SWS_FORK_ENABLED
     if(use_fork) {
       /* The fork enabled version just forks off the child and don't care
          about it anymore, so don't assume otherwise. Beware and don't do
          this at home. */
@@ -1061,17 +1063,21 @@
     } while(req.open || (req.testno == DOCNUMBER_CONNECT));
 
     logmsg("====> Client disconnect");
     sclose(msgsock);
 
+    clear_advisor_read_lock(SERVERLOGS_LOCK);
+
     if (req.testno == DOCNUMBER_QUIT)
       break;
 #ifdef CURL_SWS_FORK_ENABLED
     }
 #endif
   }
 
   sclose(sock);
 
+  clear_advisor_read_lock(SERVERLOGS_LOCK);
+
   return 0;
 }
 
Index: tests/server/tftpd.c
===================================================================
RCS file: /cvsroot/curl/curl/tests/server/tftpd.c,v
retrieving revision 1.34
diff -U 5 -r1.34 tftpd.c
--- tests/server/tftpd.c	28 Feb 2008 00:55:06 -0000	1.34
+++ tests/server/tftpd.c	23 Apr 2008 19:14:39 -0000
@@ -413,10 +413,11 @@
   unsigned short port = DEFAULT_PORT;
   curl_socket_t sock;
   int flag;
   int rc;
   struct testcase test;
+  int result = 0;
 
   while(argc>arg) {
     if(!strcmp("--version", argv[arg])) {
       printf("tftpd IPv4%s\n",
 #ifdef ENABLE_IPV6
@@ -516,24 +517,29 @@
     fromlen = sizeof(from);
     n = recvfrom(sock, buf, sizeof (buf), 0,
                  (struct sockaddr *)&from, &fromlen);
     if (n < 0) {
       logmsg("recvfrom:\n");
-      return 3;
+      result = 3;
+      break;
     }
 
+    set_advisor_read_lock(SERVERLOGS_LOCK);
+
     from.sin_family = AF_INET;
 
     peer = socket(AF_INET, SOCK_DGRAM, 0);
     if (peer < 0) {
       logmsg("socket:\n");
-      return 2;
+      result = 2;
+      break;
     }
 
     if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
       logmsg("connect: fail\n");
-      return 1;
+      result = 1;
+      break;
     }
     maxtimeout = 5*TIMEOUT;
 
     tp = (struct tftphdr *)buf;
     tp->th_opcode = ntohs(tp->th_opcode);
@@ -543,12 +549,18 @@
         break;
       if(test.buffer)
         free(test.buffer);
     }
     sclose(peer);
+
+    clear_advisor_read_lock(SERVERLOGS_LOCK);
+
   } while(1);
-  return 0;
+
+  clear_advisor_read_lock(SERVERLOGS_LOCK);
+
+  return result;
 }
 
 struct formats {
   const char *f_mode;
   int f_convert;
@@ -732,12 +744,14 @@
   (void)signum;
 
   logmsg("alarm!");
 
   timeout += rexmtval;
-  if (timeout >= maxtimeout)
+  if(timeout >= maxtimeout) {
+    clear_advisor_read_lock(SERVERLOGS_LOCK);
     exit(1);
+  }
 #ifdef HAVE_SIGSETJMP
   siglongjmp(timeoutbuf, 1);
 #endif
 }
 
Index: tests/server/util.c
===================================================================
RCS file: /cvsroot/curl/curl/tests/server/util.c,v
retrieving revision 1.23
diff -U 5 -r1.23 util.c
--- tests/server/util.c	28 Feb 2008 09:38:32 -0000	1.23
+++ tests/server/util.c	23 Apr 2008 19:14:40 -0000
@@ -232,5 +232,41 @@
   fprintf(pidfile, "%ld\n", pid);
   fclose(pidfile);
   logmsg("Wrote pid %ld to %s", pid, filename);
   return 1; /* success */
 }
+
+void set_advisor_read_lock(const char *filename)
+{
+  FILE *lockfile;
+  int error;
+  int res;
+
+  do {
+    lockfile = fopen(filename, "wb");
+  } while((lockfile == NULL) && ((error = ERRNO) == EINTR));
+  if(lockfile == NULL) {
+    logmsg("Error creating lock file %s error: %d %s",
+           filename, error, strerror(error));
+    return;
+  }
+
+  do {
+    res = fclose(lockfile);
+  } while(res && ((error = ERRNO) == EINTR));
+  if(res)
+    logmsg("Error closing lock file %s error: %d %s",
+           filename, error, strerror(error));
+}
+
+void clear_advisor_read_lock(const char *filename)
+{
+  int error;
+  int res;
+
+  do {
+    res = unlink(filename);
+  } while(res && ((error = ERRNO) == EINTR));
+  if(res)
+    logmsg("Error removing lock file %s error: %d %s",
+           filename, error, strerror(error));
+}
Index: tests/server/util.h
===================================================================
RCS file: /cvsroot/curl/curl/tests/server/util.h,v
retrieving revision 1.18
diff -U 5 -r1.18 util.h
--- tests/server/util.h	28 Feb 2008 09:38:32 -0000	1.18
+++ tests/server/util.h	23 Apr 2008 19:14:40 -0000
@@ -25,10 +25,12 @@
 
 void logmsg(const char *msg, ...);
 
 #define TEST_DATA_PATH "%s/data/test%ld"
 
+#define SERVERLOGS_LOCK "log/serverlogs.lock"
+
 /* global variable, where to find the 'data' dir */
 extern const char *path;
 
 #ifdef WIN32
 #include <process.h>
@@ -51,6 +53,10 @@
 
 int wait_ms(int timeout_ms);
 
 int write_pidfile(const char *filename);
 
+void set_advisor_read_lock(const char *filename);
+
+void clear_advisor_read_lock(const char *filename);
+
 #endif  /* __SERVER_UTIL_H */
