[PATCH rtems-libbsd v2 3/4] rtemsbsd: Made TTCP command build for RTEMS
Stephen Clark
stephen.clark at oarcorp.com
Fri Jun 11 17:00:32 UTC 2021
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;
/* 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
}
+
+#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
+ }
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
More information about the devel
mailing list