From b8c060260c864864c4f91765447d54949a6f6c46 Mon Sep 17 00:00:00 2001 From: Alexander Lunev Date: Tue, 18 Jan 2022 18:40:32 +0300 Subject: [PATCH] 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 9df86947f..6a3efc806 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 2cdeecb3f..5b51c39c2 100644 --- a/netutils/ftpc/ftpc_putfile.c +++ b/netutils/ftpc/ftpc_putfile.c @@ -25,6 +25,7 @@ #include "ftpc_config.h" #include +#include #include #include #include @@ -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);