fs_closedir.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /****************************************************************************
  2. * fs/dirent/fs_closedir.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <dirent.h>
  25. #include <errno.h>
  26. #include <nuttx/kmalloc.h>
  27. #include <nuttx/fs/fs.h>
  28. #include <nuttx/fs/dirent.h>
  29. #include "inode/inode.h"
  30. /****************************************************************************
  31. * Private Functions
  32. ****************************************************************************/
  33. /****************************************************************************
  34. * Public Functions
  35. ****************************************************************************/
  36. /****************************************************************************
  37. * Name: closedir
  38. *
  39. * Description:
  40. * The closedir() function closes the directory stream associated with
  41. * 'dirp'. The directory stream descriptor 'dirp' is not available after
  42. * this call.
  43. *
  44. * Input Parameters:
  45. * dirp -- An instance of type DIR created by a previous call to opendir();
  46. *
  47. * Returned Value:
  48. * The closedir() function returns 0 on success. On error, -1 is
  49. * returned, and errno is set appropriately.
  50. *
  51. ****************************************************************************/
  52. int closedir(FAR DIR *dirp)
  53. {
  54. struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
  55. #ifndef CONFIG_DISABLE_MOUNTPOINT
  56. struct inode *inode;
  57. #endif
  58. int ret;
  59. /* Verify that we were provided with a valid directory structure */
  60. if (!idir)
  61. {
  62. ret = EBADF;
  63. goto errout;
  64. }
  65. /* A special case is when we enumerate an "empty", unused inode.
  66. * That is an inode in the pseudo-filesystem that has no operations
  67. * and no children.
  68. * This is a "dangling" directory entry that has lost its childre.
  69. */
  70. if (idir->fd_root)
  71. {
  72. /* This is the 'root' inode of the directory. This means different
  73. * things with different filesystems.
  74. */
  75. #ifndef CONFIG_DISABLE_MOUNTPOINT
  76. inode = idir->fd_root;
  77. /* The way that we handle the close operation depends on what kind of
  78. * root inode we have open.
  79. */
  80. if (INODE_IS_MOUNTPT(inode) && !DIRENT_ISPSEUDONODE(idir->fd_flags))
  81. {
  82. /* The node is a file system mointpoint. Verify that the
  83. * mountpoint supports the closedir() method (not an error if it
  84. * does not)
  85. */
  86. if (inode->u.i_mops && inode->u.i_mops->closedir)
  87. {
  88. /* Perform the closedir() operation */
  89. ret = inode->u.i_mops->closedir(inode, idir);
  90. if (ret < 0)
  91. {
  92. ret = -ret;
  93. goto errout_with_inode;
  94. }
  95. }
  96. }
  97. else
  98. #endif
  99. {
  100. /* The node is part of the root pseudo file system, release
  101. * our contained reference to the 'next' inode.
  102. */
  103. if (idir->u.pseudo.fd_next)
  104. {
  105. inode_release(idir->u.pseudo.fd_next);
  106. }
  107. }
  108. /* Release our references on the contained 'root' inode */
  109. inode_release(idir->fd_root);
  110. }
  111. /* Then release the container */
  112. kumm_free(idir);
  113. return OK;
  114. #ifndef CONFIG_DISABLE_MOUNTPOINT
  115. errout_with_inode:
  116. inode_release(inode);
  117. kumm_free(idir);
  118. #endif
  119. errout:
  120. set_errno(ret);
  121. return ERROR;
  122. }