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