vfs/file: add reference counting to prevent accidental close during reading writing...
Signed-off-by: Shoukui Zhang <zhangshoukui@xiaomi.com>
This commit is contained in:
parent
f2fd0bc148
commit
43223124ec
@ -603,6 +603,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
audinfo("AUDIOIOC_UNREGISTERMQ\n");
|
||||
|
||||
fs_putfilep(upper->usermq);
|
||||
upper->usermq = NULL;
|
||||
ret = OK;
|
||||
}
|
||||
|
@ -901,6 +901,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
|
||||
{
|
||||
FAR struct telnet_dev_s *priv;
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Allocate instance data for this driver */
|
||||
@ -931,7 +932,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
|
||||
* instance resided in the daemon's task group`).
|
||||
*/
|
||||
|
||||
ret = sockfd_socket(session->ts_sd, &psock);
|
||||
ret = sockfd_socket(session->ts_sd, &filep, &psock);
|
||||
if (ret != OK)
|
||||
{
|
||||
nerr("ERROR: Failed to convert sd=%d to a socket structure\n",
|
||||
@ -940,6 +941,7 @@ static int telnet_session(FAR struct telnet_session_s *session)
|
||||
}
|
||||
|
||||
ret = psock_dup2(psock, &priv->td_psock);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: psock_dup2 failed: %d\n", ret);
|
||||
|
@ -80,35 +80,40 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp)
|
||||
*/
|
||||
|
||||
aioc = aioc_alloc();
|
||||
if (aioc != NULL)
|
||||
if (aioc == NULL)
|
||||
{
|
||||
/* Initialize the container */
|
||||
ret = -ENOMEM;
|
||||
goto err_putfilep;
|
||||
}
|
||||
|
||||
memset(aioc, 0, sizeof(struct aio_container_s));
|
||||
aioc->aioc_aiocbp = aiocbp;
|
||||
aioc->aioc_filep = filep;
|
||||
aioc->aioc_pid = nxsched_getpid();
|
||||
/* Initialize the container */
|
||||
|
||||
memset(aioc, 0, sizeof(struct aio_container_s));
|
||||
aioc->aioc_aiocbp = aiocbp;
|
||||
aioc->aioc_filep = filep;
|
||||
aioc->aioc_pid = nxsched_getpid();
|
||||
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
DEBUGVERIFY(nxsched_get_param (aioc->aioc_pid, ¶m));
|
||||
aioc->aioc_prio = param.sched_priority;
|
||||
DEBUGVERIFY(nxsched_get_param(aioc->aioc_pid, ¶m));
|
||||
aioc->aioc_prio = param.sched_priority;
|
||||
#endif
|
||||
|
||||
/* Add the container to the pending transfer list. */
|
||||
/* Add the container to the pending transfer list. */
|
||||
|
||||
ret = aio_lock();
|
||||
if (ret < 0)
|
||||
{
|
||||
aioc_free(aioc);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dq_addlast(&aioc->aioc_link, &g_aio_pending);
|
||||
aio_unlock();
|
||||
ret = aio_lock();
|
||||
if (ret < 0)
|
||||
{
|
||||
aioc_free(aioc);
|
||||
goto err_putfilep;
|
||||
}
|
||||
|
||||
dq_addlast(&aioc->aioc_link, &g_aio_pending);
|
||||
aio_unlock();
|
||||
|
||||
return aioc;
|
||||
|
||||
err_putfilep:
|
||||
fs_putfilep(filep);
|
||||
errout:
|
||||
set_errno(-ret);
|
||||
return NULL;
|
||||
@ -148,6 +153,7 @@ FAR struct aiocb *aioc_decant(FAR struct aio_container_s *aioc)
|
||||
*/
|
||||
|
||||
aiocbp = aioc->aioc_aiocbp;
|
||||
fs_putfilep(aioc->aioc_filep);
|
||||
aioc_free(aioc);
|
||||
|
||||
aio_unlock();
|
||||
|
@ -63,7 +63,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct file *files_fget_by_index(FAR struct filelist *list,
|
||||
int l1, int l2)
|
||||
int l1, int l2, FAR bool *new)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
irqstate_t flags;
|
||||
@ -71,9 +71,25 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list,
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
|
||||
filep = &list->fl_files[l1][l2];
|
||||
if (filep->f_inode != NULL)
|
||||
{
|
||||
filep->f_refs++;
|
||||
}
|
||||
else if (new == NULL)
|
||||
{
|
||||
filep = NULL;
|
||||
}
|
||||
else if (filep->f_refs)
|
||||
{
|
||||
filep->f_refs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
filep->f_refs = 2;
|
||||
*new = true;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
|
||||
return filep;
|
||||
}
|
||||
|
||||
@ -180,10 +196,11 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
|
||||
filep = files_fget_by_index(list, i, j);
|
||||
if (filep->f_inode != NULL)
|
||||
filep = files_fget_by_index(list, i, j, NULL);
|
||||
if (filep != NULL)
|
||||
{
|
||||
file_fsync(filep);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,6 +232,7 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
|
||||
int flags)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
FAR struct file *filep1;
|
||||
FAR struct file *filep;
|
||||
#ifdef CONFIG_FDCHECK
|
||||
uint8_t f_tag_fdcheck;
|
||||
@ -222,6 +240,7 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
|
||||
#ifdef CONFIG_FDSAN
|
||||
uint64_t f_tag_fdsan;
|
||||
#endif
|
||||
bool new = false;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
@ -254,12 +273,17 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
|
||||
}
|
||||
}
|
||||
|
||||
filep = files_fget(list, fd2);
|
||||
if (filep == NULL)
|
||||
filep1 = files_fget(list, fd1);
|
||||
if (filep1 == NULL)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
filep = files_fget_by_index(list,
|
||||
fd2 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
|
||||
fd2 % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
|
||||
&new);
|
||||
|
||||
#ifdef CONFIG_FDSAN
|
||||
f_tag_fdsan = filep->f_tag_fdsan;
|
||||
#endif
|
||||
@ -270,9 +294,16 @@ static int nx_dup3_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2,
|
||||
|
||||
/* Perform the dup3 operation */
|
||||
|
||||
ret = file_dup3(files_fget(list, fd1), filep, flags);
|
||||
ret = file_dup3(filep1, filep, flags);
|
||||
fs_putfilep(filep1);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (new)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -482,7 +513,7 @@ int files_countlist(FAR struct filelist *list)
|
||||
FAR struct file *files_fget(FAR struct filelist *list, int fd)
|
||||
{
|
||||
return files_fget_by_index(list, fd / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK,
|
||||
fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK);
|
||||
fd % CONFIG_NFILE_DESCRIPTORS_PER_BLOCK, NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -541,6 +572,7 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
|
||||
filep->f_pos = pos;
|
||||
filep->f_inode = inode;
|
||||
filep->f_priv = priv;
|
||||
filep->f_refs = 1;
|
||||
|
||||
goto found;
|
||||
}
|
||||
@ -607,7 +639,9 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
|
||||
{
|
||||
for (j = 0; j < CONFIG_NFILE_DESCRIPTORS_PER_BLOCK; j++)
|
||||
{
|
||||
FAR struct file *filep2;
|
||||
FAR struct file *filep;
|
||||
bool new = false;
|
||||
|
||||
fd = i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j;
|
||||
#ifdef CONFIG_FDCLONE_STDIO
|
||||
@ -625,8 +659,8 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
|
||||
}
|
||||
#endif
|
||||
|
||||
filep = files_fget_by_index(plist, i, j);
|
||||
if (filep->f_inode == NULL)
|
||||
filep = files_fget_by_index(plist, i, j, NULL);
|
||||
if (filep == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -642,25 +676,36 @@ int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist,
|
||||
#endif
|
||||
if (!spawn_file_is_duplicateable(actions, fd, fcloexec))
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (fcloexec)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = files_extend(clist, i + 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Yes... duplicate it for the child, include O_CLOEXEC flag. */
|
||||
|
||||
ret = file_dup2(filep, files_fget_by_index(clist, i, j));
|
||||
filep2 = files_fget_by_index(clist, i, j, &new);
|
||||
ret = file_dup2(filep, filep2);
|
||||
fs_putfilep(filep2);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (new)
|
||||
{
|
||||
fs_putfilep(filep2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -721,17 +766,55 @@ int fs_getfilep(int fd, FAR struct file **filep)
|
||||
|
||||
*filep = files_fget(list, fd);
|
||||
|
||||
/* if f_inode is NULL, fd was closed */
|
||||
/* if *filep is NULL, fd was closed */
|
||||
|
||||
if ((*filep)->f_inode == NULL)
|
||||
if (*filep == NULL)
|
||||
{
|
||||
*filep = NULL;
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fs_putfilep
|
||||
*
|
||||
* Description:
|
||||
* Handles reference counts for files, less than or equal to 0 and close
|
||||
* the file
|
||||
*
|
||||
* Input Parameters:
|
||||
* filep - The caller provided location in which to return the 'struct
|
||||
* file' instance.
|
||||
****************************************************************************/
|
||||
|
||||
int fs_putfilep(FAR struct file *filep)
|
||||
{
|
||||
irqstate_t flags;
|
||||
int ret = 0;
|
||||
int refs;
|
||||
|
||||
DEBUGASSERT(filep);
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
|
||||
refs = --filep->f_refs;
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
|
||||
/* If refs is zero, the close() had called, closing it now. */
|
||||
|
||||
if (refs == 0)
|
||||
{
|
||||
ret = file_close(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: fs putfilep file_close() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nx_dup2_from_tcb
|
||||
*
|
||||
@ -870,12 +953,20 @@ int nx_close_from_tcb(FAR struct tcb_s *tcb, int fd)
|
||||
|
||||
/* If the file was properly opened, there should be an inode assigned */
|
||||
|
||||
if (filep->f_inode == NULL)
|
||||
if (filep == NULL)
|
||||
{
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
return file_close(filep);
|
||||
/* files_fget will increase the reference count, there call fs_putfilep
|
||||
* reduce reference count.
|
||||
*/
|
||||
|
||||
fs_putfilep(filep);
|
||||
|
||||
/* Undo the last reference count from file_allocate_from_tcb */
|
||||
|
||||
return fs_putfilep(filep);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -286,6 +286,11 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
|
||||
|
||||
ret = file_mmap_(filep, start, length,
|
||||
prot, flags, offset, false, &mapped);
|
||||
if (fd != -1)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
|
@ -596,21 +596,21 @@ static int inotify_close(FAR struct file *filep)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct inotify_device_s *inotify_get_device_from_fd(int fd)
|
||||
static FAR struct inotify_device_s *
|
||||
inotify_get_device_from_fd(int fd, FAR struct file **filep)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
|
||||
if (fs_getfilep(fd, &filep) < 0)
|
||||
if (fs_getfilep(fd, filep) < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filep == NULL || filep->f_inode != &g_inotify_inode)
|
||||
if ((*filep)->f_inode != &g_inotify_inode)
|
||||
{
|
||||
fs_putfilep(*filep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return filep->f_priv;
|
||||
return (*filep)->f_priv;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1056,6 +1056,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
|
||||
FAR struct inotify_watch_s *watch;
|
||||
FAR struct inotify_watch_s *old;
|
||||
FAR struct inotify_device_s *dev;
|
||||
FAR struct file *filep;
|
||||
FAR char *abspath;
|
||||
struct stat buf;
|
||||
int ret;
|
||||
@ -1066,7 +1067,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
dev = inotify_get_device_from_fd(fd);
|
||||
dev = inotify_get_device_from_fd(fd, &filep);
|
||||
if (dev == NULL)
|
||||
{
|
||||
set_errno(EBADF);
|
||||
@ -1076,6 +1077,7 @@ int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
|
||||
abspath = lib_realpath(pathname, NULL, mask & IN_DONT_FOLLOW);
|
||||
if (abspath == NULL)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
@ -1146,6 +1148,7 @@ out:
|
||||
nxmutex_unlock(&g_inotify.lock);
|
||||
|
||||
out_free:
|
||||
fs_putfilep(filep);
|
||||
lib_free(abspath);
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -1177,8 +1180,9 @@ int inotify_rm_watch(int fd, int wd)
|
||||
{
|
||||
FAR struct inotify_device_s *dev;
|
||||
FAR struct inotify_watch_s *watch;
|
||||
FAR struct file *filep;
|
||||
|
||||
dev = inotify_get_device_from_fd(fd);
|
||||
dev = inotify_get_device_from_fd(fd, &filep);
|
||||
if (dev == NULL)
|
||||
{
|
||||
set_errno(EBADF);
|
||||
@ -1192,6 +1196,7 @@ int inotify_rm_watch(int fd, int wd)
|
||||
{
|
||||
nxmutex_unlock(&dev->lock);
|
||||
nxmutex_unlock(&g_inotify.lock);
|
||||
fs_putfilep(filep);
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
@ -1199,6 +1204,7 @@ int inotify_rm_watch(int fd, int wd)
|
||||
inotify_remove_watch(dev, watch);
|
||||
nxmutex_unlock(&dev->lock);
|
||||
nxmutex_unlock(&g_inotify.lock);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1295,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
|
||||
|
||||
/* Is there an inode associated with the file descriptor? */
|
||||
|
||||
if (filep->f_inode == NULL)
|
||||
if (filep == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1321,6 +1321,7 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
|
||||
procfile->line[linesize - 2] = '\n';
|
||||
}
|
||||
|
||||
fs_putfilep(filep);
|
||||
copysize = procfs_memcpy(procfile->line, linesize,
|
||||
buffer, remaining, &offset);
|
||||
|
||||
|
@ -192,8 +192,7 @@ int sockfd_allocate(FAR struct socket *psock, int oflags)
|
||||
|
||||
FAR struct socket *file_socket(FAR struct file *filep)
|
||||
{
|
||||
if (filep != NULL && filep->f_inode != NULL &&
|
||||
INODE_IS_SOCKET(filep->f_inode))
|
||||
if (filep != NULL && INODE_IS_SOCKET(filep->f_inode))
|
||||
{
|
||||
return filep->f_priv;
|
||||
}
|
||||
@ -201,17 +200,20 @@ FAR struct socket *file_socket(FAR struct file *filep)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sockfd_socket(int sockfd, FAR struct socket **socketp)
|
||||
int sockfd_socket(int sockfd, FAR struct file **filep,
|
||||
FAR struct socket **socketp)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
|
||||
if (fs_getfilep(sockfd, &filep) < 0)
|
||||
if (fs_getfilep(sockfd, filep) < 0)
|
||||
{
|
||||
*socketp = NULL;
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
*socketp = file_socket(filep);
|
||||
*socketp = file_socket(*filep);
|
||||
if (*socketp == NULL)
|
||||
{
|
||||
fs_putfilep(*filep);
|
||||
}
|
||||
|
||||
return *socketp != NULL ? OK : -ENOTSOCK;
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ int file_dup(FAR struct file *filep, int minfd, int flags)
|
||||
if (fd2 < 0)
|
||||
{
|
||||
file_close(&filep2);
|
||||
return fd2;
|
||||
}
|
||||
|
||||
return fd2;
|
||||
@ -97,11 +96,10 @@ int dup(int fd)
|
||||
goto err;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Let file_dup() do the real work */
|
||||
|
||||
ret = file_dup(filep, 0, 0);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err;
|
||||
|
@ -134,14 +134,13 @@ static struct inode g_epoll_inode =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static FAR epoll_head_t *epoll_head_from_fd(int fd)
|
||||
static FAR epoll_head_t *epoll_head_from_fd(int fd, FAR struct file **filep)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get file pointer by file descriptor */
|
||||
|
||||
ret = fs_getfilep(fd, &filep);
|
||||
ret = fs_getfilep(fd, filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
@ -150,13 +149,14 @@ static FAR epoll_head_t *epoll_head_from_fd(int fd)
|
||||
|
||||
/* Check fd come from us */
|
||||
|
||||
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_epoll_ops)
|
||||
if ((*filep)->f_inode->u.i_ops != &g_epoll_ops)
|
||||
{
|
||||
fs_putfilep(*filep);
|
||||
set_errno(EBADF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (FAR epoll_head_t *)filep->f_priv;
|
||||
return (*filep)->f_priv;
|
||||
}
|
||||
|
||||
static int epoll_do_open(FAR struct file *filep)
|
||||
@ -476,12 +476,13 @@ void epoll_close(int epfd)
|
||||
int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
|
||||
{
|
||||
FAR struct list_node *extend;
|
||||
FAR struct file *filep;
|
||||
FAR epoll_head_t *eph;
|
||||
FAR epoll_node_t *epn;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
eph = epoll_head_from_fd(epfd);
|
||||
eph = epoll_head_from_fd(epfd, &filep);
|
||||
if (eph == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
@ -690,10 +691,12 @@ int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
|
||||
|
||||
out:
|
||||
nxmutex_unlock(&eph->lock);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
err:
|
||||
nxmutex_unlock(&eph->lock);
|
||||
err_without_lock:
|
||||
fs_putfilep(filep);
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
@ -705,11 +708,12 @@ err_without_lock:
|
||||
int epoll_pwait(int epfd, FAR struct epoll_event *evs,
|
||||
int maxevents, int timeout, FAR const sigset_t *sigmask)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
FAR epoll_head_t *eph;
|
||||
sigset_t oldsigmask;
|
||||
int ret;
|
||||
|
||||
eph = epoll_head_from_fd(epfd);
|
||||
eph = epoll_head_from_fd(epfd, &filep);
|
||||
if (eph == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
@ -755,9 +759,11 @@ retry:
|
||||
ret = num;
|
||||
}
|
||||
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
fs_putfilep(filep);
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
@ -776,10 +782,11 @@ err:
|
||||
int epoll_wait(int epfd, FAR struct epoll_event *evs,
|
||||
int maxevents, int timeout)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
FAR epoll_head_t *eph;
|
||||
int ret;
|
||||
|
||||
eph = epoll_head_from_fd(epfd);
|
||||
eph = epoll_head_from_fd(epfd, &filep);
|
||||
if (eph == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
@ -822,9 +829,11 @@ retry:
|
||||
ret = num;
|
||||
}
|
||||
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
fs_putfilep(filep);
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ static int fchstat(int fd, FAR struct stat *buf, int flags)
|
||||
/* Perform the fchstat operation */
|
||||
|
||||
ret = file_fchstat(filep, buf, flags);
|
||||
fs_putfilep(filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Successfully fchstat'ed the file */
|
||||
|
@ -350,13 +350,12 @@ int fcntl(int fd, int cmd, ...)
|
||||
ret = fs_getfilep(fd, &filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Let file_vfcntl() do the real work. The errno is not set on
|
||||
* failures.
|
||||
*/
|
||||
|
||||
ret = file_vfcntl(filep, cmd, ap);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -236,7 +236,8 @@ int nx_fstat(int fd, FAR struct stat *buf)
|
||||
{
|
||||
/* Perform the fstat operation */
|
||||
|
||||
return file_fstat(filep, buf);
|
||||
ret = file_fstat(filep, buf);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -72,22 +72,10 @@ int fstatfs(int fd, FAR struct statfs *buf)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Get the inode from the file structure */
|
||||
|
||||
inode = filep->f_inode;
|
||||
DEBUGASSERT(inode != NULL);
|
||||
|
||||
/* Check if the file is open */
|
||||
|
||||
if (inode == NULL)
|
||||
{
|
||||
/* The descriptor does not refer to an open file. */
|
||||
|
||||
ret = -EBADF;
|
||||
}
|
||||
else
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
/* The way we handle the stat depends on the type of inode that we
|
||||
* are dealing with.
|
||||
@ -121,6 +109,7 @@ int fstatfs(int fd, FAR struct statfs *buf)
|
||||
|
||||
/* Check if the fstat operation was successful */
|
||||
|
||||
fs_putfilep(filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Successfully statfs'ed the file */
|
||||
|
@ -110,11 +110,10 @@ int fsync(int fd)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Perform the fsync operation */
|
||||
|
||||
ret = file_fsync(filep);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
|
@ -276,6 +276,7 @@ int ioctl(int fd, int req, ...)
|
||||
ret = file_vioctl(filep, req, ap);
|
||||
va_end(ap);
|
||||
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err;
|
||||
|
@ -131,11 +131,11 @@ off_t nx_seek(int fd, off_t offset, int whence)
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Then let file_seek do the real work */
|
||||
|
||||
return file_seek(filep, offset, whence);
|
||||
ret = file_seek(filep, offset, whence);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -218,7 +218,9 @@ int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup)
|
||||
|
||||
/* Let file_poll() do the rest */
|
||||
|
||||
return file_poll(filep, fds, setup);
|
||||
ret = file_poll(filep, fds, setup);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -138,11 +138,10 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Let file_pread do the real work */
|
||||
|
||||
ret = file_pread(filep, buf, nbytes, offset);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
|
@ -144,6 +144,7 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
|
||||
/* Let file_pwrite do the real work */
|
||||
|
||||
ret = file_pwrite(filep, buf, nbytes, offset);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
|
@ -145,7 +145,9 @@ ssize_t nx_read(int fd, FAR void *buf, size_t nbytes)
|
||||
|
||||
/* Then let file_read do all of the work. */
|
||||
|
||||
return file_read(filep, buf, nbytes);
|
||||
ret = file_read(filep, buf, nbytes);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -342,10 +342,13 @@ ssize_t sendfile(int outfd, int infd, FAR off_t *offset, size_t count)
|
||||
ret = fs_getfilep(infd, &infile);
|
||||
if (ret < 0)
|
||||
{
|
||||
fs_putfilep(outfile);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = file_sendfile(outfile, infile, offset, count);
|
||||
fs_putfilep(outfile);
|
||||
fs_putfilep(infile);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
|
@ -328,6 +328,7 @@ out:
|
||||
int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
{
|
||||
FAR struct signalfd_priv_s *dev;
|
||||
FAR struct file *filep = NULL;
|
||||
struct sigaction act;
|
||||
int ret = EINVAL;
|
||||
int signo;
|
||||
@ -360,8 +361,6 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR struct file *filep;
|
||||
|
||||
if (fs_getfilep(fd, &filep) < 0)
|
||||
{
|
||||
ret = EBADF;
|
||||
@ -370,6 +369,7 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
|
||||
if (filep->f_inode->u.i_ops != &g_signalfd_fileops)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -397,6 +397,11 @@ int signalfd(int fd, FAR const sigset_t *mask, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (filep != NULL)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
errout_with_dev:
|
||||
|
@ -85,8 +85,8 @@ int syncfs(int fd)
|
||||
ret = fs_getfilep(fd, &filep);
|
||||
if (ret == OK)
|
||||
{
|
||||
DEBUGASSERT(filep != NULL);
|
||||
ret = file_syncfs(filep);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
|
@ -511,12 +511,9 @@ int timerfd_settime(int fd, int flags,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check fd come from us */
|
||||
|
||||
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_timerfd_fops)
|
||||
if (filep->f_inode->u.i_ops != &g_timerfd_fops)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
goto errout_with_filep;
|
||||
}
|
||||
|
||||
dev = (FAR struct timerfd_priv_s *)filep->f_priv;
|
||||
@ -556,6 +553,7 @@ int timerfd_settime(int fd, int flags,
|
||||
if (new_value->it_value.tv_sec <= 0 && new_value->it_value.tv_nsec <= 0)
|
||||
{
|
||||
leave_critical_section(intflags);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -601,12 +599,15 @@ int timerfd_settime(int fd, int flags,
|
||||
if (ret < 0)
|
||||
{
|
||||
leave_critical_section(intflags);
|
||||
goto errout;
|
||||
goto errout_with_filep;
|
||||
}
|
||||
|
||||
leave_critical_section(intflags);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
|
||||
errout_with_filep:
|
||||
fs_putfilep(filep);
|
||||
errout:
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
@ -635,11 +636,9 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check fd come from us */
|
||||
|
||||
if (!filep->f_inode || filep->f_inode->u.i_ops != &g_timerfd_fops)
|
||||
if (filep->f_inode->u.i_ops != &g_timerfd_fops)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
fs_putfilep(filep);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@ -653,6 +652,7 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
|
||||
|
||||
clock_ticks2time(&curr_value->it_value, ticks);
|
||||
clock_ticks2time(&curr_value->it_interval, dev->delay);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
|
@ -174,11 +174,10 @@ int ftruncate(int fd, off_t length)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
DEBUGASSERT(filep != NULL);
|
||||
|
||||
/* Perform the truncate operation */
|
||||
|
||||
ret = file_truncate(filep, length);
|
||||
fs_putfilep(filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
return 0;
|
||||
|
@ -146,6 +146,7 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes)
|
||||
*/
|
||||
|
||||
ret = file_write(filep, buf, nbytes);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -465,6 +465,7 @@ typedef struct cookie_io_functions_t
|
||||
struct file
|
||||
{
|
||||
int f_oflags; /* Open mode flags */
|
||||
int f_refs; /* Reference count */
|
||||
off_t f_pos; /* File position */
|
||||
FAR struct inode *f_inode; /* Driver or file system interface */
|
||||
FAR void *f_priv; /* Per file driver private data */
|
||||
@ -1151,6 +1152,21 @@ int nx_open(FAR const char *path, int oflags, ...);
|
||||
|
||||
int fs_getfilep(int fd, FAR struct file **filep);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fs_putfilep
|
||||
*
|
||||
* Description:
|
||||
* Release reference counts for files, less than or equal to 0 and close
|
||||
* the file
|
||||
*
|
||||
* Input Parameters:
|
||||
* filep - The caller provided location in which to return the 'struct
|
||||
* file' instance.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fs_putfilep(FAR struct file *filep);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: file_close
|
||||
*
|
||||
|
@ -597,7 +597,8 @@ int sockfd_allocate(FAR struct socket *psock, int oflags);
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct socket *file_socket(FAR struct file *filep);
|
||||
int sockfd_socket(int sockfd, FAR struct socket **socketp);
|
||||
int sockfd_socket(int sockfd, FAR struct file **filep,
|
||||
FAR struct socket **socketp);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: psock_socket
|
||||
|
@ -120,11 +120,13 @@ static int local_sendctl(FAR struct local_conn_s *conn,
|
||||
filep2 = kmm_zalloc(sizeof(*filep2));
|
||||
if (!filep2)
|
||||
{
|
||||
fs_putfilep(filep);
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = file_dup2(filep, filep2);
|
||||
fs_putfilep(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
kmm_free(filep2);
|
||||
|
@ -245,6 +245,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
|
||||
{
|
||||
FAR struct socket *psock = NULL;
|
||||
FAR struct socket *newsock;
|
||||
FAR struct file *filep;
|
||||
int oflags = O_RDWR;
|
||||
int errcode;
|
||||
int newfd;
|
||||
@ -262,7 +263,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
|
||||
@ -276,7 +277,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
|
||||
if (newsock == NULL)
|
||||
{
|
||||
errcode = ENOMEM;
|
||||
goto errout;
|
||||
goto errout_with_filep;
|
||||
}
|
||||
|
||||
ret = psock_accept(psock, addr, addrlen, newsock, flags);
|
||||
@ -307,6 +308,7 @@ int accept4(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen,
|
||||
goto errout_with_psock;
|
||||
}
|
||||
|
||||
fs_putfilep(filep);
|
||||
leave_cancellation_point();
|
||||
return newfd;
|
||||
|
||||
@ -316,6 +318,9 @@ errout_with_psock:
|
||||
errout_with_alloc:
|
||||
kmm_free(newsock);
|
||||
|
||||
errout_with_filep:
|
||||
fs_putfilep(filep);
|
||||
|
||||
errout:
|
||||
leave_cancellation_point();
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -151,17 +152,19 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_bind do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_bind(psock, addr, addrlen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -224,6 +225,7 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
||||
int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* accept() is a cancellation point */
|
||||
@ -232,13 +234,14 @@ int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_connect() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_connect(psock, addr, addrlen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -147,17 +148,19 @@ int getpeername(int sockfd, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Let psock_getpeername() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_getpeername(psock, addr, addrlen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -145,17 +146,19 @@ int getsockname(int sockfd, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Let psock_getsockname() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_getsockname(psock, addr, addrlen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
@ -348,17 +350,19 @@ int getsockopt(int sockfd, int level, int option,
|
||||
void *value, socklen_t *value_len)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_getsockopt() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_getsockopt(psock, level, option, value, value_len);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -140,11 +140,12 @@ int psock_listen(FAR struct socket *psock, int backlog)
|
||||
int listen(int sockfd, int backlog)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* The let psock_listen to the work. If psock_listen() fails, it will have
|
||||
* set the errno variable.
|
||||
@ -153,6 +154,7 @@ int listen(int sockfd, int backlog)
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_listen(psock, backlog);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -155,6 +155,7 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
||||
FAR struct sockaddr *from, FAR socklen_t *fromlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
ssize_t ret;
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
struct sockaddr_storage kaddr;
|
||||
@ -192,13 +193,14 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_recvfrom() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_recvfrom(psock, buf, len, flags, from, fromlen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -167,6 +168,7 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
|
||||
ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
ssize_t ret;
|
||||
|
||||
/* recvmsg() is a cancellation point */
|
||||
@ -175,13 +177,14 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Let psock_recvmsg() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_recvmsg(psock, msg, flags);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -141,6 +142,7 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
|
||||
ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
ssize_t ret;
|
||||
|
||||
/* sendmsg() is a cancellation point */
|
||||
@ -149,13 +151,14 @@ ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Let psock_sendmsg() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_sendmsg(psock, msg, flags);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -201,6 +201,7 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
|
||||
FAR const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
ssize_t ret;
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
struct sockaddr_storage kaddr;
|
||||
@ -237,13 +238,14 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* And let psock_sendto do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_sendto(psock, buf, len, flags, to, tolen);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <assert.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <netdev/netdev.h>
|
||||
@ -385,17 +386,19 @@ int setsockopt(int sockfd, int level, int option, const void *value,
|
||||
socklen_t value_len)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_setockopt() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_setsockopt(psock, level, option, value, value_len);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "socket/socket.h"
|
||||
@ -128,17 +129,19 @@ int psock_shutdown(FAR struct socket *psock, int how)
|
||||
int shutdown(int sockfd, int how)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure */
|
||||
|
||||
ret = sockfd_socket(sockfd, &psock);
|
||||
ret = sockfd_socket(sockfd, &filep, &psock);
|
||||
|
||||
/* Then let psock_shutdown() do all of the work */
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = psock_shutdown(psock, how);
|
||||
fs_putfilep(filep);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -106,18 +106,16 @@ int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat)
|
||||
int ret;
|
||||
|
||||
ret = fs_getfilep(mqdes, &filep);
|
||||
if (ret < 0)
|
||||
if (ret >= 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
ret = file_mq_getattr(filep, mq_stat);
|
||||
fs_putfilep(filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
ret = file_mq_getattr(filep, mq_stat);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -115,12 +115,12 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
|
||||
|
||||
/* Was a valid message queue descriptor provided? */
|
||||
|
||||
if (!inode || !inode->i_private)
|
||||
if (!inode->i_private)
|
||||
{
|
||||
/* No.. return EBADF */
|
||||
|
||||
errval = EBADF;
|
||||
goto errout_without_lock;
|
||||
goto errout_with_filep;
|
||||
}
|
||||
|
||||
/* Get a pointer to the message queue */
|
||||
@ -184,11 +184,15 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
fs_putfilep(filep);
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
leave_critical_section(flags);
|
||||
|
||||
errout_with_filep:
|
||||
fs_putfilep(filep);
|
||||
|
||||
errout_without_lock:
|
||||
set_errno(errval);
|
||||
return ERROR;
|
||||
|
@ -153,7 +153,7 @@ ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
||||
FAR unsigned int *prio)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
|
||||
ret = fs_getfilep(mqdes, &filep);
|
||||
if (ret < 0)
|
||||
@ -161,7 +161,9 @@ ssize_t nxmq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return file_mq_receive(filep, msg, msglen, prio);
|
||||
ret = file_mq_receive(filep, msg, msglen, prio);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -181,7 +181,9 @@ int nxmq_send(mqd_t mqdes, FAR const char *msg, size_t msglen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return file_mq_send(filep, msg, msglen, prio);
|
||||
ret = file_mq_send(filep, msg, msglen, prio);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -118,18 +118,16 @@ int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat,
|
||||
int ret;
|
||||
|
||||
ret = fs_getfilep(mqdes, &filep);
|
||||
if (ret < 0)
|
||||
if (ret >= 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
ret = file_mq_setattr(filep, mq_stat, oldstat);
|
||||
fs_putfilep(filep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
ret = file_mq_setattr(filep, mq_stat, oldstat);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
||||
FAR const struct timespec *abstime)
|
||||
{
|
||||
FAR struct file *filep;
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
|
||||
ret = fs_getfilep(mqdes, &filep);
|
||||
if (ret < 0)
|
||||
@ -365,7 +365,9 @@ ssize_t nxmq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return file_mq_timedreceive_internal(filep, msg, msglen, prio, abstime, 0);
|
||||
ret = file_mq_timedreceive_internal(filep, msg, msglen, prio, abstime, 0);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -437,7 +437,9 @@ int nxmq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return file_mq_timedsend_internal(filep, msg, msglen, prio, abstime, 0);
|
||||
ret = file_mq_timedsend_internal(filep, msg, msglen, prio, abstime, 0);
|
||||
fs_putfilep(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user