1
0
Fork 0
forked from nuttx/nuttx-update

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 <wangyingdong@xiaomi.com>
This commit is contained in:
wangyingdong 2023-06-29 11:35:25 +08:00 committed by Xiang Xiao
parent 8cee6f0cc8
commit 8f6f601ec1
4 changed files with 76 additions and 22 deletions

View file

@ -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 */
{

View file

@ -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
****************************************************************************/

View file

@ -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

View file

@ -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;
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,7 +360,10 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* the next packet.
*/
if (conn->pktlen <= 0)
{
ret = local_sync(&conn->lc_infile);
if (ret < 0)
{
nerr("ERROR: Failed to get packet length: %d\n", ret);
@ -358,12 +375,13 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
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)