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 2022/01/20 06:16:08 UTC

[incubator-nuttx-apps] branch master updated: netutils/ftpc: implemented FTPC_OVER_SENDFILE option. This option enables using sendfile() in ftpc binary transfer mode of PUT operation. If the option is enabled but ASCII transfer mode is activated, ftpc falls back to the combination of read() and write(). Using sendfile() provides a higher performance compared to the combination of read() and write().

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


The following commit(s) were added to refs/heads/master by this push:
     new b8c0602  netutils/ftpc: implemented FTPC_OVER_SENDFILE option. This option enables using sendfile() in ftpc binary transfer mode of PUT operation. If the option is enabled but ASCII transfer mode is activated, ftpc falls back to the combination of read() and write(). Using sendfile() provides a higher performance compared to the combination of read() and write().
b8c0602 is described below

commit b8c060260c864864c4f91765447d54949a6f6c46
Author: Alexander Lunev <al...@mail.ru>
AuthorDate: Tue Jan 18 18:40:32 2022 +0300

    netutils/ftpc: implemented FTPC_OVER_SENDFILE option.
    This option enables using sendfile() in ftpc binary transfer mode of PUT operation.
    If the option is enabled but ASCII transfer mode is activated,
    ftpc falls back to the combination of read() and write().
    Using sendfile() provides a higher performance compared to
    the combination of read() and write().
    
    Also this option is useful for testing / debugging tcp_sendfile()
    functionality of NuttX TCP/IP stack.
---
 netutils/ftpc/Kconfig        | 11 +++++++
 netutils/ftpc/ftpc_putfile.c | 69 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/netutils/ftpc/Kconfig b/netutils/ftpc/Kconfig
index 9df8694..6a3efc8 100644
--- a/netutils/ftpc/Kconfig
+++ b/netutils/ftpc/Kconfig
@@ -50,4 +50,15 @@ config FTPC_DISABLE_EPSV
 		if you need to use PASV instead, use this option to disable EPSV and
 		fallback to using PASV.
 
+config FTPC_OVER_SENDFILE
+	bool "Use sendfile() in ftpc binary transfer mode of PUT operation"
+	default y
+	depends on NET_SENDFILE
+	---help---
+		This option enables using sendfile() in ftpc binary transfer mode of PUT
+		operation. If the option is enabled but ASCII transfer mode is activated,
+		ftpc falls back to the combination of read() and write().
+		Using sendfile() provides a higher performance compared
+		to the combination of read() and write().
+
 endif
diff --git a/netutils/ftpc/ftpc_putfile.c b/netutils/ftpc/ftpc_putfile.c
index 2cdeecb..5b51c39 100644
--- a/netutils/ftpc/ftpc_putfile.c
+++ b/netutils/ftpc/ftpc_putfile.c
@@ -25,6 +25,7 @@
 #include "ftpc_config.h"
 
 #include <sys/stat.h>
+#include <sys/sendfile.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
@@ -65,11 +66,60 @@
  *
  ****************************************************************************/
 
+#ifdef CONFIG_FTPC_OVER_SENDFILE
 static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
-                           FAR FILE *linstream, FILE *routstream)
+                           FAR FILE *linstream)
+{
+  struct stat stat_buf;
+  off_t offset = session->offset;
+  ssize_t result;
+  ssize_t len;
+  int linfd = fileno(linstream);
+
+  if (linfd == -1 || fstat(linfd, &stat_buf) == -1)
+    {
+      ftpc_xfrabort(session, NULL);
+      return ERROR;
+    }
+
+  /* Loop until the entire file is sent */
+
+  len = stat_buf.st_size - offset;
+
+  while (len > 0)
+    {
+      result = sendfile(session->data.sd, linfd, &offset, len);
+
+      if (result == -1 && errno == EAGAIN)
+        {
+          continue;
+        }
+      else if (result == -1)
+        {
+          ftpc_xfrabort(session, NULL);
+          return ERROR;
+        }
+
+      len -= result;
+
+      /* Increment the size of the file sent */
+
+      session->size += result;
+    }
+
+  /* Return success */
+
+  return OK;
+}
+
+#else
+
+static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
+                           FAR FILE *linstream)
 {
   ssize_t nread;
   ssize_t nwritten;
+  FILE *routstream = session->data.outstream;
 
   /* Loop until the entire file is sent */
 
@@ -111,6 +161,7 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
       session->size += nread;
     }
 }
+#endif
 
 /****************************************************************************
  * Name: ftpc_sendtext
@@ -121,10 +172,11 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
  ****************************************************************************/
 
 static int ftpc_sendtext(FAR struct ftpc_session_s *session,
-                         FAR FILE *linstream, FAR FILE *routstream)
+                         FAR FILE *linstream)
 {
   int ch;
   int ret = OK;
+  FILE *routstream = session->data.outstream;
 
   /* Write characters one at a time. */
 
@@ -174,7 +226,6 @@ static int ftpc_sendtext(FAR struct ftpc_session_s *session,
 static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
                          FILE *stream, uint8_t how, uint8_t xfrmode)
 {
-  long offset = session->offset;
 #ifdef CONFIG_DEBUG_FEATURES
   FAR char *rname;
   FAR char *str;
@@ -182,8 +233,6 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
 #endif
   int ret;
 
-  session->offset = 0;
-
   /* Were we asked to store a file uniquely?  Does the host support the STOU
    * command?
    */
@@ -212,10 +261,10 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
    * allow REST immediately before STOR for binary files.
    */
 
-  if (offset > 0)
+  if (session->offset > 0)
     {
-      ret = ftpc_cmd(session, "REST %ld", offset);
-      session->size = offset;
+      ret = ftpc_cmd(session, "REST %ld", session->offset);
+      session->size = session->offset;
     }
 
   /* Send the file using STOR, STOU, or APPE:
@@ -331,11 +380,11 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
 
   if (xfrmode == FTPC_XFRMODE_ASCII)
     {
-      ret = ftpc_sendtext(session, stream, session->data.outstream);
+      ret = ftpc_sendtext(session, stream);
     }
   else
     {
-      ret = ftpc_sendbinary(session, stream, session->data.outstream);
+      ret = ftpc_sendbinary(session, stream);
     }
 
   ftpc_sockflush(&session->data);