diff --git a/fs/aio/aio_fsync.c b/fs/aio/aio_fsync.c index fd08328db45..86f67bdd343 100644 --- a/fs/aio/aio_fsync.c +++ b/fs/aio/aio_fsync.c @@ -99,10 +99,8 @@ static void aio_fsync_worker(FAR void *arg) ret = file_fsync(aioc->u.aioc_filep); if (ret < 0) { - int errcode = get_errno(); - ferr("ERROR: fsync failed: %d\n", errcode); - DEBUGASSERT(errcode > 0); - aiocbp->aio_result = -errcode; + ferr("ERROR: file_fsync failed: %d\n", ret); + aiocbp->aio_result = ret; } else { diff --git a/fs/aio/aioc_contain.c b/fs/aio/aioc_contain.c index 88d3deddb68..ac492abbc37 100644 --- a/fs/aio/aioc_contain.c +++ b/fs/aio/aioc_contain.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/aio/aioc_contain.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -86,6 +86,7 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) #ifdef CONFIG_PRIORITY_INHERITANCE struct sched_param param; #endif + int ret; #if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) if (aiocbp->aio_fildes < CONFIG_NFILE_DESCRIPTORS) @@ -94,13 +95,13 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) { /* Get the file structure corresponding to the file descriptor. */ - u.filep = fs_getfilep(aiocbp->aio_fildes); - if (!u.filep) + ret = fs_getfilep(aiocbp->aio_fildes, &u.filep); + if (ret < 0) { - /* The errno value has already been set */ - - return NULL; + goto errout; } + + DEBUGASSERT(u.filep != NULL); } #endif #if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) @@ -111,12 +112,14 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) /* Get the socket structure corresponding to the socket descriptor */ u.psock = sockfd_socket(aiocbp->aio_fildes); - if (!u.psock) + if (u.psock == NULL) { - /* Does not set the errno. EBADF is the most likely explanation. */ + /* Does not return error information. EBADF is the most likely + * explanation. + */ - set_errno(EBADF); - return NULL; + ret = -EBADF; + goto errout; } } #endif @@ -146,6 +149,10 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) dq_addlast(&aioc->aioc_link, &g_aio_pending); aio_unlock(); return aioc; + +errout: + set_errno(-ret); + return NULL; } /**************************************************************************** diff --git a/fs/vfs/fs_dupfd.c b/fs/vfs/fs_dupfd.c index 70137916d73..41650368f9b 100644 --- a/fs/vfs/fs_dupfd.c +++ b/fs/vfs/fs_dupfd.c @@ -55,10 +55,6 @@ #define DUP_ISOPEN(filep) (filep->f_inode != NULL) -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -128,24 +124,27 @@ int fs_dupfd(int fd, int minfd) /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - return ERROR; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Let file_dup() do the real work */ ret = file_dup(filep, minfd); if (ret < 0) { - set_errno(-ret); - return ERROR; + goto errout; } return OK; + +errout: + set_errno(-ret); + return ERROR; } #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ diff --git a/fs/vfs/fs_dupfd2.c b/fs/vfs/fs_dupfd2.c index 0631553bf1b..1f4f983196a 100644 --- a/fs/vfs/fs_dupfd2.c +++ b/fs/vfs/fs_dupfd2.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_dupfd2.c * - * Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014, 2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -84,27 +85,30 @@ int dup2(int fd1, int fd2) #endif { FAR struct file *filep1; - FAR struct file *filep2; + FAR struct file *filep2 = NULL; int ret; /* Get the file structures corresponding to the file descriptors. */ - filep1 = fs_getfilep(fd1); - filep2 = fs_getfilep(fd2); - - if (!filep1 || !filep2) + ret = fs_getfilep(fd1, &filep1); + if (ret >= 0) { - /* The errno value has already been set */ - - return ERROR; + ret = fs_getfilep(fd2, &filep2); } + if (ret < 0) + { + goto errout; + } + + DEBUGASSERT(filep1 != NULL && filep2 != NULL); + /* Verify that fd1 is a valid, open file descriptor */ if (!DUP_ISOPEN(filep1)) { - set_errno(EBADF); - return ERROR; + ret = -EBADF; + goto errout; } /* Handle a special case */ @@ -119,11 +123,14 @@ int dup2(int fd1, int fd2) ret = file_dup2(filep1, filep2); if (ret < 0) { - set_errno(-ret); - return ERROR; + goto errout; } return OK; + +errout: + set_errno(-ret); + return ERROR; } #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c index c24305a0f87..67ebd617642 100644 --- a/fs/vfs/fs_fcntl.c +++ b/fs/vfs/fs_fcntl.c @@ -254,21 +254,17 @@ int fcntl(int fd, int cmd, ...) { /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret >= 0) { - /* The errno value has already been set */ + DEBUGASSERT(filep != NULL); - va_end(ap); - leave_cancellation_point(); - return ERROR; + /* Let file_vfcntl() do the real work. The errno is not set on + * failures. + */ + + ret = file_vfcntl(filep, cmd, ap); } - - /* Let file_vfcntl() do the real work. The errno is not set on - * failures. - */ - - ret = file_vfcntl(filep, cmd, ap); } else #endif diff --git a/fs/vfs/fs_fdopen.c b/fs/vfs/fs_fdopen.c index 6125db8dbec..09154ec56fd 100644 --- a/fs/vfs/fs_fdopen.c +++ b/fs/vfs/fs_fdopen.c @@ -67,17 +67,16 @@ static inline int fs_checkfd(FAR struct tcb_s *tcb, int fd, int oflags) { FAR struct file *filep; FAR struct inode *inode; + int ret; DEBUGASSERT(tcb && tcb->group); /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - return ERROR; + return ret; } /* Get the inode associated with the file descriptor. This should diff --git a/fs/vfs/fs_fstat.c b/fs/vfs/fs_fstat.c index 1cf97f4ebb8..f7aaf1cd4ce 100644 --- a/fs/vfs/fs_fstat.c +++ b/fs/vfs/fs_fstat.c @@ -84,8 +84,8 @@ int fstat(int fd, FAR struct stat *buf) { /* No networking... it is a bad descriptor in any event */ - set_errno(EBADF); - return ERROR; + ret = -EBADF; + goto errout; } /* The descriptor is in a valid range to file descriptor... do the @@ -93,14 +93,14 @@ int fstat(int fd, FAR struct stat *buf) * fs_getfilep() will set the errno variable. */ - filep = fs_getfilep(fd); - if (filep == NULL) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - return ERROR; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Get the inode from the file structure */ inode = filep->f_inode; @@ -135,13 +135,14 @@ int fstat(int fd, FAR struct stat *buf) /* Check if the fstat operation was successful */ - if (ret < 0) + if (ret >= 0) { - set_errno(-ret); - return ERROR; + /* Successfully fstat'ed the file */ + + return OK; } - /* Successfully fstat'ed the file */ - - return OK; +errout: + set_errno(-ret); + return ERROR; } diff --git a/fs/vfs/fs_fstatfs.c b/fs/vfs/fs_fstatfs.c index 207311ea470..80c0d1d7dd3 100644 --- a/fs/vfs/fs_fstatfs.c +++ b/fs/vfs/fs_fstatfs.c @@ -81,8 +81,8 @@ int fstatfs(int fd, FAR struct statfs *buf) { /* It is a bad, out-of-range descriptor */ - set_errno(EBADF); - return ERROR; + ret = -EBADF; + goto errout; } /* The descriptor is in a valid range to file descriptor... do the @@ -90,14 +90,14 @@ int fstatfs(int fd, FAR struct statfs *buf) * fs_getfilep() will set the errno variable. */ - filep = fs_getfilep(fd); - if (filep == NULL) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - return ERROR; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Get the inode from the file structure */ inode = filep->f_inode; @@ -144,13 +144,14 @@ int fstatfs(int fd, FAR struct statfs *buf) /* Check if the fstat operation was successful */ - if (ret < 0) + if (ret >= 0) { - set_errno(-ret); - return ERROR; + /* Successfully statfs'ed the file */ + + return OK; } - /* Successfully statfs'ed the file */ - - return OK; +errout: + set_errno(-ret); + return ERROR; } diff --git a/fs/vfs/fs_fsync.c b/fs/vfs/fs_fsync.c index 60c55634971..c2783dc436e 100644 --- a/fs/vfs/fs_fsync.c +++ b/fs/vfs/fs_fsync.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_fsync.c * - * Copyright (C) 2007-2009, 2013-2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013-2014, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -61,22 +62,20 @@ * * Description: * Equivalent to the standard fsync() function except that is accepts a - * struct file instance instead of a file descriptor. Currently used - * only by aio_fsync(); + * struct file instance instead of a file descriptor and it does not set + * the errno variable. * ****************************************************************************/ int file_fsync(FAR struct file *filep) { struct inode *inode; - int ret; /* Was this file opened for write access? */ if ((filep->f_oflags & O_WROK) == 0) { - ret = EBADF; - goto errout; + return -EBADF; } /* Is this inode a registered mountpoint? Does it support the @@ -88,23 +87,12 @@ int file_fsync(FAR struct file *filep) if (!inode || !INODE_IS_MOUNTPT(inode) || !inode->u.i_mops || !inode->u.i_mops->sync) { - ret = EINVAL; - goto errout; + return -EINVAL; } /* Yes, then tell the mountpoint to sync this file */ - ret = inode->u.i_mops->sync(filep); - if (ret >= 0) - { - return OK; - } - - ret = -ret; - -errout: - set_errno(ret); - return ERROR; + return inode->u.i_mops->sync(filep); } /**************************************************************************** @@ -126,20 +114,29 @@ int fsync(int fd) /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - leave_cancellation_point(); - return ERROR; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Perform the fsync operation */ ret = file_fsync(filep); + if (ret < 0) + { + goto errout; + } + leave_cancellation_point(); return ret; + +errout: + leave_cancellation_point(); + set_errno(-ret); + return ERROR; } #endif /* !CONFIG_DISABLE_MOUNTPOINT */ diff --git a/fs/vfs/fs_getfilep.c b/fs/vfs/fs_getfilep.c index 79daf09b65f..807d0cf6088 100644 --- a/fs/vfs/fs_getfilep.c +++ b/fs/vfs/fs_getfilep.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/vfs/fs_getfilep.c * - * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,10 +48,6 @@ #include "inode/inode.h" -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -64,25 +60,26 @@ * file. NOTE that this function will currently fail if it is provided * with a socket descriptor. * - * Parameters: - * fd - The file descriptor + * Input Parameters: + * fd - The file descriptor + * filep - The location to return the struct file instance * - * Return: - * A point to the corresponding struct file instance is returned on - * success. On failure, NULL is returned and the errno value is - * set appropriately (EBADF). + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. * ****************************************************************************/ -FAR struct file *fs_getfilep(int fd) +int fs_getfilep(int fd, FAR struct file **filep) { FAR struct filelist *list; - int errcode; + + DEBUGASSERT(filep != NULL); + *filep = (FAR struct file *)NULL; if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) { - errcode = EBADF; - goto errout; + return -EBADF; } /* The descriptor is in a valid range to file descriptor... Get the @@ -100,15 +97,11 @@ FAR struct file *fs_getfilep(int fd) if (list == NULL) { - errcode = EAGAIN; - goto errout; + return -EAGAIN; } /* And return the file pointer from the list */ - return &list->fl_files[fd]; - -errout: - set_errno(errcode); - return NULL; + *filep = &list->fl_files[fd]; + return OK; } diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index 7e916b3253a..a68dc43ce5c 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_ioctl.c * - * Copyright (C) 2007-2010, 2012-2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2012-2014, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -68,7 +69,9 @@ * arg The argument of the ioctl cmd * * Return: - * See ioctl() below. + * Returns a non-negative number on success; A negated errno value is + * returned on any failure (see comments ioctl() for a list of appropriate + * errno values). * ****************************************************************************/ @@ -76,8 +79,6 @@ int file_ioctl(FAR struct file *filep, int req, unsigned long arg) { FAR struct inode *inode; - int errcode; - int ret; DEBUGASSERT(filep != NULL); @@ -86,32 +87,19 @@ int file_ioctl(FAR struct file *filep, int req, unsigned long arg) inode = filep->f_inode; if (!inode) { - errcode = EBADF; - goto errout; + return -EBADF; } /* Does the driver support the ioctl method? */ if (inode->u.i_ops == NULL || inode->u.i_ops->ioctl == NULL) { - errcode = ENOTTY; - goto errout; + return -ENOTTY; } /* Yes on both accounts. Let the driver perform the ioctl command */ - ret = (int)inode->u.i_ops->ioctl(filep, req, arg); - if (ret < 0) - { - errcode = -ret; - goto errout; - } - - return ret; - -errout: - set_errno(errcode); - return ERROR; + return (int)inode->u.i_ops->ioctl(filep, req, arg); } #endif /* CONFIG_NFILE_DESCRIPTORS > 0 */ @@ -153,6 +141,7 @@ int ioctl(int fd, int req, unsigned long arg) int errcode; #if CONFIG_NFILE_DESCRIPTORS > 0 FAR struct file *filep; + int ret; /* Did we get a valid file descriptor? */ @@ -164,7 +153,7 @@ int ioctl(int fd, int req, unsigned long arg) #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) { - int ret = netdev_ioctl(fd, req, arg); + ret = netdev_ioctl(fd, req, arg); if (ret < 0) { errcode = -ret; @@ -184,22 +173,27 @@ int ioctl(int fd, int req, unsigned long arg) #if CONFIG_NFILE_DESCRIPTORS > 0 /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* Apparently, the fd does not correspond to any open file. In the - * case of errors, the errno value has already been set by - * fs_getfilep(). - */ - - return ERROR; + errcode = -ret; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Perform the file ioctl. If file_ioctl() fails, it will set the errno * value appropriately. */ - return file_ioctl(filep, req, arg); + ret = file_ioctl(filep, req, arg); + if (ret < 0) + { + errcode = -ret; + goto errout; + } + + return ret; #else errcode = ENOTTY; #endif diff --git a/fs/vfs/fs_lseek.c b/fs/vfs/fs_lseek.c index daca43f020d..6827d931d10 100644 --- a/fs/vfs/fs_lseek.c +++ b/fs/vfs/fs_lseek.c @@ -162,27 +162,34 @@ off_t lseek(int fd, off_t offset, int whence) { FAR struct file *filep; off_t newpos; + int errcode; + int ret; /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - return (off_t)ERROR; + errcode = -ret; + goto errout; } + DEBUGASSERT(filep != NULL); + /* Then let file_seek do the real work */ - newpos = file_seek(filep, offset, whence); - if (newpos < 0) - { - set_errno((int)-newpos); - return (off_t)ERROR; - } + newpos = file_seek(filep, offset, whence); + if (newpos < 0) + { + errcode = (int)-newpos; + goto errout; + } return newpos; + +errout: + set_errno(errcode); + return (off_t)ERROR; } #endif diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index c3e56e6a736..04b0d4b13d4 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_open.c * - * Copyright (C) 2007-2009, 2011-2012, 2016-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -216,12 +217,11 @@ int open(const char *path, int oflags, ...) /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - goto errout; + ret = -ret; + goto errout_with_inode; } /* Perform the driver open operation. NOTE that the open method may be diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 81480cbe3d6..825f8d16d85 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -321,7 +321,8 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) * setup - true: Setup up the poll; false: Teardown the poll * * Returned Value: - * 0: Success; Negated errno on failure + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. * ****************************************************************************/ @@ -329,19 +330,18 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) int fdesc_poll(int fd, FAR struct pollfd *fds, bool setup) { FAR struct file *filep; + int ret; /* Get the file pointer corresponding to this file descriptor */ - filep = fs_getfilep(fd); - if (!filep) + ret = fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - int errorcode = get_errno(); - DEBUGASSERT(errorcode > 0); - return -errorcode; + return ret; } + DEBUGASSERT(filep != NULL); + /* Let file_poll() do the rest */ return file_poll(filep, fds, setup); diff --git a/fs/vfs/fs_pread.c b/fs/vfs/fs_pread.c index 03c1ec27c07..782c7448fbd 100644 --- a/fs/vfs/fs_pread.c +++ b/fs/vfs/fs_pread.c @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -146,25 +147,27 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset) /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - ret = (ssize_t)ERROR; + goto errout; } - else - { - /* Let file_pread do the real work */ - ret = file_pread(filep, buf, nbytes, offset); - if (ret < 0) - { - set_errno((int)-ret); - ret = (ssize_t)ERROR; - } + DEBUGASSERT(filep != NULL); + + /* Let file_pread do the real work */ + + ret = file_pread(filep, buf, nbytes, offset); + if (ret < 0) + { + goto errout; } leave_cancellation_point(); return ret; + +errout: + set_errno((int)-ret); + leave_cancellation_point(); + return (ssize_t)ERROR; } diff --git a/fs/vfs/fs_pwrite.c b/fs/vfs/fs_pwrite.c index ad7741b9d05..1a67d915f87 100644 --- a/fs/vfs/fs_pwrite.c +++ b/fs/vfs/fs_pwrite.c @@ -144,25 +144,25 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset) /* Get the file structure corresponding to the file descriptor. */ - filep = fs_getfilep(fd); - if (!filep) + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - ret = (ssize_t)ERROR; - } - else - { - /* Let file_pread do the real work */ - - ret = file_pwrite(filep, buf, nbytes, offset); - if (ret < 0) - { - set_errno((int)-ret); - ret = (ssize_t)ERROR; - } + goto errout; } - (void)enter_cancellation_point(); + /* Let file_pwrite do the real work */ + + ret = file_pwrite(filep, buf, nbytes, offset); + if (ret < 0) + { + goto errout; + } + + leave_cancellation_point(); return ret; + +errout: + set_errno((int)-ret); + leave_cancellation_point(); + return (ssize_t)ERROR; } diff --git a/fs/vfs/fs_read.c b/fs/vfs/fs_read.c index 42e0fa2b0fa..9cd139703ce 100644 --- a/fs/vfs/fs_read.c +++ b/fs/vfs/fs_read.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_read.c * - * Copyright (C) 2007-2009, 2012-2014, 2016-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2014, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -148,8 +149,8 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes) #else /* No networking... it is a bad descriptor in any event */ - set_errno(EBADF); - ret = ERROR; + ret = -EBADF; + goto errout; #endif } @@ -163,27 +164,27 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes) * fs_getfilep() will set the errno variable. */ - filep = fs_getfilep(fd); - if (filep == NULL) + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - ret = ERROR; + goto errout; } - else - { - /* Then let file_read do all of the work. */ - ret = file_read(filep, buf, nbytes); - if (ret < 0) - { - set_errno((int)-ret); - ret = ERROR; - } + /* Then let file_read do all of the work. */ + + ret = file_read(filep, buf, nbytes); + if (ret < 0) + { + goto errout; } } #endif leave_cancellation_point(); return ret; + +errout: + set_errno((int)-ret); + leave_cancellation_point(); + return (ssize_t)ERROR; } diff --git a/fs/vfs/fs_sendfile.c b/fs/vfs/fs_sendfile.c index c91435e11fb..a71dbcdf9bb 100644 --- a/fs/vfs/fs_sendfile.c +++ b/fs/vfs/fs_sendfile.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_sendfile.c * - * Copyright (C) 2007, 2009, 2011, 2013, 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013, 2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -111,19 +112,21 @@ ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count) (unsigned int)infd < CONFIG_NFILE_DESCRIPTORS) { FAR struct file *filep; + int ret; /* This appears to be a file-to-socket transfer. Get the file * structure. */ - filep = fs_getfilep(infd); - if (!filep) + ret = fs_getfilep(infd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - + set_errno(-ret); return ERROR; } + DEBUGASSERT(filep != NULL); + /* Then let net_sendfile do the work. */ return net_sendfile(outfd, filep, offset, count); diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c index 0a40a1ff27b..b180988a34a 100644 --- a/fs/vfs/fs_write.c +++ b/fs/vfs/fs_write.c @@ -1,7 +1,8 @@ /**************************************************************************** * fs/vfs/fs_write.c * - * Copyright (C) 2007-2009, 2012-2014, 2016-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2012-2014, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -155,8 +156,7 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes) if (buf == NULL) { - set_errno(EINVAL); - ret = ERROR; + ret = -EINVAL; goto errout; } @@ -173,8 +173,8 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes) ret = send(fd, buf, nbytes, 0); #else - set_errno(EBADF); - ret = ERROR; + ret = -EBADF; + goto errout; #endif } @@ -186,30 +186,29 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes) * failure. */ - filep = fs_getfilep(fd); - if (filep == NULL) + ret = (ssize_t)fs_getfilep(fd, &filep); + if (ret < 0) { - /* The errno value has already been set */ - - ret = ERROR; + goto errout; } - else - { - /* Perform the write operation using the file descriptor as an - * index. Note that file_write() will set the errno on failure. - */ - ret = file_write(filep, buf, nbytes); - if (ret < 0) - { - set_errno((int)-ret); - ret = ERROR; - } + /* Perform the write operation using the file descriptor as an + * index. Note that file_write() will set the errno on failure. + */ + + ret = file_write(filep, buf, nbytes); + if (ret < 0) + { + goto errout; } } #endif -errout: leave_cancellation_point(); return ret; + +errout: + set_errno(-ret); + leave_cancellation_point(); + return ERROR; } diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index fd2d44d8475..15dbab0a428 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -1,7 +1,8 @@ /**************************************************************************** * include/nuttx/fs/fs.h * - * Copyright (C) 2007-2009, 2011-2013, 2015-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013, 2015-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -61,6 +62,36 @@ * Pre-processor Definitions ****************************************************************************/ +/* Most internal OS interfaces are not available in the user space in + * PROTECTED and KERNEL builds. In that context, the corresponding + * application interfaces must be used. The differences between the two + * sets of interfaces are: The internal OS interfaces (1) do not cause + * cancellation points and (2) they do not modify the errno variable. + * + * This is only important when compiling libraries (libc or libnx) that are + * used both by the OS (libkc.a and libknx.a) or by the applications + * (libuc.a and libunx.a). The that case, the correct interface must be + * used for the build context. + * + * The interfaces open(), close(), creat(), read(), pread(), write(), + * pwrite(), poll(), select(), fcntl(), and aio_suspend() are all + * cancellation points. + * + * REVISIT: These cancellation points are an issue and may cause + * violations: It use of these internally will cause the calling function + * to become a cancellation points! + */ + +#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) +# define _NX_WRITE(f,b,s) nx_write(s,b,s) +# define _NX_ERRNO(r) (-(r)) +# define _NX_ERRVAL(r) (r) +#else +# define _NX_WRITE(f,b,s) rite(s,b,s) +# define _NX_ERRNO(r) errno +# define _NX_ERRVAL(r) (-errno) +#endif + /* Stream flags for the fs_flags field of in struct file_struct */ #define __FS_FLAG_EOF (1 << 0) /* EOF detected by a read operation */ @@ -739,13 +770,13 @@ int file_close_detached(FAR struct file *filep); * Description: * Return the inode of the block driver specified by 'pathname' * - * Inputs: + * Input Parameters: * pathname - the full path to the block driver to be opened * mountflags - if MS_RDONLY is not set, then driver must support write * operations (see include/sys/mount.h) * ppinode - address of the location to return the inode reference * - * Return: + * Returned Value: * Returns zero on success or a negated errno on failure: * * EINVAL - pathname or pinode is NULL @@ -767,10 +798,10 @@ int open_blockdriver(FAR const char *pathname, int mountflags, * Description: * Call the close method and release the inode * - * Inputs: + * Input Parameters: * inode - reference to the inode of a block driver opened by open_blockdriver * - * Return: + * Returned Value: * Returns zero on success or a negated errno on failure: * * EINVAL - inode is NULL @@ -788,12 +819,12 @@ int close_blockdriver(FAR struct inode *inode); * Description: * Perform device specific operations. * - * Parameters: + * Input Parameters: * fd File/socket descriptor of device * req The ioctl command * arg The argument of the ioctl cmd * - * Return: + * Returned Value: * >=0 on success (positive non-zero values are cmd-specific) * -1 on failure with errno set properly: * @@ -862,18 +893,18 @@ ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count); * file. NOTE that this function will currently fail if it is provided * with a socket descriptor. * - * Parameters: - * fd - The file descriptor + * Input Parameters: + * fd - The file descriptor + * filep - The location to return the struct file instance * - * Return: - * A point to the corresponding struct file instance is returned on - * success. On failure, NULL is returned and the errno value is - * set appropriately (EBADF). + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. * ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -FAR struct file *fs_getfilep(int fd); +int fs_getfilep(int fd, FAR struct file **filep); #endif /**************************************************************************** @@ -953,8 +984,8 @@ off_t file_seek(FAR struct file *filep, off_t offset, int whence); * * Description: * Equivalent to the standard fsync() function except that is accepts a - * struct file instance instead of a file descriptor. Currently used - * only by aio_fsync(); + * struct file instance instead of a file descriptor and it does not set + * the errno variable. * ****************************************************************************/ @@ -974,7 +1005,9 @@ int file_fsync(FAR struct file *filep); * arg The argument of the ioctl cmd * * Return: - * See ioctl() below. + * Returns a non-negative number on success; A negated errno value is + * returned on any failure (see comments ioctl() for a list of appropriate + * errno values). * ****************************************************************************/