Minor note, please use the the --subject-prefix="PATCH rtems-libbsd" as mentioned in https://docs.rtems.org/branches/master/eng/vc-users.html#creating-a-patch
This helps set the context of the patch review better for non-rtems.git patches. On Tue, Jun 8, 2021 at 9:50 AM Stephen Clark <stephen.cl...@oarcorp.com> wrote: > > Added the original Test TCP (TTCP) program in unmodified form. > Also added the associated README. > --- > rtemsbsd/ttcp/README | 27 ++ > rtemsbsd/ttcp/ttcp.c | 841 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 868 insertions(+) > create mode 100644 rtemsbsd/ttcp/README > create mode 100644 rtemsbsd/ttcp/ttcp.c > > diff --git a/rtemsbsd/ttcp/README b/rtemsbsd/ttcp/README > new file mode 100644 > index 00000000..215ddacc > --- /dev/null > +++ b/rtemsbsd/ttcp/README > @@ -0,0 +1,27 @@ > +TTCP is a benchmarking tool for determining TCP and UDP performance > +between 2 systems. > + > +The program was created at the US Army Ballistics Research Lab (BRL) > +and is in the public domain. Feel free to distribute this program > +but please do leave the credit notices in the source and man page intact. > + > +Contents of this directory: > + > +ttcp.c Source that runs on IRIX 3.3.x and 4.0.x systems > + and BSD-based systems. This version also uses getopt(3) > + and has 2 new options: -f and -T. > + > +ttcp.c-brl Original source from BRL. > + > +ttcp.1 Manual page (describes ttcp.c options, which are a > + superset of the other version). > + > + > +How to get TCP performance numbers: > + > + receiver sender > + > +host1% ttcp -r -s host2% ttcp -t -s host1 > + > +-n and -l options change the number and size of the buffers. > + Does this code come from somewhere that should be documented in the README? > diff --git a/rtemsbsd/ttcp/ttcp.c b/rtemsbsd/ttcp/ttcp.c > new file mode 100644 > index 00000000..305a7c7d > --- /dev/null > +++ b/rtemsbsd/ttcp/ttcp.c > @@ -0,0 +1,841 @@ > +/* > + * T T C P . C > + * > + * Test TCP connection. Makes a connection on port 5001 > + * and transfers fabricated buffers or data copied from stdin. > + * > + * Usable on 4.2, 4.3, and 4.1a systems by defining one of > + * BSD42 BSD43 (BSD41a) > + * Machines using System V with BSD sockets should define SYSV. > + * > + * Modified for operation under 4.2BSD, 18 Dec 84 > + * T.C. Slattery, USNA > + * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85. > + * Modified in 1989 at Silicon Graphics, Inc. > + * catch SIGPIPE to be able to print stats when receiver has died > + * for tcp, don't look for sentinel during reads to allow small transfers > + * increased default buffer size to 8K, nbuf to 2K to transfer 16MB > + * moved default port to 5001, beyond IPPORT_USERRESERVED > + * make sinkmode default because it is more popular, > + * -s now means don't sink/source > + * count number of read/write system calls to see effects of > + * blocking from full socket buffers > + * for tcp, -D option turns off buffered writes (sets TCP_NODELAY > sockopt) > + * buffer alignment options, -A and -O > + * print stats in a format that's a bit easier to use with grep & awk > + * for SYSV, mimic BSD routines to use most of the existing timing code > + * Modified by Steve Miller of the University of Maryland, College Park > + * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF) > + * Modified Sept. 1989 at Silicon Graphics, Inc. > + * restored -s sense at request of tcs@brl > + * Modified Oct. 1991 at Silicon Graphics, Inc. > + * use getopt(3) for option processing, add -f and -T options. > + * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV. > + * > + * Distribution Status - > + * Public Domain. Distribution Unlimited. > + */ > +#ifndef lint > +static char RCSid[] = "ttcp.c $Revision$"; > +#endif > + > +#define BSD43 > +/* #define BSD42 */ > +/* #define BSD41a */ > +/* #define SYSV */ /* required on SGI IRIX releases before 3.3 */ > + > +#include <stdio.h> > +#include <signal.h> > +#include <ctype.h> > +#include <errno.h> > +#include <sys/types.h> > +#include <sys/socket.h> > +#include <netinet/in.h> > +#include <netinet/tcp.h> > +#include <arpa/inet.h> > +#include <netdb.h> > +#include <sys/time.h> /* struct timeval */ > + > +#if defined(SYSV) > +#include <sys/times.h> > +#include <sys/param.h> > +struct rusage { > + struct timeval ru_utime, ru_stime; > +}; > +#define RUSAGE_SELF 0 > +#else > +#include <sys/resource.h> > +#endif > + > +struct sockaddr_in sinme; > +struct sockaddr_in sinhim; > +struct sockaddr_in frominet; > + > +int domain, fromlen; > +int fd; /* fd of network socket */ > + > +int buflen = 8 * 1024; /* length of buffer */ > +char *buf; /* ptr to dynamic buffer */ > +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ > + > +int bufoffset = 0; /* align buffer to this */ > +int bufalign = 16*1024; /* modulo this */ > + > +int udp = 0; /* 0 = tcp, !0 = udp */ > +int options = 0; /* socket options */ > +int one = 1; /* for 4.3 BSD style setsockopt() */ > +short port = 5001; /* TCP port number */ > +char *host; /* ptr to name of host */ > +int trans; /* 0=receive, !0=transmit mode */ > +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ > +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc > + * resource usage. */ > +int nodelay = 0; /* set TCP_NODELAY socket option */ > +int b_flag = 0; /* use mread() */ > +int sockbufsize = 0; /* socket buffer size to use */ > +char fmt = 'K'; /* output format: k = kilobits, K = > kilobytes, > + * m = megabits, M = megabytes, > + * g = gigabits, G = gigabytes */ > +int touchdata = 0; /* access data after reading */ > + > +struct hostent *addr; > +extern int errno; > +extern int optind; > +extern char *optarg; > + > +char Usage[] = "\ > +Usage: ttcp -t [-options] host [ < in ]\n\ > + ttcp -r [-options > out]\n\ > +Common options:\n\ > + -l ## length of bufs read from or written to network (default > 8192)\n\ > + -u use UDP instead of TCP\n\ > + -p ## port number to send to or listen at (default 5001)\n\ > + -s -t: source a pattern to network\n\ > + -r: sink (discard) all data from network\n\ > + -A align the start of buffers to this modulus (default 16384)\n\ > + -O start buffers at this offset from the modulus (default 0)\n\ > + -v verbose: print more statistics\n\ > + -d set SO_DEBUG socket option\n\ > + -b ## set socket buffer size (if supported)\n\ > + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = > giga\n\ > +Options specific to -t:\n\ > + -n## number of source bufs written to network (default 2048)\n\ > + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ > +Options specific to -r:\n\ > + -B for -s, only output full blocks as specified by -l (for > TAR)\n\ > + -T \"touch\": access each byte as it's read\n\ > +"; > + > +char stats[128]; > +double nbytes; /* bytes on net */ > +unsigned long numCalls; /* # of I/O system calls */ > +double cput, realt; /* user, real time (seconds) */ > + > +void err(); > +void mes(); > +int pattern(); > +void prep_timer(); > +double read_timer(); > +int Nread(); > +int Nwrite(); > +void delay(); > +int mread(); > +char *outfmt(); > + > +void > +sigpipe() > +{ > +} > + > +main(argc,argv) > +int argc; > +char **argv; > +{ > + unsigned long addr_tmp; > + int c; > + > + if (argc < 2) goto usage; > + > + while ((c = getopt(argc, argv, "drstuvBDTb:f:l:n:p:A:O:")) != -1) { > + switch (c) { > + > + case 'B': > + b_flag = 1; > + break; > + case 't': > + trans = 1; > + break; > + case 'r': > + trans = 0; > + break; > + case 'd': > + options |= SO_DEBUG; > + break; > + case 'D': > +#ifdef TCP_NODELAY > + nodelay = 1; > +#else > + fprintf(stderr, > + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); > +#endif > + break; > + case 'n': > + nbuf = atoi(optarg); > + break; > + case 'l': > + buflen = atoi(optarg); > + break; > + case 's': > + sinkmode = !sinkmode; > + break; > + case 'p': > + port = atoi(optarg); > + break; > + case 'u': > + udp = 1; > + break; > + case 'v': > + verbose = 1; > + break; > + case 'A': > + bufalign = atoi(optarg); > + break; > + case 'O': > + bufoffset = atoi(optarg); > + break; > + case 'b': > +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) > + sockbufsize = atoi(optarg); > +#else > + fprintf(stderr, > +"ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not > supported\n"); > +#endif > + break; > + case 'f': > + fmt = *optarg; > + break; > + case 'T': > + touchdata = 1; > + break; > + > + default: > + goto usage; > + } > + } > + if(trans) { > + /* xmitr */ > + if (optind == argc) > + goto usage; > + bzero((char *)&sinhim, sizeof(sinhim)); > + host = argv[optind]; > + if (atoi(host) > 0 ) { > + /* Numeric */ > + sinhim.sin_family = AF_INET; > +#if defined(cray) > + addr_tmp = inet_addr(host); > + sinhim.sin_addr = addr_tmp; > +#else > + sinhim.sin_addr.s_addr = inet_addr(host); > +#endif > + } else { > + if ((addr=gethostbyname(host)) == NULL) > + err("bad hostname"); > + sinhim.sin_family = addr->h_addrtype; > + bcopy(addr->h_addr,(char*)&addr_tmp, addr->h_length); > +#if defined(cray) > + sinhim.sin_addr = addr_tmp; > +#else > + sinhim.sin_addr.s_addr = addr_tmp; > +#endif /* cray */ > + } > + sinhim.sin_port = htons(port); > + sinme.sin_port = 0; /* free choice */ > + } else { > + /* rcvr */ > + sinme.sin_port = htons(port); > + } > + > + > + if (udp && buflen < 5) { > + buflen = 5; /* send more than the sentinel size */ > + } > + > + if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) > + err("malloc"); > + if (bufalign != 0) > + buf +=(bufalign - ((int)buf % bufalign) + bufoffset) % > bufalign; > + > + if (trans) { > + fprintf(stdout, > + "ttcp-t: buflen=%d, nbuf=%d, align=%d/%d, port=%d", > + buflen, nbuf, bufalign, bufoffset, port); > + if (sockbufsize) > + fprintf(stdout, ", sockbufsize=%d", sockbufsize); > + fprintf(stdout, " %s -> %s\n", udp?"udp":"tcp", host); > + } else { > + fprintf(stdout, > + "ttcp-r: buflen=%d, nbuf=%d, align=%d/%d, port=%d", > + buflen, nbuf, bufalign, bufoffset, port); > + if (sockbufsize) > + fprintf(stdout, ", sockbufsize=%d", sockbufsize); > + fprintf(stdout, " %s\n", udp?"udp":"tcp"); > + } > + > + if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) > + err("socket"); > + mes("socket"); > + > + if (bind(fd, &sinme, sizeof(sinme)) < 0) > + err("bind"); > + > +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) > + if (sockbufsize) { > + if (trans) { > + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, > + sizeof sockbufsize) < 0) > + err("setsockopt: sndbuf"); > + mes("sndbuf"); > + } else { > + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, > + sizeof sockbufsize) < 0) > + err("setsockopt: rcvbuf"); > + mes("rcvbuf"); > + } > + } > +#endif > + > + if (!udp) { > + signal(SIGPIPE, sigpipe); > + if (trans) { > + /* We are the client if transmitting */ > + if (options) { > +#if defined(BSD42) > + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) > +#else /* BSD43 */ > + if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) > +#endif > + err("setsockopt"); > + } > +#ifdef TCP_NODELAY > + if (nodelay) { > + struct protoent *p; > + p = getprotobyname("tcp"); > + if( p && setsockopt(fd, p->p_proto, TCP_NODELAY, > + &one, sizeof(one)) < 0) > + err("setsockopt: nodelay"); > + mes("nodelay"); > + } > +#endif > + if(connect(fd, &sinhim, sizeof(sinhim) ) < 0) > + err("connect"); > + mes("connect"); > + } else { > + /* otherwise, we are the server and > + * should listen for the connections > + */ > +#if defined(ultrix) || defined(sgi) > + listen(fd,1); /* workaround for alleged u4.2 bug */ > +#else > + listen(fd,0); /* allow a queue of 0 */ > +#endif > + if(options) { > +#if defined(BSD42) > + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) > +#else /* BSD43 */ > + if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) > +#endif > + err("setsockopt"); > + } > + fromlen = sizeof(frominet); > + domain = AF_INET; > + if((fd=accept(fd, &frominet, &fromlen) ) < 0) > + err("accept"); > + { struct sockaddr_in peer; > + int peerlen = sizeof(peer); > + if (getpeername(fd, (struct sockaddr_in *) &peer, > + &peerlen) < 0) { > + err("getpeername"); > + } > + fprintf(stderr,"ttcp-r: accept from %s\n", > + inet_ntoa(peer.sin_addr)); > + } > + } > + } > + prep_timer(); > + errno = 0; > + if (sinkmode) { > + register int cnt; > + if (trans) { > + pattern( buf, buflen ); > + if(udp) (void)Nwrite( fd, buf, 4 ); /* rcvr start */ > + while (nbuf-- && Nwrite(fd,buf,buflen) == buflen) > + nbytes += buflen; > + if(udp) (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > + } else { > + if (udp) { > + while ((cnt=Nread(fd,buf,buflen)) > 0) { > + static int going = 0; > + if( cnt <= 4 ) { > + if( going ) > + break; /* "EOF" */ > + going = 1; > + prep_timer(); > + } else { > + nbytes += cnt; > + } > + } > + } else { > + while ((cnt=Nread(fd,buf,buflen)) > 0) { > + nbytes += cnt; > + } > + } > + } > + } else { > + register int cnt; > + if (trans) { > + while((cnt=read(0,buf,buflen)) > 0 && > + Nwrite(fd,buf,cnt) == cnt) > + nbytes += cnt; > + } else { > + while((cnt=Nread(fd,buf,buflen)) > 0 && > + write(1,buf,cnt) == cnt) > + nbytes += cnt; > + } > + } > + if(errno) err("IO"); > + (void)read_timer(stats,sizeof(stats)); > + if(udp&&trans) { > + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > + } > + if( cput <= 0.0 ) cput = 0.001; > + if( realt <= 0.0 ) realt = 0.001; > + fprintf(stdout, > + "ttcp%s: %.0f bytes in %.2f real seconds = %s/sec +++\n", > + trans?"-t":"-r", > + nbytes, realt, outfmt(nbytes/realt)); > + if (verbose) { > + fprintf(stdout, > + "ttcp%s: %.0f bytes in %.2f CPU seconds = %s/cpu sec\n", > + trans?"-t":"-r", > + nbytes, cput, outfmt(nbytes/cput)); > + } > + fprintf(stdout, > + "ttcp%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", > + trans?"-t":"-r", > + numCalls, > + 1024.0 * realt/((double)numCalls), > + ((double)numCalls)/realt); > + fprintf(stdout,"ttcp%s: %s\n", trans?"-t":"-r", stats); > + if (verbose) { > + fprintf(stdout, > + "ttcp%s: buffer address %#x\n", > + trans?"-t":"-r", > + buf); > + } > + exit(0); > + > +usage: > + fprintf(stderr,Usage); > + exit(1); > +} > + > +void > +err(s) > +char *s; > +{ > + fprintf(stderr,"ttcp%s: ", trans?"-t":"-r"); > + perror(s); > + fprintf(stderr,"errno=%d\n",errno); > + exit(1); > +} > + > +void > +mes(s) > +char *s; > +{ > + fprintf(stderr,"ttcp%s: %s\n", trans?"-t":"-r", s); > +} > + > +pattern( cp, cnt ) > +register char *cp; > +register int cnt; > +{ > + register char c; > + c = 0; > + while( cnt-- > 0 ) { > + while( !isprint((c&0x7F)) ) c++; > + *cp++ = (c++&0x7F); > + } > +} > + > +char * > +outfmt(b) > +double b; > +{ > + static char obuf[50]; > + switch (fmt) { > + case 'G': > + sprintf(obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); > + break; > + default: > + case 'K': > + sprintf(obuf, "%.2f KB", b / 1024.0); > + break; > + case 'M': > + sprintf(obuf, "%.2f MB", b / 1024.0 / 1024.0); > + break; > + case 'g': > + sprintf(obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); > + break; > + case 'k': > + sprintf(obuf, "%.2f Kbit", b * 8.0 / 1024.0); > + break; > + case 'm': > + sprintf(obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); > + break; > + } > + return obuf; > +} > + > +static struct timeval time0; /* Time at which timing started */ > +static struct rusage ru0; /* Resource utilization at the start */ > + > +static void prusage(); > +static void tvadd(); > +static void tvsub(); > +static void psecs(); > + > +#if defined(SYSV) > +/*ARGSUSED*/ > +static > +getrusage(ignored, ru) > + int ignored; > + register struct rusage *ru; > +{ > + struct tms buf; > + > + times(&buf); > + > + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ > + ru->ru_stime.tv_sec = buf.tms_stime / HZ; > + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; > + ru->ru_utime.tv_sec = buf.tms_utime / HZ; > + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; > +} > + > +/*ARGSUSED*/ > +static > +gettimeofday(tp, zp) > + struct timeval *tp; > + struct timezone *zp; > +{ > + tp->tv_sec = time(0); > + tp->tv_usec = 0; > +} > +#endif /* SYSV */ > + > +/* > + * P R E P _ T I M E R > + */ > +void > +prep_timer() > +{ > + gettimeofday(&time0, (struct timezone *)0); > + getrusage(RUSAGE_SELF, &ru0); > +} > + > +/* > + * R E A D _ T I M E R > + * > + */ > +double > +read_timer(str,len) > +char *str; > +{ > + struct timeval timedol; > + struct rusage ru1; > + struct timeval td; > + struct timeval tend, tstart; > + char line[132]; > + > + getrusage(RUSAGE_SELF, &ru1); > + gettimeofday(&timedol, (struct timezone *)0); > + prusage(&ru0, &ru1, &timedol, &time0, line); > + (void)strncpy( str, line, len ); > + > + /* Get real time */ > + tvsub( &td, &timedol, &time0 ); > + realt = td.tv_sec + ((double)td.tv_usec) / 1000000; > + > + /* Get CPU time (user+sys) */ > + tvadd( &tend, &ru1.ru_utime, &ru1.ru_stime ); > + tvadd( &tstart, &ru0.ru_utime, &ru0.ru_stime ); > + tvsub( &td, &tend, &tstart ); > + cput = td.tv_sec + ((double)td.tv_usec) / 1000000; > + if( cput < 0.00001 ) cput = 0.00001; > + return( cput ); > +} > + > +static void > +prusage(r0, r1, e, b, outp) > + register struct rusage *r0, *r1; > + struct timeval *e, *b; > + char *outp; > +{ > + struct timeval tdiff; > + register time_t t; > + register char *cp; > + register int i; > + int ms; > + > + t = (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ > + (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ > + (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ > + (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; > + ms = (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; > + > +#define END(x) {while(*x) x++;} > +#if defined(SYSV) > + cp = "%Uuser %Ssys %Ereal %P"; > +#else > +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ > + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; > +#else > + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; > +#endif > +#endif > + for (; *cp; cp++) { > + if (*cp != '%') > + *outp++ = *cp; > + else if (cp[1]) switch(*++cp) { > + > + case 'U': > + tvsub(&tdiff, &r1->ru_utime, &r0->ru_utime); > + sprintf(outp,"%d.%01d", tdiff.tv_sec, > tdiff.tv_usec/100000); > + END(outp); > + break; > + > + case 'S': > + tvsub(&tdiff, &r1->ru_stime, &r0->ru_stime); > + sprintf(outp,"%d.%01d", tdiff.tv_sec, > tdiff.tv_usec/100000); > + END(outp); > + break; > + > + case 'E': > + psecs(ms / 100, outp); > + END(outp); > + break; > + > + case 'P': > + sprintf(outp,"%d%%", (int) (t*100 / ((ms ? ms : 1)))); > + END(outp); > + break; > + > +#if !defined(SYSV) > + case 'W': > + i = r1->ru_nswap - r0->ru_nswap; > + sprintf(outp,"%d", i); > + END(outp); > + break; > + > + case 'X': > + sprintf(outp,"%d", t == 0 ? 0 : > (r1->ru_ixrss-r0->ru_ixrss)/t); > + END(outp); > + break; > + > + case 'D': > + sprintf(outp,"%d", t == 0 ? 0 : > + > (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); > + END(outp); > + break; > + > + case 'K': > + sprintf(outp,"%d", t == 0 ? 0 : > + ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - > + (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); > + END(outp); > + break; > + > + case 'M': > + sprintf(outp,"%d", r1->ru_maxrss/2); > + END(outp); > + break; > + > + case 'F': > + sprintf(outp,"%d", r1->ru_majflt-r0->ru_majflt); > + END(outp); > + break; > + > + case 'R': > + sprintf(outp,"%d", r1->ru_minflt-r0->ru_minflt); > + END(outp); > + break; > + > + case 'I': > + sprintf(outp,"%d", r1->ru_inblock-r0->ru_inblock); > + END(outp); > + break; > + > + case 'O': > + sprintf(outp,"%d", r1->ru_oublock-r0->ru_oublock); > + END(outp); > + break; > + case 'C': > + sprintf(outp,"%d+%d", r1->ru_nvcsw-r0->ru_nvcsw, > + r1->ru_nivcsw-r0->ru_nivcsw ); > + END(outp); > + break; > +#endif /* !SYSV */ > + } > + } > + *outp = '\0'; > +} > + > +static void > +tvadd(tsum, t0, t1) > + struct timeval *tsum, *t0, *t1; > +{ > + > + tsum->tv_sec = t0->tv_sec + t1->tv_sec; > + tsum->tv_usec = t0->tv_usec + t1->tv_usec; > + if (tsum->tv_usec > 1000000) > + tsum->tv_sec++, tsum->tv_usec -= 1000000; > +} > + > +static void > +tvsub(tdiff, t1, t0) > + struct timeval *tdiff, *t1, *t0; > +{ > + > + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; > + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; > + if (tdiff->tv_usec < 0) > + tdiff->tv_sec--, tdiff->tv_usec += 1000000; > +} > + > +static void > +psecs(l,cp) > +long l; > +register char *cp; > +{ > + register int i; > + > + i = l / 3600; > + if (i) { > + sprintf(cp,"%d:", i); > + END(cp); > + i = l % 3600; > + sprintf(cp,"%d%d", (i/60) / 10, (i/60) % 10); > + END(cp); > + } else { > + i = l; > + sprintf(cp,"%d", i / 60); > + END(cp); > + } > + i %= 60; > + *cp++ = ':'; > + sprintf(cp,"%d%d", i / 10, i % 10); > +} > + > +/* > + * N R E A D > + */ > +Nread( fd, buf, count ) > +int fd; > +void *buf; > +int count; > +{ > + struct sockaddr_in from; > + int len = sizeof(from); > + register int cnt; > + if( udp ) { > + cnt = recvfrom( fd, buf, count, 0, &from, &len ); > + numCalls++; > + } else { > + if( b_flag ) > + cnt = mread( fd, buf, count ); /* fill buf */ > + else { > + cnt = read( fd, buf, count ); > + numCalls++; > + } > + if (touchdata && cnt > 0) { > + register int c = cnt, sum; > + register char *b = buf; > + while (c--) > + sum += *b++; > + } > + } > + return(cnt); > +} > + > +/* > + * N W R I T E > + */ > +Nwrite( fd, buf, count ) > +int fd; > +void *buf; > +int count; > +{ > + register int cnt; > + if( udp ) { > +again: > + cnt = sendto( fd, buf, count, 0, &sinhim, sizeof(sinhim) ); > + numCalls++; > + if( cnt<0 && errno == ENOBUFS ) { > + delay(18000); > + errno = 0; > + goto again; > + } > + } else { > + cnt = write( fd, buf, count ); > + numCalls++; > + } > + return(cnt); > +} > + > +void > +delay(us) > +{ > + struct timeval tv; > + > + tv.tv_sec = 0; > + tv.tv_usec = us; > + (void)select( 1, (char *)0, (char *)0, (char *)0, &tv ); > +} > + > +/* > + * M R E A D > + * > + * This function performs the function of a read(II) but will > + * call read(II) multiple times in order to get the requested > + * number of characters. This can be necessary because > + * network connections don't deliver data with the same > + * grouping as it is written with. Written by Robert S. Miles, BRL. > + */ > +int > +mread(fd, bufp, n) > +int fd; > +register char *bufp; > +unsigned n; > +{ > + register unsigned count = 0; > + register int nread; > + > + do { > + nread = read(fd, bufp, n-count); > + numCalls++; > + if(nread < 0) { > + perror("ttcp_mread"); > + return(-1); > + } > + if(nread == 0) > + return((int)count); > + count += (unsigned)nread; > + bufp += nread; > + } while(count < n); > + > + return((int)count); > +} > -- > 2.27.0 > > _______________________________________________ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel