[PATCH v1 3/4] rtemsbsd: Made TTCP command build for RTEMS

Stephen Clark stephen.clark at oarcorp.com
Tue Jun 8 15:55:28 UTC 2021


Updated ttcp.c to build for RTEMS 6. 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/ttcp.c                          | 266 ++++++++++++++----
 5 files changed, 259 insertions(+), 52 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/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