On Fri, Jun 11, 2021 at 11:19 AM Stephen Clark <stephen.cl...@oarcorp.com> wrote: > > Updated ttcp.c to build for RTEMS 6, in addition to the machines > it originally built for. Also fixed ttcp.c to close network sockets > after completion. Defined a shell command for TTCP in > rtems-bsd-shell-ttcp.c. Added TTCP to the list of RTEMS network > commands in netcmds-config.h. Added declaration of the TTCP shell > command to rtems-bsd-commands.h. Modified libbsd.py to make waf > build TTCP and its shell command. > --- > libbsd.py | 2 + > rtemsbsd/include/machine/rtems-bsd-commands.h | 2 + > rtemsbsd/include/rtems/netcmds-config.h | 2 + > rtemsbsd/rtems/rtems-bsd-shell-ttcp.c | 39 +++ > rtemsbsd/ttcp/README | 11 +- > rtemsbsd/ttcp/ttcp.c | 266 ++++++++++++++---- > 6 files changed, 262 insertions(+), 60 deletions(-) > create mode 100644 rtemsbsd/rtems/rtems-bsd-shell-ttcp.c > > diff --git a/libbsd.py b/libbsd.py > index b367d94e..2badfdee 100644 > --- a/libbsd.py > +++ b/libbsd.py > @@ -269,6 +269,7 @@ class rtems(builder.Module): > 'rtems/rtems-bsd-shell-tcpdump.c', > 'rtems/rtems-bsd-shell-vmstat.c', > 'rtems/rtems-bsd-shell-wlanstats.c', > + 'rtems/rtems-bsd-shell-ttcp.c', > 'rtems/rtems-kvm.c', > 'rtems/rtems-program.c', > 'rtems/rtems-program-socket.c', > @@ -292,6 +293,7 @@ class rtems(builder.Module): > 'pppd/upap.c', > 'pppd/utils.c', > 'telnetd/telnetd-service.c', > + 'ttcp/ttcp.c', > ], > mm.generator['source']() > ) > diff --git a/rtemsbsd/include/machine/rtems-bsd-commands.h > b/rtemsbsd/include/machine/rtems-bsd-commands.h > index d314471f..d82c274c 100644 > --- a/rtemsbsd/include/machine/rtems-bsd-commands.h > +++ b/rtemsbsd/include/machine/rtems-bsd-commands.h > @@ -84,6 +84,8 @@ int rtems_bsd_command_setkey(int argc, char **argv); > > int rtems_bsd_command_openssl(int argc, char **argv); > > +int rtems_shell_main_ttcp(int argc, char **argv); > + > __END_DECLS > > #endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */ > diff --git a/rtemsbsd/include/rtems/netcmds-config.h > b/rtemsbsd/include/rtems/netcmds-config.h > index bc493af4..c1d56eb3 100644 > --- a/rtemsbsd/include/rtems/netcmds-config.h > +++ b/rtemsbsd/include/rtems/netcmds-config.h > @@ -29,6 +29,8 @@ extern rtems_shell_cmd_t rtems_shell_PFCTL_Command; > extern rtems_shell_cmd_t rtems_shell_PING_Command; > extern rtems_shell_cmd_t rtems_shell_PING6_Command; > > +extern rtems_shell_cmd_t rtems_shell_TTCP_Command; > + > extern rtems_shell_cmd_t rtems_shell_IFCONFIG_Command; > > extern rtems_shell_cmd_t rtems_shell_IFMCSTAT_Command; > diff --git a/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c > b/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c > new file mode 100644 > index 00000000..babaa011 > --- /dev/null > +++ b/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c > @@ -0,0 +1,39 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > + > +/* > + * COPYRIGHT (c) 2021. On-Line Applications Research Corporation (OAR). > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +#include <rtems/netcmds-config.h> > +#include <machine/rtems-bsd-commands.h> > + > +rtems_shell_cmd_t rtems_shell_TTCP_Command = { > + "ttcp", /* name */ > + "ttcp -h # to get help", /* usage */ > + "net", /* topic */ > + rtems_shell_main_ttcp, /* command */ > + NULL, /* alias */ > + NULL /* next */ > +}; > diff --git a/rtemsbsd/ttcp/README b/rtemsbsd/ttcp/README > index 215ddacc..8a9bf017 100644 > --- a/rtemsbsd/ttcp/README > +++ b/rtemsbsd/ttcp/README > @@ -7,14 +7,9 @@ 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). > +ttcp.c Source that runs on IRIX 3.3.x and 4.0.x systems, > + BSD-based systems, and RTEMS. This version also > + uses getopt(3) and has 2 new options: -f and -T. > > > How to get TCP performance numbers: > diff --git a/rtemsbsd/ttcp/ttcp.c b/rtemsbsd/ttcp/ttcp.c > index dc62c64b..46e0f3fc 100644 > --- a/rtemsbsd/ttcp/ttcp.c > +++ b/rtemsbsd/ttcp/ttcp.c > @@ -74,48 +74,95 @@ struct rusage { > #include <sys/resource.h> > #endif > > -struct sockaddr_in sinme; > -struct sockaddr_in sinhim; > -struct sockaddr_in frominet; > +#if defined(__rtems__) > +#define __need_getopt_newlib > +#include <getopt.h> > +#include <rtems/shell.h> > +#endif > + > +static struct sockaddr_in sinme; > +static struct sockaddr_in sinhim; > +static struct sockaddr_in frominet; > Are some of these changes in line with an upstream copy? Are you trying to use the __rtems__ guards to demark the RTEMS-specific changes from the upstream copy?
Usually we would prefer to have all the upstream code added, and then add the __rtems__parts, and then add the code to the build system. Would that be possible and the right thing to do in this case also? > /* these make it easier to avoid warnings */ > -struct sockaddr *sinhim_p = (struct sockaddr *) &sinhim; > -struct sockaddr *sinme_p = (struct sockaddr *) &sinme; > -struct sockaddr *frominet_p = (struct sockaddr *) &frominet; > - > -int domain; > -socklen_t 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 > +static struct sockaddr *sinhim_p = (struct sockaddr *) &sinhim; > +static struct sockaddr *sinme_p = (struct sockaddr *) &sinme; > +static struct sockaddr *frominet_p = (struct sockaddr *) &frominet; > + > +static int domain; > +static socklen_t fromlen; > +static int fd; /* fd of network socket */ > + > +static int buflen = 8 * 1024; /* length of buffer */ > +static char *buf; /* ptr to dynamic buffer */ > +static char *alloc_buf; /* ptr to beginning of memory > allocated for buf */ > +static int nbuf = 2 * 1024; /* number of buffers to send in > sinkmode */ > + > +static int bufoffset = 0; /* align buffer to this */ > +static int bufalign = 16*1024; /* modulo this */ > + > +static int udp = 0; /* 0 = tcp, !0 = udp */ > +static int options = 0; /* socket options */ > +static int one = 1; /* for 4.3 BSD style setsockopt() */ > +static short port = 5001; /* TCP port number */ > +static char *host; /* ptr to name of host */ > +static int trans; /* 0=receive, !0=transmit mode */ > +static int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode > */ > +static 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, > +static int nodelay = 0; /* set TCP_NODELAY socket option */ > +static int b_flag = 0; /* use mread() */ > +static int sockbufsize = 0; /* socket buffer size to use */ > +static char fmt = 'K'; /* output format: k = kilobits, K = > kilobytes, > * m = megabits, M = megabytes, > * g = gigabits, G = gigabytes */ > -int touchdata = 0; /* access data after reading */ > -long milliseconds = 0; /* delay in milliseconds */ > +static int touchdata = 0; /* access data after reading */ > +static long milliseconds = 0; /* delay in milliseconds */ > > -struct hostent *addr; > -extern int errno; > -extern int optind; > -extern char *optarg; > +static struct hostent *addr; > +static void initialize_vars(void) > +{ > + memset(&sinme, 0, sizeof(sinme)); > + memset(&sinhim, 0, sizeof(sinhim)); > + memset(&frominet, 0, sizeof(frominet)); > + > + /* these make it easier to avoid warnings */ > + sinhim_p = (struct sockaddr *) &sinhim; > + sinme_p = (struct sockaddr *) &sinme; > + frominet_p = (struct sockaddr *) &frominet; > + > + domain = 0; > + fromlen = 0; > + fd = 0; /* fd of network socket */ > + > + buflen = 8 * 1024; /* length of buffer */ > + buf = NULL; /* ptr to dynamic buffer */ > + alloc_buf = NULL; /* ptr to beginning of memory allocated for buf */ > + nbuf = 2 * 1024; /* number of buffers to send in > sinkmode */ > + > + bufoffset = 0; /* align buffer to this */ > + bufalign = 16*1024; /* modulo this */ > + > + udp = 0; /* 0 = tcp, !0 = udp */ > + options = 0; /* socket options */ > + one = 1; /* for 4.3 BSD style setsockopt() */ > + port = 5001; /* TCP port number */ > + host = NULL; /* ptr to name of host */ > + trans = 0; /* 0=receive, !0=transmit mode */ > + sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ > + verbose = 0; /* 0=print basic info, 1=print cpu rate, proc > + * > resource usage. */ > + nodelay = 0; /* set TCP_NODELAY socket option */ > + b_flag = 0; /* use mread() */ > + sockbufsize = 0; /* socket buffer size to use */ > + fmt = 'K'; /* output format: k = kilobits, K = > kilobytes, > + * m > = megabits, M = megabytes, > + * g > = gigabits, G = gigabytes */ > + touchdata = 0; /* access data after reading */ > + milliseconds = 0; /* delay in milliseconds */ > + > + addr = NULL; > +} > > char Usage[] = "\ > Usage: ttcp -t [-options] host [ < in ]\n\ > @@ -173,16 +220,34 @@ void millisleep(long msec) > nanosleep( &req, NULL ); > #endif > } > + Avoid making own changes outside of the __rtems__ guards if you're trying to preserve compatibility with the upstream. Please read contributing.md. > +#if (defined (__rtems__)) > +int rtems_shell_main_ttcp(argc,argv) > +#else > int main(argc,argv) > +#endif > int argc; > char **argv; > { > + initialize_vars(); > unsigned long addr_tmp; > int c; > > if (argc < 2) goto usage; > > +#ifdef __rtems__ > + struct getopt_data getopt_reent; > +#define optarg getopt_reent.optarg > +#define optind getopt_reent.optind > +#define opterr getopt.reent.opterr > +#define optopt getopt.reent.optopt > + memset(&getopt_reent, 0, sizeof(getopt_data)); > + while ((c = getopt_r(argc, argv, > + "drstuvBDTb:f:l:m:n:p:A:O:", > + &getopt_reent)) != -1) { > +#else > while ((c = getopt(argc, argv, "drstuvBDTb:f:l:m:n:p:A:O:")) != -1) { > +#endif > switch (c) { > > case 'B': > @@ -270,8 +335,12 @@ char **argv; > sinhim.sin_addr.s_addr = inet_addr(host); > #endif > } else { > - if ((addr=gethostbyname(host)) == NULL) > + if ((addr=gethostbyname(host)) == NULL) { > err("bad hostname"); > +#ifdef __rtems__ > + return 1; > +#endif > + } I believe the proper way to do this is if ((addr=gethostbyname(host)) == NULL) #ifdef __rtems__ { #endif /* __rtems__ */ err("bad hostname"); #ifdef __rtems__ return 1; } #endif /* __rtems__ */ or #ifdef __rtems__ { err("bad hostname"); return 1; } #else /* __rtems__ */ err("bad hostname"); #endif /* __rtems__ */ > sinhim.sin_family = addr->h_addrtype; > bcopy(addr->h_addr,(char*)&addr_tmp, addr->h_length); > #if defined(cray) > @@ -292,8 +361,13 @@ char **argv; > buflen = 5; /* send more than the sentinel size */ > } > > - if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) > + if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) { > err("malloc"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > + alloc_buf = buf; > if (bufalign != 0) > buf +=(bufalign - ((int)buf % bufalign) + bufoffset) % > bufalign; > > @@ -313,24 +387,40 @@ char **argv; > fprintf(stdout, " %s\n", udp?"udp":"tcp"); > } > > - if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) > + if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) { > err("socket"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > mes("socket"); > > - if (bind(fd, sinme_p, sizeof(sinme)) < 0) > + if (bind(fd, sinme_p, sizeof(sinme)) < 0) { > err("bind"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > > #if defined(SO_SNDBUF) || defined(SO_RCVBUF) > if (sockbufsize) { > if (trans) { > if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, > - sizeof sockbufsize) < 0) > + sizeof sockbufsize) < 0) { > err("setsockopt: sndbuf"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > mes("sndbuf"); > } else { > if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, > - sizeof sockbufsize) < 0) > + sizeof sockbufsize) < 0) { > err("setsockopt: rcvbuf"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > mes("rcvbuf"); > } > } > @@ -344,24 +434,36 @@ char **argv; > /* We are the client if transmitting */ > if (options) { > #if defined(BSD42) > - if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) > + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) { > #else /* BSD43 */ > - if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) > + if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) { > #endif > err("setsockopt"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > } > #ifdef TCP_NODELAY > if (nodelay) { > struct protoent *p; > p = getprotobyname("tcp"); > if( p && setsockopt(fd, p->p_proto, TCP_NODELAY, > - &one, sizeof(one)) < 0) > + &one, sizeof(one)) < 0) { > err("setsockopt: nodelay"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > mes("nodelay"); > } > #endif > - if(connect(fd, sinhim_p, sizeof(sinhim) ) < 0) > + if(connect(fd, sinhim_p, sizeof(sinhim) ) < 0) { > err("connect"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > mes("connect"); > } else { > /* otherwise, we are the server and > @@ -374,21 +476,41 @@ char **argv; > #endif > if(options) { > #if defined(BSD42) > - if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) > + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) { > #else /* BSD43 */ > - if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) > + if( setsockopt(fd, SOL_SOCKET, options, &one, > sizeof(one)) < 0) { > #endif > err("setsockopt"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > } > fromlen = sizeof(frominet); > domain = AF_INET; > - if((fd=accept(fd, frominet_p, &fromlen) ) < 0) > + int fd_list = fd; > + if((fd=accept(fd_list, frominet_p, &fromlen) ) < 0) { > err("accept"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > + > + if(close(fd_list) < 0) { > + err("close"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > + > { struct sockaddr_in peer; > socklen_t peerlen = sizeof(peer); > if (getpeername(fd, (struct sockaddr *) &peer, > &peerlen) < 0) { > err("getpeername"); > +#ifdef __rtems__ > + return 1; > +#endif > } > fprintf(stderr,"ttcp-r: accept from %s\n", > inet_ntoa(peer.sin_addr)); > @@ -438,7 +560,12 @@ char **argv; > nbytes += cnt; > } > } > - if(errno) err("IO"); > + if(errno) { > + err("IO"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > (void)read_timer(stats,sizeof(stats)); > if(udp&&trans) { > (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > @@ -446,6 +573,14 @@ char **argv; > (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > (void)Nwrite( fd, buf, 4 ); /* rcvr end */ > } > + > + if(close(fd) < 0) { > + err("close"); > +#ifdef __rtems__ > + return 1; > +#endif > + } > + > if( cput <= 0.0 ) cput = 0.001; > if( realt <= 0.0 ) realt = 0.001; > fprintf(stdout, > @@ -471,22 +606,41 @@ char **argv; > trans?"-t":"-r", > buf); > } > + free(alloc_buf); > +#ifdef __rtems__ > + return 0; > +#else > exit(0); > +#endif > > usage: > fprintf(stderr,Usage); > + free(alloc_buf); > +#ifdef __rtems__ > + return 1; > +#else > exit(1); > - return 0; > + return 1; > +#endif > } > > void > -err(s) > +err(s) > char *s; > { > fprintf(stderr,"ttcp%s: ", trans?"-t":"-r"); > perror(s); > fprintf(stderr,"errno=%d\n",errno); > + free(alloc_buf); > + if (fd != 0) > + { > + close(fd); > + } > +#ifdef __rtems__ > + return; > +#else > exit(1); > +#endif > } > > void > @@ -540,7 +694,9 @@ double b; > static struct timeval time0; /* Time at which timing started */ > static struct rusage ru0; /* Resource utilization at the start */ > > +#ifndef __rtems__ > static void prusage(); > +#endif > static void tvadd(); > static void tvsub(); > static void psecs(); > @@ -601,7 +757,11 @@ int len; > > getrusage(RUSAGE_SELF, &ru1); > gettimeofday(&timedol, (struct timezone *)0); > +#ifndef __rtems__ > prusage(&ru0, &ru1, &timedol, &time0, line); > +#else > + line[0] = '\0'; > +#endif > (void)strncpy( str, line, len ); > > /* Get real time */ > @@ -617,6 +777,7 @@ int len; > return( cput ); > } > > +#ifndef __rtems__ > static void > prusage(r0, r1, e, b, outp) > register struct rusage *r0, *r1; > @@ -731,6 +892,7 @@ prusage(r0, r1, e, b, outp) > } > *outp = '\0'; > } > +#endif > > static void > tvadd(tsum, t0, t1) > -- > 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