Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions components/drivers/ipc/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* 2023-06-28 shell return POLLHUP when writer closed its channel on poll()
* fix flag test on pipe_fops_open()
* 2023-12-02 shell Make read pipe operation interruptable.
* 2026-11-02 seteiro pipe ioctl: copy FIONREAD/FIONWRITE via lwp_put_to_user
*/
#include <rthw.h>
#include <rtdevice.h>
Expand All @@ -24,6 +25,9 @@
#include <sys/ioctl.h>
#include <dfs_file.h>
#include <resource_id.h>
#ifdef RT_USING_LWP
#include <lwp_user_mm.h>
#endif

/* check RT_UNAMED_PIPE_NUMBER */

Expand Down Expand Up @@ -190,19 +194,33 @@ static int pipe_fops_ioctl(struct dfs_file *fd, int cmd, void *args)

pipe = (rt_pipe_t *)fd->vnode->data;

if (args == RT_NULL)
if (args == RT_NULL || pipe == RT_NULL || pipe->fifo == RT_NULL)
{
return -EINVAL;
}

switch ((rt_ubase_t)cmd)
{
case FIONREAD:
*((int*)args) = rt_ringbuffer_data_len(pipe->fifo);
break;
case FIONWRITE:
*((int*)args) = rt_ringbuffer_space_len(pipe->fifo);
{
int value = (cmd == FIONREAD)
? (int)rt_ringbuffer_data_len(pipe->fifo)
: (int)rt_ringbuffer_space_len(pipe->fifo);
#ifdef RT_USING_LWP
if (!lwp_user_accessable(args, sizeof(value)))
{
return -EFAULT;
}
if (lwp_put_to_user(args, &value, sizeof(value)) != sizeof(value))
{
return -EFAULT;
}
#else
*(int *)args = value;
#endif
break;
}
default:
ret = -EINVAL;
break;
Expand Down
Loading