1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
$NetBSD: patch-ab,v 1.4 2019/06/15 15:01:03 christos Exp $
1. handle SIGCLD portably
2. define a large enough value for SO_LINGER that does not fail
3. add a runtime option -U <seconds>
--- nttcp.c.orig 2000-12-18 05:16:54.000000000 -0500
+++ nttcp.c 2019-06-15 10:56:28.798775017 -0400
@@ -136,9 +136,9 @@
#endif /* aix */
/*====================================================================*/
-#if defined(FreeBSD)
+#ifndef SIGCLD
#define SIGCLD SIGCHLD
-#endif /*FreeBSD*/
+#endif /*SIGCLD*/
/*====================================================================*/
#if defined(BSD42)
@@ -268,6 +268,7 @@
\t-n# number of source bufs written to network (default 2048)\n\
\t-u use UDP instead of TCP\n\
\t-g#us gap in micro seconds between UDP packets (default 0s)\n\
+\t-U# run until a number of seconds have elapsed\n\
\t-d set SO_DEBUG in sockopt\n\
\t-D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\
\t-w# set the send buffer space to #kilobytes, which is\n\
@@ -310,9 +311,15 @@
setitimer(ITIMER_REAL, &itval, Nil(struct itimerval))
#define Suspend(msec) SetItVal(msec); pause()
+/*
+ * we use 32767 (9 hours) because this is the largest implementation-specific
+ * value that we can since on the BSD's the kernel linger value is
+ * unsigned short, on opensolaris is int, and on linux is unsigned long
+ * scaled by HZ.
+ */
struct linger Ling = {
1, /* option on */
- 1000000 /* linger time, for our control connection */
+ 32767 /* linger time, for our control connection */
};
/* global variables needed by StartTimer, StopTimer */
@@ -346,6 +353,7 @@
int FixedDataSize; /* if>0: calc BufCnt/BufLen from this */
int Window, SndWin, RcvWin; /* TCP window sizes */
int Verbose; /* ==1: more diagnostics */
+ int RunTime; /* approximate runtime in seconds */
char *MulticastChannel; /* we send multicast traffic */
short MulticastPort;
int GapLength; /* Gap length between packets */
@@ -496,6 +504,13 @@
SysCalls=0;
}
+int CheckTimer() {
+ TimeVal now;
+
+ gettimeofday(&now, (struct timezone *)0);
+ return opt.RunTime < (now.tv_sec - time0.tv_sec);
+}
+
void StopTimer(double *cput, double *realt) {
/* delivers in cput: the amount of cpu time in seconds
* in realt: the real time in seconds
@@ -878,6 +893,7 @@
opt->Verbose=0; /* ==1: more diagnostics */
opt->GapLength=0; /* no delay, send as fast as possible */
opt->inetd= 0; /* ==1: run in inetd mode */
+ opt->RunTime = 0; /* run effectively forever (ie BufCnt is limiting factor) */
opt->Service= GetService(); /* the service-port to listen to */
opt->MulticastChannel= NULL;
opt->MulticastPort= 0;
@@ -1013,6 +1029,10 @@
#endif /*MULTICAST*/
break;
}
+ case 'U':
+ GetSizeValue(&argc, &argv, &opt->RunTime, 1000000000,
+ "runtime");
+ break;
default: {
strcpy(MsgBuf, "unknown option: ");
strncat(MsgBuf, argv[0], sizeof(MsgBuf)-strlen(MsgBuf)-1);
@@ -1427,6 +1447,10 @@
sprintf(OptBuf, "-g%d", opt.GapLength);
StrVecAppend(RemOpt, OptBuf);
}
+ if (opt.RunTime > 0) {
+ sprintf(OptBuf, "-U%d", opt.RunTime);
+ StrVecAppend(RemOpt, OptBuf);
+ }
if (opt.MulticastChannel) {
sprintf(OptBuf, "-m%s:%d",
opt.MulticastChannel, opt.MulticastPort);
@@ -1781,9 +1805,17 @@
else
Pattern(buf, opt.BufLen);
StartTimer();
- while (n-- && Nwrite(fd, buf, opt.BufLen) == opt.BufLen) {
+ while (Nwrite(fd, buf, opt.BufLen) == opt.BufLen) {
nBytes+= opt.BufLen;
nBuffer++;
+ if (opt.RunTime == 0) {
+ if (--n == 0)
+ break;
+ } else {
+ /* XXX: tune how often to check if timer has expired? */
+ if ((nBuffer % 100 == 0) && CheckTimer())
+ break;
+ }
}
StopTimer(&cput, &realt);
opt.GapLength= 0;
@@ -1797,9 +1829,17 @@
nBytes= 0;
nBuffer= 0;
StartTimer();
- while (n-- && Nwrite(fd, buf, opt.BufLen) == opt.BufLen) {
+ while (Nwrite(fd, buf, opt.BufLen) == opt.BufLen) {
nBytes+= opt.BufLen;
nBuffer++;
+ if (opt.RunTime == 0) {
+ if (--n == 0)
+ break;
+ } else {
+ /* XXX: tune how often to check if timer has expired? */
+ if ((nBuffer % 100 == 0) && CheckTimer())
+ break;
+ }
}
StopTimer(&cput, &realt);
}
|