You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/07/16 16:33:19 UTC

[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #4116: net: Add file_socket function

xiaoxiang781216 commented on a change in pull request #4116:
URL: https://github.com/apache/incubator-nuttx/pull/4116#discussion_r671385494



##########
File path: net/socket/net_sendfile.c
##########
@@ -130,8 +130,8 @@ ssize_t psock_sendfile(FAR struct socket *psock, FAR struct file *infile,
   if (psock == NULL || psock->s_conn == NULL)
     {
       nerr("ERROR: Invalid socket\n");
-      _SO_SETERRNO(psock, EBADF);
-      return ERROR;
+      psock->s_error = EBADF;

Review comment:
       Done.

##########
File path: fs/vfs/fs_sendfile.c
##########
@@ -26,20 +26,255 @@
 
 #include <sys/sendfile.h>
 #include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
 #include <errno.h>
-#include <assert.h>
 
-#include <nuttx/sched.h>
+#include <nuttx/kmalloc.h>
 #include <nuttx/net/net.h>
 
-#ifdef CONFIG_NET_SENDFILE
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static ssize_t copyfile(FAR struct file *outfile, FAR struct file *infile,
+                        off_t *offset, size_t count)
+{
+  FAR uint8_t *iobuffer;
+  FAR uint8_t *wrbuffer;
+  off_t startpos = 0;
+  ssize_t nbytesread;
+  ssize_t nbyteswritten;
+  size_t  ntransferred;
+  bool endxfr;
+
+  /* Get the current file position. */
+
+  if (offset)
+    {
+      off_t newpos;
+
+      /* Use lseek to get the current file position */
+
+      startpos = file_seek(infile, 0, SEEK_CUR);
+      if (startpos < 0)
+        {
+          return startpos;
+        }
+
+      /* Use lseek again to set the new file position */
+
+      newpos = file_seek(infile, *offset, SEEK_SET);
+      if (newpos < 0)
+        {
+          return newpos;
+        }
+    }
+
+  /* Allocate an I/O buffer */
+
+  iobuffer = kmm_malloc(CONFIG_SENDFILE_BUFSIZE);
+  if (!iobuffer)
+    {
+      return -ENOMEM;
+    }
+
+  /* Now transfer 'count' bytes from the infile to the outfile */
+
+  for (ntransferred = 0, endxfr = false; ntransferred < count && !endxfr; )
+    {
+      /* Loop until the read side of the transfer comes to some conclusion */
+
+      do
+        {
+          /* Read a buffer of data from the infile */
+
+          nbytesread = count - ntransferred;
+          if (nbytesread > CONFIG_SENDFILE_BUFSIZE)
+            {
+              nbytesread = CONFIG_SENDFILE_BUFSIZE;
+            }
+
+          nbytesread = file_read(infile, iobuffer, nbytesread);
+
+          /* Check for end of file */
+
+          if (nbytesread == 0)
+            {
+              /* End of file.  Break out and return current number of bytes
+               * transferred.
+               */
+
+              endxfr = true;
+              break;
+            }
+
+          /* Check for a read ERROR.  EINTR is a special case.  This function
+           * should break out and return an error if EINTR is returned and
+           * no data has been transferred.  But what should it do if some
+           * data has been transferred?  I suppose just continue?
+           */
+
+          else if (nbytesread < 0)
+            {
+              /* EINTR is not an error (but will still stop the copy) */
+
+              if (nbytesread != -EINTR || ntransferred == 0)
+                {
+                  /* Read error.  Break out and return the error condition. */
+
+                  ntransferred = nbytesread;
+                  endxfr       = true;
+                  break;
+                }
+            }
+        }
+      while (nbytesread < 0);
+
+      /* Was anything read? */
+
+      if (!endxfr)
+        {
+          /* Yes.. Loop until the read side of the transfer comes to some
+           * conclusion.
+           */
+
+          wrbuffer = iobuffer;
+          do
+            {
+              /* Write the buffer of data to the outfile */
+
+              nbyteswritten = file_write(outfile, wrbuffer, nbytesread);
+
+              /* Check for a complete (or parial) write.  write() should not
+               * return zero.
+               */
+
+              if (nbyteswritten >= 0)
+                {
+                  /* Advance the buffer pointer and decrement the number of
+                   * bytes remaining in the iobuffer.  Typically, nbytesread
+                   * will now be zero.
+                   */
+
+                  wrbuffer     += nbyteswritten;
+                  nbytesread   -= nbyteswritten;
+
+                  /* Increment the total number of bytes successfully
+                   * transferred.
+                   */
+
+                  ntransferred += nbyteswritten;
+                }
+
+              /* Otherwise an error occurred */
+
+              else
+                {
+                  /* Check for a write ERROR.  EINTR is a special case.  This
+                   * function should break out and return an error if EINTR
+                   * is returned and no data has been transferred.  But what
+                   * should it do if some data has been transferred?  I
+                   * suppose just continue?
+                   */
+
+                  if (nbyteswritten != -EINTR || ntransferred == 0)
+                    {
+                      /* Write error.  Break out and return the error
+                       * condition.
+                       */
+
+                      ntransferred = nbyteswritten;
+                      endxfr       = true;
+                      break;
+                    }
+                }
+            }
+          while (nbytesread > 0);
+        }
+    }
+
+  /* Release the I/O buffer */
+
+  kmm_free(iobuffer);
+
+  /* Return the current file position */
+
+  if (offset)
+    {
+      /* Use lseek to get the current file position */

Review comment:
       Done.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org