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