diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-03 20:34:44 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-03 20:34:44 +0000 |
commit | c96d656001914b495f54e7a25d54079e41af86ce (patch) | |
tree | dabdb9c5fded41355669eccebd630d33b106689a /nuttx/fs | |
parent | 0792c58515fae8507fcd6de41ca7db89fd2734d4 (diff) | |
download | px4-nuttx-c96d656001914b495f54e7a25d54079e41af86ce.tar.gz px4-nuttx-c96d656001914b495f54e7a25d54079e41af86ce.tar.bz2 px4-nuttx-c96d656001914b495f54e7a25d54079e41af86ce.zip |
Add send, sendto, rec, recvfrom
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@328 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs')
-rw-r--r-- | nuttx/fs/fs_close.c | 134 | ||||
-rw-r--r-- | nuttx/fs/fs_write.c | 122 |
2 files changed, 196 insertions, 60 deletions
diff --git a/nuttx/fs/fs_close.c b/nuttx/fs/fs_close.c index a704d1d5e..5a63ba6a9 100644 --- a/nuttx/fs/fs_close.c +++ b/nuttx/fs/fs_close.c @@ -43,70 +43,120 @@ #include <sched.h> #include <errno.h> #include <nuttx/fs.h> + +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 +# include <nuttx/net.h> +#endif + #include "fs_internal.h" /**************************************************************************** * Global Functions ****************************************************************************/ +/**************************************************************************** + * Function: close + * + * Description: + * close() closes a file descriptor, so that it no longer refers to any + * file and may be reused. Any record locks (see fcntl(2)) held on the file + * it was associated with, and owned by the process, are removed (regardless + * of the file descriptor that was used to obtain the lock). + * + * If fd is the last copy of a particular file descriptor the resources + * associated with it are freed; if the descriptor was the last reference + * to a file which has been removed using unlink(2) the file is deleted. + * + * Parameters: + * fd file descriptor to close + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately. + * + * Assumptions: + * + ****************************************************************************/ + int close(int fd) { FAR struct filelist *list; + FAR struct inode *inode; + int err; + + /* Did we get a valid file descriptor? */ + + if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + { + /* Close a socket descriptor */ +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 + if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) + { + return net_close(fd); + } + else +#endif + { + err = EBADF; + goto errout; + } + } /* Get the thread-specific file list */ list = sched_getfiles(); if (!list) { - *get_errno_ptr() = EMFILE; - return ERROR; + err = EMFILE; + goto errout; } - if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) + /* If the file was properly opened, there should be an inode assigned */ + + inode = list->fl_files[fd].f_inode; + if (!inode) + { + err = EBADF; + goto errout; + } + + /* Close the driver or mountpoint. NOTES: (1) there is no + * exclusion mechanism here , the driver or mountpoint must be + * able to handle concurrent operations internally, (2) The driver + * may have been opened numerous times (for different file + * descriptors) and must also handle being closed numerous times. + * (3) for the case of the mountpoint, we depend on the close + * methods bing identical in signature and position in the operations + * vtable. + */ + + if (inode->u.i_ops && inode->u.i_ops->close) { - FAR struct inode *inode = list->fl_files[fd].f_inode; - if (inode) + /* Perform the close operation (by the driver) */ + + int ret = inode->u.i_ops->close(&list->fl_files[fd]); + if (ret < 0) { - int ret = OK; - - /* Close the driver or mountpoint. NOTES: (1) there is no - * exclusion mechanism here , the driver or mountpoint must be - * able to handle concurrent operations internally, (2) The driver - * may have been opened numerous times (for different file - * descriptors) and must also handle being closed numerous times. - * (3) for the case of the mountpoint, we depend on the close - * methods bing identical in signature and position in the operations - * vtable. - */ - - if (inode->u.i_ops && inode->u.i_ops->close) - { - /* Perform the close operation (by the driver) */ - - int status = inode->u.i_ops->close(&list->fl_files[fd]); - if (status < 0) - { - /* An error occurred while closing the driver */ - - *get_errno_ptr() = -status; - ret = ERROR; - } - } - - /* Release the file descriptor */ - - files_release(fd); - - /* Decrement the reference count on the inode. This may remove the inode and - * eliminate the name from the namespace - */ - - inode_release(inode); - return ret; + /* An error occurred while closing the driver */ + + err = -ret; + goto errout; } } - *get_errno_ptr() = EBADF; + /* Release the file descriptor */ + + files_release(fd); + + /* Decrement the reference count on the inode. This may remove the inode and + * eliminate the name from the namespace + */ + + inode_release(inode); + + return OK; + +errout: + *get_errno_ptr() = err; return ERROR; } diff --git a/nuttx/fs/fs_write.c b/nuttx/fs/fs_write.c index 60a6b8290..7de7898f4 100644 --- a/nuttx/fs/fs_write.c +++ b/nuttx/fs/fs_write.c @@ -47,48 +47,134 @@ #include <fcntl.h> #include <sched.h> #include <errno.h> + +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 +# include <sys/socket.h> +#endif + #include "fs_internal.h" /************************************************************ * Global Functions ************************************************************/ +/**************************************************************************** + * Function: send + * + * Description: + * write() writes up to nytes bytes to the file referenced by the file + * descriptor fd from the buffer starting at buf. + * + * Parameters: + * fd file descriptor (or socket descriptor) to write to + * buf Data to write + * nbytes Length of data to write + * + * Returned Value: + * On success, the number of bytes written are returned (zero indicates + * nothing was written). On error, -1 is returned, and errno is set appro‐ + * priately: + * + * EAGAIN + * Non-blocking I/O has been selected using O_NONBLOCK and the write + * would block. + * EBADF + * fd is not a valid file descriptor or is not open for writing. + * EFAULT + * buf is outside your accessible address space. + * EFBIG + * An attempt was made to write a file that exceeds the implementation + * defined maximum file size or the process' file size limit, or + * to write at a position past the maximum allowed offset. + * EINTR + * The call was interrupted by a signal before any data was written. + * EINVAL + * fd is attached to an object which is unsuitable for writing; or + * the file was opened with the O_DIRECT flag, and either the address + * specified in buf, the value specified in count, or the current + * file offset is not suitably aligned. + * EIO + * A low-level I/O error occurred while modifying the inode. + * ENOSPC + * The device containing the file referred to by fd has no room for + * the data. + * EPIPE + * fd is connected to a pipe or socket whose reading end is closed. + * When this happens the writing process will also receive a SIGPIPE + * signal. (Thus, the write return value is seen only if the program + * catches, blocks or ignores this signal.) + * + * Assumptions: + * + ****************************************************************************/ + int write(int fd, const void *buf, unsigned int nbytes) { FAR struct filelist *list; - int ret = EBADF; + FAR struct file *this_file; + FAR struct inode *inode; + int err; + int ret; + + /* Did we get a valid file descriptor? */ + + if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) + { + /* Write to a socket descriptor is equivalent to send with flags == 0 */ + +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 + if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) + { + return send(fd, buf, nbytes, 0); + } + else +#endif + { + err = EBADF; + goto errout; + } + } /* Get the thread-specific file list */ list = sched_getfiles(); if (!list) { - *get_errno_ptr() = EMFILE; - return ERROR; + err = EMFILE; + goto errout; } - /* Did we get a valid file descriptor? */ + /* Was this file opened for write access? */ - if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) + this_file = &list->fl_files[fd]; + if ((this_file->f_oflags & O_WROK) == 0) { - FAR struct file *this_file = &list->fl_files[fd]; - - /* Was this file opened for write access? */ + err = EBADF; + goto errout; + } - if ((this_file->f_oflags & O_WROK) != 0) - { - struct inode *inode = this_file->f_inode; + /* Is a driver registered? Does it support the write method? */ - /* Is a driver registered? Does it support the write method? */ + inode = this_file->f_inode; + if (!inode || !inode->u.i_ops && inode->u.i_ops->write) + { + err = EBADF; + goto errout; + } - if (inode && inode->u.i_ops && inode->u.i_ops->write) - { - /* Yes, then let it perform the write */ + /* Yes, then let the driver perform the write */ - ret = inode->u.i_ops->write(this_file, buf, nbytes); - } - } + ret = inode->u.i_ops->write(this_file, buf, nbytes); + if (ret < 0) + { + err = -ret; + goto errout; } + return ret; + +errout: + *get_errno_ptr() = err; + return ERROR; } |