You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/02/04 22:07:40 UTC

[incubator-nuttx-apps] 01/06: Ensure telnet object get freed before the abnormal exit

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

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

commit 65fcf27f94471492751a9367d866c103b3537221
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Feb 4 02:05:22 2020 +0800

    Ensure telnet object get freed before the abnormal exit
    
    Change-Id: I5335c5f6c86965b321ebf68482818b05f11caf2a
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 system/telnet/Make.defs       |  2 +-
 system/telnet/telnet_chatd.c  | 33 +++++++++++++++++++++++--------
 system/telnet/telnet_client.c | 46 +++++++++++++++++++++++--------------------
 3 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/system/telnet/Make.defs b/system/telnet/Make.defs
index 12fe718..0e0954a 100644
--- a/system/telnet/Make.defs
+++ b/system/telnet/Make.defs
@@ -1,5 +1,5 @@
 ############################################################################
-# apps/system/usbmsc/Make.defs
+# apps/system/telnet/Make.defs
 # Adds selected applications to apps/ build
 #
 #   Copyright (C) 2016 Gregory Nutt. All rights reserved.
diff --git a/system/telnet/telnet_chatd.c b/system/telnet/telnet_chatd.c
index 6d51ead..356aac8 100644
--- a/system/telnet/telnet_chatd.c
+++ b/system/telnet/telnet_chatd.c
@@ -107,6 +107,23 @@ static struct user_s g_users[MAX_USERS];
  * Private Functions
  ****************************************************************************/
 
+static void cleanup_exit(void)
+{
+  int i;
+
+  for (i = 0; i != MAX_USERS; ++i)
+    {
+      if (g_users[i].sock != -1)
+        {
+          close(g_users[i].sock);
+          free(g_users[i].name);
+          telnet_free(g_users[i].telnet);
+      }
+    }
+
+  exit(1);
+}
+
 static void linebuffer_push(char *buffer, size_t size, int *linepos,
                             char ch, void (*cb) (const char *line, int overflow,
                                                  void *ud), void *ud)
@@ -180,7 +197,7 @@ static void _send(int sock, const char *buffer, unsigned int size)
           if (errno != EINTR && errno != ECONNRESET)
             {
               fprintf(stderr, "send() failed: %d\n", errno);
-              exit(1);
+              cleanup_exit();
             }
           else
             {
@@ -190,7 +207,7 @@ static void _send(int sock, const char *buffer, unsigned int size)
       else if (ret == 0)
         {
           fprintf(stderr, "send() unexpectedly returned 0\n");
-          exit(1);
+          cleanup_exit();
         }
 
       /* Update pointer and size to see if we've got more to send */
@@ -246,6 +263,7 @@ static void _online(const char *line, int overflow, void *ud)
       _message(user->name, "** HAS QUIT **");
       free(user->name);
       user->name = 0;
+      telnet_free(user->telnet);
       return;
     }
 
@@ -258,7 +276,7 @@ static void _input(struct user_s *user, const char *buffer, unsigned int size)
 {
   unsigned int i;
 
-  for (i = 0; i != size; ++i)
+  for (i = 0; user->sock != -1 && i != size; ++i)
     {
       linebuffer_push(user->linebuf, sizeof(user->linebuf), &user->linepos,
                       (char)buffer[i], _online, user);
@@ -420,7 +438,7 @@ int main(int argc, FAR char *argv[])
       if (ret == -1 && errno != EINTR)
         {
           fprintf(stderr, "poll() failed: %d\n", errno);
-          return 1;
+          cleanup_exit();
         }
 
       /* New connection */
@@ -434,7 +452,7 @@ int main(int argc, FAR char *argv[])
                            &addrlen)) == -1)
             {
               fprintf(stderr, "accept() failed: %d\n", errno);
-              return 1;
+              cleanup_exit();
             }
 
           printf("Connection received.\n");
@@ -488,6 +506,7 @@ int main(int argc, FAR char *argv[])
                 {
                   printf("Connection closed.\n");
                   close(g_users[i].sock);
+                  g_users[i].sock = -1;
                   if (g_users[i].name != 0)
                     {
                       _message(g_users[i].name, "** HAS DISCONNECTED **");
@@ -496,13 +515,11 @@ int main(int argc, FAR char *argv[])
                     }
 
                   telnet_free(g_users[i].telnet);
-                  g_users[i].sock = -1;
-                  break;
                 }
               else if (errno != EINTR)
                 {
                   fprintf(stderr, "recv(client) failed: %d\n", errno);
-                  exit(1);
+                  cleanup_exit();
                 }
             }
         }
diff --git a/system/telnet/telnet_client.c b/system/telnet/telnet_client.c
index 6f1d354..6b89ae9 100644
--- a/system/telnet/telnet_client.c
+++ b/system/telnet/telnet_client.c
@@ -156,14 +156,17 @@ static void telnet_ev_send(int sock, const char *buffer, size_t size)
 
   while (size > 0)
     {
-      if ((ret = send(sock, buffer, size, 0)) == -1)
+      if ((ret = send(sock, buffer, size, 0)) <= 0)
         {
-          fprintf(stderr, "send() failed: %d\n", errno);
-          exit(1);
-        }
-      else if (ret == 0)
-        {
-          fprintf(stderr, "send() unexpectedly returned 0\n");
+          if (ret < 0)
+            {
+              fprintf(stderr, "send() failed: %d\n", errno);
+            }
+          else
+            {
+              fprintf(stderr, "send() unexpectedly returned 0\n");
+            }
+          telnet_free(g_telnet);
           exit(1);
         }
 
@@ -245,6 +248,7 @@ static void _event_handler(struct telnet_s *telnet,
 
     case TELNET_EV_ERROR:
       fprintf(stderr, "ERROR: %s\n", ev->error.msg);
+      telnet_free(g_telnet);
       exit(1);
 
     default:
@@ -264,7 +268,7 @@ static void show_usage(const char *progname, int exitcode)
   fprintf(stderr, "\t\tIPv6 form: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx\n");
   fprintf(stderr, "\t<port> is the (optional) listening port of the Telnet server.\n");
   fprintf(stderr, "\t\tDefault: %u\n", DEFAULT_PORT);
-  exit(exitcode)  ;
+  exit(exitcode);
 }
 
 /****************************************************************************
@@ -414,14 +418,14 @@ int main(int argc, FAR char *argv[])
             {
               send_local_input(buffer, ret);
             }
-          else if (ret == 0)
-            {
-              break;
-            }
           else
             {
-              fprintf(stderr, "recv(server) failed: %d\n", errno);
-              exit(1);
+              if (ret < 0)
+                {
+                  fprintf(stderr, "recv(server) failed: %d\n", errno);
+                  ret = 1;
+                }
+              break;
             }
         }
 
@@ -433,14 +437,14 @@ int main(int argc, FAR char *argv[])
             {
               telnet_recv(g_telnet, buffer, ret);
             }
-          else if (ret == 0)
-            {
-              break;
-            }
           else
             {
-              fprintf(stderr, "recv(client) failed: %d\n", errno);
-              exit(1);
+              if (ret < 0)
+                {
+                  fprintf(stderr, "recv(client) failed: %d\n", errno);
+                  ret = 1;
+                }
+              break;
             }
         }
     }
@@ -449,5 +453,5 @@ int main(int argc, FAR char *argv[])
 
   telnet_free(g_telnet);
   close(sock);
-  return 0;
+  return ret;
 }