fs_write.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /****************************************************************************
  2. * fs/vfs/fs_write.c
  3. *
  4. * Copyright (C) 2007-2009, 2012-2014, 2016-2017 Gregory Nutt. All rights
  5. * reserved.
  6. * Author: Gregory Nutt <gnutt@nuttx.org>
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. * 3. Neither the name NuttX nor the names of its contributors may be
  19. * used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  29. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  30. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  32. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. ****************************************************************************/
  36. /****************************************************************************
  37. * Included Files
  38. ****************************************************************************/
  39. #include <nuttx/config.h>
  40. #include <sys/types.h>
  41. #include <unistd.h>
  42. #include <fcntl.h>
  43. #include <sched.h>
  44. #include <errno.h>
  45. #include <assert.h>
  46. #ifdef CONFIG_NET_TCP
  47. # include <sys/socket.h>
  48. #endif
  49. #include <nuttx/cancelpt.h>
  50. #include <nuttx/net/net.h>
  51. #include "inode/inode.h"
  52. /****************************************************************************
  53. * Public Functions
  54. ****************************************************************************/
  55. /****************************************************************************
  56. * Name: file_write
  57. *
  58. * Description:
  59. * Equivalent to the standard write() function except that is accepts a
  60. * struct file instance instead of a file descriptor. It is functionally
  61. * equivalent to write() except that in addition to the differences in
  62. * input paramters:
  63. *
  64. * - It does not modify the errno variable,
  65. * - It is not a cancellation point, and
  66. * - It does not handle socket descriptors.
  67. *
  68. * Input Parameters:
  69. * filep - Instance of struct file to use with the write
  70. * buf - Data to write
  71. * nbytes - Length of data to write
  72. *
  73. * Returned Value:
  74. * On success, the number of bytes written are returned (zero indicates
  75. * nothing was written). On any failure, a negated errno value is returned
  76. * (see comments withwrite() for a description of the appropriate errno
  77. * values).
  78. *
  79. ****************************************************************************/
  80. ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
  81. {
  82. FAR struct inode *inode;
  83. /* Was this file opened for write access? */
  84. if ((filep->f_oflags & O_WROK) == 0)
  85. {
  86. return -EBADF;
  87. }
  88. /* Is a driver registered? Does it support the write method? */
  89. inode = filep->f_inode;
  90. if (!inode || !inode->u.i_ops || !inode->u.i_ops->write)
  91. {
  92. return -EBADF;
  93. }
  94. /* Yes, then let the driver perform the write */
  95. return inode->u.i_ops->write(filep, buf, nbytes);
  96. }
  97. /****************************************************************************
  98. * Name: nx_write
  99. *
  100. * Description:
  101. * nx_write() writes up to nytes bytes to the file referenced by the file
  102. * descriptor fd from the buffer starting at buf. nx_write() is an
  103. * internal OS function. It is functionally equivalent to write() except
  104. * that:
  105. *
  106. * - It does not modify the errno variable, and
  107. * - It is not a cancellation point.
  108. *
  109. * Input Parameters:
  110. * fd - file descriptor (or socket descriptor) to write to
  111. * buf - Data to write
  112. * nbytes - Length of data to write
  113. *
  114. * Returned Value:
  115. * On success, the number of bytes written are returned (zero indicates
  116. * nothing was written). On any failure, a negated errno value is returned
  117. * (see comments withwrite() for a description of the appropriate errno
  118. * values).
  119. *
  120. ****************************************************************************/
  121. ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes)
  122. {
  123. FAR struct file *filep;
  124. ssize_t ret;
  125. if (buf == NULL)
  126. {
  127. return -EINVAL;
  128. }
  129. /* Did we get a valid file descriptor? */
  130. if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
  131. {
  132. #ifdef CONFIG_NET_TCP
  133. /* Write to a socket descriptor is equivalent to send with flags == 0. */
  134. ret = nx_send(fd, buf, nbytes, 0);
  135. #else
  136. ret = -EBADF;
  137. #endif
  138. }
  139. else
  140. {
  141. /* The descriptor is in the right range to be a file descriptor..
  142. * write to the file. Note that fs_getfilep() will set the errno on
  143. * failure.
  144. */
  145. ret = (ssize_t)fs_getfilep(fd, &filep);
  146. if (ret >= 0)
  147. {
  148. /* Perform the write operation using the file descriptor as an
  149. * index. Note that file_write() will set the errno on failure.
  150. */
  151. ret = file_write(filep, buf, nbytes);
  152. }
  153. }
  154. return ret;
  155. }
  156. /****************************************************************************
  157. * Name: write
  158. *
  159. * Description:
  160. * write() writes up to nytes bytes to the file referenced by the file
  161. * descriptor fd from the buffer starting at buf.
  162. *
  163. * Input Parameters:
  164. * fd - file descriptor (or socket descriptor) to write to
  165. * buf - Data to write
  166. * nbytes - Length of data to write
  167. *
  168. * Returned Value:
  169. * On success, the number of bytes written are returned (zero indicates
  170. * nothing was written). On error, -1 is returned, and errno is set appro-
  171. * priately:
  172. *
  173. * EAGAIN
  174. * Non-blocking I/O has been selected using O_NONBLOCK and the write
  175. * would block.
  176. * EBADF
  177. * fd is not a valid file descriptor or is not open for writing.
  178. * EFAULT
  179. * buf is outside your accessible address space.
  180. * EFBIG
  181. * An attempt was made to write a file that exceeds the implementation
  182. * defined maximum file size or the process' file size limit, or
  183. * to write at a position past the maximum allowed offset.
  184. * EINTR
  185. * The call was interrupted by a signal before any data was written.
  186. * EINVAL
  187. * fd is attached to an object which is unsuitable for writing; or
  188. * the file was opened with the O_DIRECT flag, and either the address
  189. * specified in buf, the value specified in count, or the current
  190. * file offset is not suitably aligned.
  191. * EIO
  192. * A low-level I/O error occurred while modifying the inode.
  193. * ENOSPC
  194. * The device containing the file referred to by fd has no room for
  195. * the data.
  196. * EPIPE
  197. * fd is connected to a pipe or socket whose reading end is closed.
  198. * When this happens the writing process will also receive a SIGPIPE
  199. * signal. (Thus, the write return value is seen only if the program
  200. * catches, blocks or ignores this signal.)
  201. *
  202. ****************************************************************************/
  203. ssize_t write(int fd, FAR const void *buf, size_t nbytes)
  204. {
  205. ssize_t ret;
  206. /* write() is a cancellation point */
  207. (void)enter_cancellation_point();
  208. /* Let nx_write() do all of the work */
  209. ret = nx_write(fd, buf, nbytes);
  210. if (ret < 0)
  211. {
  212. set_errno(-ret);
  213. ret = ERROR;
  214. }
  215. leave_cancellation_point();
  216. return ret;
  217. }