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)