diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c index 48bee433b3..ad6d95ac0c 100644 --- a/drivers/serial/pty.c +++ b/drivers/serial/pty.c @@ -504,32 +504,6 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg) ****************************************************************************/ #ifndef CONFIG_DISABLE_POLL -/* REVISIT: There is a file_poll() function, but it does not work in this - * context so the logic is implemented locally as my_file_poll(). - */ - -static my_file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) -{ - FAR struct inode *inode; - int ret = -ENOSYS; - - DEBUGASSERT(filep != NULL && filep->f_inode != NULL); - inode = filep->f_inode; - - /* Is a driver registered? Does it support the poll method? - * If not, return -ENOSYS - */ - - if (inode != NULL && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL) - { - /* Yes, then setup the poll */ - - ret = (int)inode->u.i_ops->poll(filep, fds, setup); - } - - return ret; -} - static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) { @@ -544,16 +518,13 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds, /* REVISIT: If both POLLIN and POLLOUT are set, might the following logic * fail? Could we not get POLLIN on the sink file and POLLOUT on the source * file? - * - * REVISIT: There is a file_poll() function, but it does not work in this - * context so the logic is implemented locally as my_file_poll(). */ /* POLLIN: Data other than high-priority data may be read without blocking. */ if ((fds->events & POLLIN) != 0) { - ret = my_file_poll(dev->pd_src, fds, setup); + ret = file_poll(dev->pd_src, fds, setup); } if (ret >= OK || ret == -ENOTTY) @@ -562,7 +533,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds, if ((fds->events & POLLOUT) != 0) { - ret = my_file_poll(dev->pd_sink, fds, setup); + ret = file_poll(dev->pd_sink, fds, setup); } } diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 924c5c8371..375267e11a 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -243,6 +243,49 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count, * Public Functions ****************************************************************************/ +/**************************************************************************** + * Function: file_poll + * + * Description: + * Low-level poll operation based on struc file. This is used both to (1) + * support detached file, and also (2) by fdesc_poll() to perform all + * normal operations on file descriptors descriptors. + * + * Input Parameters: + * file File structure instance + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * setup - true: Setup up the poll; false: Teardown the poll + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) +{ + FAR struct inode *inode; + int ret = -ENOSYS; + + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + + /* Is a driver registered? Does it support the poll method? + * If not, return -ENOSYS + */ + + if (inode != NULL && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL) + { + /* Yes, it does... Setup the poll */ + + ret = (int)inode->u.i_ops->poll(filep, fds, setup); + } + + return ret; +} +#endif + /**************************************************************************** * Function: fdesc_poll * @@ -265,8 +308,6 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count, int fdesc_poll(int fd, FAR struct pollfd *fds, bool setup) { FAR struct file *filep; - FAR struct inode *inode; - int ret = -ENOSYS; /* Get the file pointer corresponding to this file descriptor */ @@ -275,22 +316,14 @@ int fdesc_poll(int fd, FAR struct pollfd *fds, bool setup) { /* The errno value has already been set */ - return -get_errno(); + int errorcode = get_errno(); + DEBUGASSERT(errcode > 0); + return -errcode; } - /* Is a driver registered? Does it support the poll method? - * If not, return -ENOSYS - */ + /* Let file_poll() do the rest */ - inode = filep->f_inode; - if (inode && inode->u.i_ops && inode->u.i_ops->poll) - { - /* Yes, then setup the poll */ - - ret = (int)inode->u.i_ops->poll(filep, fds, setup); - } - - return ret; + return file_poll(filep, fds, setup); } #endif diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index b9952a4eb8..5b6cfdc31e 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -929,6 +929,29 @@ int file_ioctl(FAR struct file *filep, int req, unsigned long arg); int file_vfcntl(FAR struct file *filep, int cmd, va_list ap); #endif +/**************************************************************************** + * Function: file_poll + * + * Description: + * Low-level poll operation based on struc file. This is used both to (1) + * support detached file, and also (2) by fdesc_poll() to perform all + * normal operations on file descriptors descriptors. + * + * Input Parameters: + * file File structure instance + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * setup - true: Setup up the poll; false: Teardown the poll + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +#if CONFIG_NFILE_DESCRIPTORS > 0 +int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); +#endif + /**************************************************************************** * Function: fdesc_poll *