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 2023/08/15 15:58:52 UTC

[nuttx] branch master updated: net/local:Add peek support for pipe and MSG_PEEK support for local socket

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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f6f601ec1 net/local:Add peek support for pipe and MSG_PEEK support for local socket
8f6f601ec1 is described below

commit 8f6f601ec13f9c92c41b8d5d8749acb50f659830
Author: wangyingdong <wa...@xiaomi.com>
AuthorDate: Thu Jun 29 11:35:25 2023 +0800

    net/local:Add peek support for pipe and MSG_PEEK support for local socket
    
    fifo peek example:
    struct pipe_peek_s peek_buf;
    peek_buf.len = len;
    peek_buf.data = buf;
    ret = file_ioctl(filep, PIPEIOC_PEEK,(unsigned long)((uintptr_t)&peek_buf));
    
    Signed-off-by: wangyingdong <wa...@xiaomi.com>
---
 drivers/pipes/pipe_common.c | 10 +++++++
 include/nuttx/fs/ioctl.h    | 11 +++++++
 net/local/local.h           |  4 +++
 net/local/local_recvmsg.c   | 73 +++++++++++++++++++++++++++++++--------------
 4 files changed, 76 insertions(+), 22 deletions(-)

diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c
index daf3eb3e7a..576f4b79fd 100644
--- a/drivers/pipes/pipe_common.c
+++ b/drivers/pipes/pipe_common.c
@@ -838,6 +838,16 @@ int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         }
         break;
 
+      case PIPEIOC_PEEK:
+        {
+          FAR struct pipe_peek_s *peek = (FAR struct pipe_peek_s *)arg;
+
+          DEBUGASSERT(peek && peek->buf);
+
+          ret = circbuf_peek(&dev->d_buffer, peek->buf, peek->size);
+        }
+        break;
+
       case FIONWRITE:  /* Number of bytes waiting in send queue */
       case FIONREAD:   /* Number of bytes available for reading */
         {
diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h
index 3fed64f823..1ccf37cf23 100644
--- a/include/nuttx/fs/ioctl.h
+++ b/include/nuttx/fs/ioctl.h
@@ -26,6 +26,7 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <sys/types.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -447,6 +448,10 @@
                                                *     threshold.
                                                * OUT: None */
 
+#define PIPEIOC_PEEK        _PIPEIOC(0x0004)  /* Pipe peek interface
+                                               * IN: pipe_peek_s
+                                               * OUT: Length of data */
+
 /* RTC driver ioctl definitions *********************************************/
 
 /* (see nuttx/include/rtc.h */
@@ -661,6 +666,12 @@
  * Public Type Definitions
  ****************************************************************************/
 
+struct pipe_peek_s
+{
+  FAR void *buf;
+  size_t size;
+};
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
diff --git a/net/local/local.h b/net/local/local.h
index 83f70c4320..cb9c00d5b8 100644
--- a/net/local/local.h
+++ b/net/local/local.h
@@ -122,6 +122,10 @@ struct local_conn_s
   char lc_path[UNIX_PATH_MAX];   /* Path assigned by bind() */
   int32_t lc_instance_id;        /* Connection instance ID for stream
                                   * server<->client connection pair */
+#ifdef CONFIG_NET_LOCAL_DGRAM
+  uint16_t pktlen;                 /* Read-ahead packet length */
+#endif /* CONFIG_NET_LOCAL_DGRAM */
+
   FAR struct local_conn_s *
                         lc_peer; /* Peer connection instance */
 #ifdef CONFIG_NET_LOCAL_SCM
diff --git a/net/local/local_recvmsg.c b/net/local/local_recvmsg.c
index 1f8df8a87a..fb3b3d3e62 100644
--- a/net/local/local_recvmsg.c
+++ b/net/local/local_recvmsg.c
@@ -56,12 +56,27 @@
  ****************************************************************************/
 
 static int psock_fifo_read(FAR struct socket *psock, FAR void *buf,
-                           FAR size_t *readlen, bool once)
+                           FAR size_t *readlen, int flags, bool once)
 {
   FAR struct local_conn_s *conn = psock->s_conn;
   int ret;
 
-  ret = local_fifo_read(&conn->lc_infile, buf, readlen, once);
+  if (flags & MSG_PEEK)
+    {
+      struct pipe_peek_s peek =
+        {
+          buf,
+          *readlen
+        };
+
+      ret = file_ioctl(&conn->lc_infile, PIPEIOC_PEEK,
+                       (unsigned long)((uintptr_t)&peek));
+    }
+  else
+    {
+      ret = local_fifo_read(&conn->lc_infile, buf, readlen, once);
+    }
+
   if (ret < 0)
     {
       /* -ECONNRESET is a special case.  We may or not have received
@@ -245,7 +260,7 @@ psock_stream_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   /* Read the packet */
 
-  ret = psock_fifo_read(psock, buf, &readlen, true);
+  ret = psock_fifo_read(psock, buf, &readlen, flags, true);
   if (ret < 0)
     {
       return ret;
@@ -294,10 +309,9 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                      FAR socklen_t *fromlen)
 {
   FAR struct local_conn_s *conn = psock->s_conn;
-  uint16_t pktlen;
   size_t readlen;
   bool bclose = false;
-  int ret;
+  int ret = 0;
 
   /* We keep packet sizes in a uint16_t, so there is a upper limit to the
    * 'len' that can be supported.
@@ -346,24 +360,28 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
    * the next packet.
    */
 
-  ret = local_sync(&conn->lc_infile);
-  if (ret < 0)
+  if (conn->pktlen <= 0)
     {
-      nerr("ERROR: Failed to get packet length: %d\n", ret);
-      goto errout_with_infd;
-    }
-  else if (ret > UINT16_MAX)
-    {
-      nerr("ERROR: Packet is too big: %d\n", ret);
-      goto errout_with_infd;
-    }
+      ret = local_sync(&conn->lc_infile);
+
+      if (ret < 0)
+        {
+          nerr("ERROR: Failed to get packet length: %d\n", ret);
+          goto errout_with_infd;
+        }
+      else if (ret > UINT16_MAX)
+        {
+          nerr("ERROR: Packet is too big: %d\n", ret);
+          goto errout_with_infd;
+        }
 
-  pktlen = ret;
+      conn->pktlen = ret;
+    }
 
   /* Read the packet */
 
-  readlen = MIN(pktlen, len);
-  ret     = psock_fifo_read(psock, buf, &readlen, false);
+  readlen = MIN(conn->pktlen, len);
+  ret     = psock_fifo_read(psock, buf, &readlen, flags, false);
   if (ret < 0)
     {
       goto errout_with_infd;
@@ -373,20 +391,25 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
    * of the packet to the bit bucket.
    */
 
-  DEBUGASSERT(readlen <= pktlen);
-  if (readlen < pktlen)
+  if (flags & MSG_PEEK)
+    {
+      goto skip_flush;
+    }
+
+  DEBUGASSERT(readlen <= conn->pktlen);
+  if (readlen < conn->pktlen)
     {
       uint8_t bitbucket[32];
       uint16_t remaining;
       size_t tmplen;
 
-      remaining = pktlen - readlen;
+      remaining = conn->pktlen - readlen;
       do
         {
           /* Read 32 bytes into the bit bucket */
 
           tmplen = MIN(remaining, 32);
-          ret     = psock_fifo_read(psock, bitbucket, &tmplen, false);
+          ret = psock_fifo_read(psock, bitbucket, &tmplen, flags, false);
           if (ret < 0)
             {
               goto errout_with_infd;
@@ -402,6 +425,12 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
       while (remaining > 0);
     }
 
+  /* The fifo has been read and the pktlen needs to be cleared */
+
+  conn->pktlen = 0;
+
+skip_flush:
+
   /* Return the address family */
 
   if (from)