[PATCH rtems-libbsd v2 3/4] rtemsbsd: Made TTCP command build for RTEMS
Gedare Bloom
gedare at rtems.org
Tue Jun 15 15:24:54 UTC 2021
On Fri, Jun 11, 2021 at 11:19 AM Stephen Clark
<stephen.clark at 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 at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list