You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/01/28 09:18:59 UTC

[incubator-nuttx-apps] 02/03: netcat: Rewrite the i/o loop

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git

commit eb996e5650cd697161cbbcdb35bc0e95012d824c
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Thu Jan 28 09:57:06 2021 +0900

    netcat: Rewrite the i/o loop
    
    * Stop echoing back the input.
      It isn't the responsibility of this app, IMO.
    
    * Allow non-text data
    
    * Error checks and cleanups
---
 netutils/netcat/netcat_main.c | 149 +++++++++++++++++++++++++-----------------
 1 file changed, 89 insertions(+), 60 deletions(-)

diff --git a/netutils/netcat/netcat_main.c b/netutils/netcat/netcat_main.c
index 116b2e8..797db2f 100644
--- a/netutils/netcat/netcat_main.c
+++ b/netutils/netcat/netcat_main.c
@@ -24,8 +24,9 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#include <stdio.h>
 
+#include <fcntl.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
@@ -45,12 +46,44 @@
  * Public Functions
  ****************************************************************************/
 
+int do_io(int infd, int outfd)
+{
+  size_t capacity = 256;
+  char buf[capacity];
+
+  while (true)
+    {
+      ssize_t avail = read(infd, buf, capacity);
+      if (avail == 0)
+        {
+          break;
+        }
+
+      if (avail == -1)
+        {
+          perror("do_io: read error");
+          return 5;
+        }
+
+      ssize_t written = write(outfd, buf, avail);
+      if (written == -1)
+        {
+          perror("do_io: write error");
+          return 6;
+        }
+    }
+
+  return EXIT_SUCCESS;
+}
+
 int netcat_server(int argc, char * argv[])
 {
-  FILE * fout = stdout;
+  int id = -1;
+  int outfd = STDOUT_FILENO;
   struct sockaddr_in server;
   struct sockaddr_in client;
   int port = NETCAT_PORT;
+  int result = EXIT_SUCCESS;
 
   if ((1 < argc) && (0 == strcmp("-l", argv[1])))
     {
@@ -61,21 +94,23 @@ int netcat_server(int argc, char * argv[])
 
       if (3 < argc)
         {
-          fout = fopen(argv[3], "w");
-          if (0 > fout)
+          outfd = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0777);
+          if (outfd == -1)
             {
               perror("error: io: Failed to create file");
-              return 1;
+              outfd = STDOUT_FILENO;
+              result = 1;
+              goto out;
             }
         }
     }
 
-  int id;
   id = socket(AF_INET , SOCK_STREAM , 0);
   if (0 > id)
     {
       perror("error: net: Failed to create socket");
-      return 2;
+      result = 2;
+      goto out;
     }
 
   server.sin_family = AF_INET;
@@ -84,49 +119,57 @@ int netcat_server(int argc, char * argv[])
   if (0 > bind(id, (struct sockaddr *)&server , sizeof(server)))
     {
       perror("error: net: Failed to bind");
-      return 3;
+      result = 3;
+      goto out;
     }
 
   fprintf(stderr, "log: net: listening on :%d\n", port);
-  listen(id , 3);
-  int capacity = 256;
-  char buf[capacity];
+  if (listen(id , 3) == -1)
+    {
+      perror("error: net: Failed to listen");
+      result = 7;
+      goto out;
+    }
+
   socklen_t addrlen;
   int conn;
-  while ((conn = accept(id, (struct sockaddr *)&client, &addrlen)))
+  while ((conn = accept(id, (struct sockaddr *)&client, &addrlen)) != -1)
     {
-      int avail = 1;
-      while (0 < avail)
+      result = do_io(conn, outfd);
+      if (result != 0)
         {
-          avail = recv(conn, buf, capacity, 0);
-          fwrite(buf, avail, 1, fout);
-          int status = fflush(fout);
-          if (0 != status)
-            {
-              perror("error: io: Failed to flush");
-            }
+          break;
         }
     }
 
   if (0 > conn)
     {
       perror("accept failed");
-      return 4;
+      result = 4;
+      goto out;
     }
 
-  if (stdout != fout)
+out:
+  if (id != -1)
     {
-      fclose(fout);
+      close(id);
     }
 
-  return EXIT_SUCCESS;
+  if (outfd != STDOUT_FILENO)
+    {
+      close(outfd);
+    }
+
+  return result;
 }
 
 int netcat_client(int argc, char * argv[])
 {
-  FILE *fin = stdin;
+  int id = -1;
+  int infd = STDIN_FILENO;
   char *host = "127.0.0.1";
   int port = NETCAT_PORT;
+  int result = EXIT_SUCCESS;
 
   if (argc > 1)
     {
@@ -140,20 +183,22 @@ int netcat_client(int argc, char * argv[])
 
   if (argc > 3)
     {
-      fin = fopen(argv[3], "r");
-      if (0 > fin)
+      infd = open(argv[3], O_RDONLY);
+      if (infd == -1)
         {
-          perror("error: io: Failed to create file");
-          return 1;
+          perror("error: io: Failed to open file");
+          infd = STDIN_FILENO;
+          result = 1;
+          goto out;
         }
     }
 
-  int id;
   id = socket(AF_INET , SOCK_STREAM , 0);
   if (0 > id)
     {
       perror("error: net: Failed to create socket");
-      return 2;
+      result = 2;
+      goto out;
     }
 
   struct sockaddr_in server;
@@ -162,47 +207,31 @@ int netcat_client(int argc, char * argv[])
   if (1 != inet_pton(AF_INET, host, &server.sin_addr))
     {
       perror("error: net: Invalid host");
-      return 3;
+      result = 3;
+      goto out;
     }
 
   if (connect(id, (struct sockaddr *) &server, sizeof(server)) < 0)
     {
       perror("error: net: Failed to connect");
-      return 4;
+      result = 4;
+      goto out;
     }
 
-  int capacity = 256;
-  char buf[capacity];
-  int avail;
-  while (true)
-    {
-      avail = -1;
-      if (fgets(buf, capacity, fin))
-        {
-          avail = strnlen(buf, capacity);
-        }
-
-      if (avail < 0)
-        {
-          exit(EXIT_SUCCESS);
-        }
+  result = do_io(infd, id);
 
-      buf[avail] = 0;
-      avail = write(id, buf, avail);
-      printf("%s", buf);
-      if (avail < 0)
-        {
-          perror("error: net: writing to socket");
-          exit(1);
-        }
+out:
+  if (id != -1)
+    {
+      close(id);
     }
 
-  if (stdout != fin)
+  if (infd != STDIN_FILENO)
     {
-      fclose(fin);
+      close(infd);
     }
 
-  return EXIT_SUCCESS;
+  return result;
 }
 
 /****************************************************************************