tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ftp and ftpd should use a monotonic clock



Hi List

ftp and ftpd both use gettimeofday to work out how long an action took.
If the system time changes this the time deltas reported will be wrong.
References for this happening are here [1].

Attached are patches to ftp and ftpd which change the relevant parts from timeval + gettimeofday to timespec + clock_gettime using a MONOTONIC clock so that deltas are more accurately reported.

Please consider applying :)

Thanks

Roy

[1] http://mail-index.netbsd.org/current-users/2008/07/17/msg003559.html
? .gdbinit
? .progressbar.c.swp
? ftp
? ftp.cat1
Index: progressbar.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/progressbar.c,v
retrieving revision 1.20
diff -u -p -r1.20 progressbar.c
--- progressbar.c       30 Sep 2008 03:41:53 -0000      1.20
+++ progressbar.c       30 Oct 2008 10:51:03 -0000
@@ -112,8 +112,8 @@ static const char * const suffixes[] = {
  *   with flag = 0
  * - After the transfer, call with flag = 1
  */
-static struct timeval start;
-static struct timeval lastupdate;
+static struct timespec start;
+static struct timespec lastupdate;
 
 #define        BUFLEFT (sizeof(buf) - len)
 
@@ -122,9 +122,9 @@ progressmeter(int flag)
 {
        static off_t lastsize;
        off_t cursize;
-       struct timeval now, wait;
+       struct timespec now, wait;
 #ifndef NO_PROGRESS
-       struct timeval td;
+       struct timespec td;
        off_t abbrevsize, bytespersec;
        double elapsed;
        int ratio, i, remaining, barlength;
@@ -154,14 +154,14 @@ progressmeter(int flag)
 #endif
 
        if (flag == -1) {
-               (void)gettimeofday(&start, NULL);
+               (void)clock_gettime(CLOCK_MONOTONIC, &start);
                lastupdate = start;
                lastsize = restart_point;
        }
 
-       (void)gettimeofday(&now, NULL);
+       (void)clock_gettime(CLOCK_MONOTONIC, &now);
        cursize = bytes + restart_point;
-       timersub(&now, &lastupdate, &wait);
+       timespecsub(&now, &lastupdate, &wait);
        if (cursize > lastsize) {
                lastupdate = now;
                lastsize = cursize;
@@ -238,8 +238,8 @@ progressmeter(int flag)
            (LLT)abbrevsize,
            suffixes[i]);
 
-       timersub(&now, &start, &td);
-       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
+       timespecsub(&now, &start, &td);
+       elapsed = td.tv_sec + (td.tv_nsec / 1000000000.0);
 
        bytespersec = 0;
        if (bytes > 0) {
@@ -300,7 +300,7 @@ progressmeter(int flag)
 void
 ptransfer(int siginfo)
 {
-       struct timeval now, td, wait;
+       struct timespec now, td, wait;
        double elapsed;
        off_t bytespersec;
        int remaining, hh, i;
@@ -311,9 +311,9 @@ ptransfer(int siginfo)
        if (!verbose && !progress && !siginfo)
                return;
 
-       (void)gettimeofday(&now, NULL);
-       timersub(&now, &start, &td);
-       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
+       (void)clock_gettime(CLOCK_MONOTONIC, &now);
+       timespecsub(&now, &start, &td);
+       elapsed = td.tv_sec + (td.tv_nsec / 1000000000.0);
        bytespersec = 0;
        if (bytes > 0) {
                bytespersec = bytes;
@@ -359,7 +359,7 @@ ptransfer(int siginfo)
                        len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
                len += snprintf(buf + len, BUFLEFT, "%02d:%02d",
                    remaining / 60, remaining % 60);
-               timersub(&now, &lastupdate, &wait);
+               timespecsub(&now, &lastupdate, &wait);
                if (wait.tv_sec >= STALLTIME)
                        len += snprintf(buf + len, BUFLEFT, "  (stalled)");
        }
? ftpcmd.c
? ftpd.cat8
? ftpd.conf.cat5
? ftpusers.cat5
Index: extern.h
===================================================================
RCS file: /cvsroot/src/libexec/ftpd/extern.h,v
retrieving revision 1.58
diff -u -p -r1.58 extern.h
--- extern.h    13 Sep 2008 03:30:35 -0000      1.58
+++ extern.h    30 Oct 2008 11:20:22 -0000
@@ -135,7 +135,7 @@ FILE   *ftpd_popen(char *[], const char 
 int    getline(char *, int, FILE *);
 void   init_curclass(void);
 void   logxfer(const char *, off_t, const char *, const char *,
-           const struct timeval *, const char *);
+           const struct timespec *, const char *);
 struct tab *lookup(struct tab *, const char *);
 void   makedir(const char *);
 void   mlsd(const char *);
Index: ftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.188
diff -u -p -r1.188 ftpd.c
--- ftpd.c      16 Sep 2008 12:30:38 -0000      1.188
+++ ftpd.c      30 Oct 2008 11:20:23 -0000
@@ -1682,7 +1682,7 @@ retrieve(char *argv[], const char *name)
        struct stat st;
        int (*closefunc)(FILE *) = NULL;
        int dolog, sendrv, closerv, stderrfd, isconversion, isdata, isls;
-       struct timeval start, finish, td, *tdp;
+       struct timespec start, finish, td, *tdp;
        struct rusage rusage_before, rusage_after;
        const char *dispname;
        char *error;
@@ -1765,12 +1765,12 @@ retrieve(char *argv[], const char *name)
                goto done;
 
        (void)getrusage(RUSAGE_SELF, &rusage_before);
-       (void)gettimeofday(&start, NULL);
+       (void)clock_gettime(CLOCK_MONOTONIC, &start);
        sendrv = send_data(fin, dout, &st, isdata);
-       (void)gettimeofday(&finish, NULL);
+       (void)clock_gettime(CLOCK_MONOTONIC, &finish);
        (void)getrusage(RUSAGE_SELF, &rusage_after);
        closedataconn(dout);            /* close now to affect timing stats */
-       timersub(&finish, &start, &td);
+       timespecsub(&finish, &start, &td);
        tdp = &td;
  done:
        if (dolog) {
@@ -1823,7 +1823,7 @@ store(const char *name, const char *fmod
        FILE *fout, *din;
        struct stat st;
        int (*closefunc)(FILE *);
-       struct timeval start, finish, td, *tdp;
+       struct timespec start, finish, td, *tdp;
        char *desc, *error;
 
        din = NULL;
@@ -1880,7 +1880,7 @@ store(const char *name, const char *fmod
        din = dataconn(name, (off_t)-1, "r");
        if (din == NULL)
                goto done;
-       (void)gettimeofday(&start, NULL);
+       (void)clock_gettime(CLOCK_MONOTONIC, &start);
        if (receive_data(din, fout) == 0) {
                if (unique)
                        reply(226, "Transfer complete (unique file name:%s).",
@@ -1888,9 +1888,9 @@ store(const char *name, const char *fmod
                else
                        reply(226, "Transfer complete.");
        }
-       (void)gettimeofday(&finish, NULL);
+       (void)clock_gettime(CLOCK_MONOTONIC, &finish);
        closedataconn(din);             /* close now to affect timing stats */
-       timersub(&finish, &start, &td);
+       timespecsub(&finish, &start, &td);
        tdp = &td;
  done:
        logxfer(desc, byte_count, name, NULL, tdp, error);
@@ -3544,7 +3544,7 @@ conffilename(const char *s)
  */
 void
 logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
-    const struct timeval *elapsed, const char *error)
+    const struct timespec *elapsed, const char *error)
 {
        char             buf[MAXPATHLEN * 2 + 100];
        char             realfile1[MAXPATHLEN], realfile2[MAXPATHLEN];
@@ -3576,8 +3576,8 @@ logxfer(const char *command, off_t bytes
                            " %s", r2);
                if (elapsed != NULL)
                        len += snprintf(buf + len, sizeof(buf) - len,
-                           " in %ld.%.03d seconds", elapsed->tv_sec,
-                           (int)(elapsed->tv_usec / 1000));
+                           " in %ld.%.03d seconds", (long int)elapsed->tv_sec,
+                           (int)(elapsed->tv_nsec / 1000000));
                if (error != NULL)
                        len += snprintf(buf + len, sizeof(buf) - len,
                            ": %s", error);
@@ -3607,7 +3607,7 @@ logxfer(const char *command, off_t bytes
  *     given that syslog messages don't contain the full date.
  */
            ctime(&now),
-           elapsed == NULL ? 0 : elapsed->tv_sec + (elapsed->tv_usec > 0),
+           elapsed == NULL ? 0 : (long int)elapsed->tv_sec + (elapsed->tv_nsec 
> 0),
            remotehost,
            (LLT) bytes,
            r1,


Home | Main Index | Thread Index | Old Index