1beacf11bSopenharmony_ci/****************************************************************************
2beacf11bSopenharmony_ci * fs/dirent/fs_closedir.c
3beacf11bSopenharmony_ci *
4beacf11bSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved.
5beacf11bSopenharmony_ci * Based on NuttX originally from nuttx source (nuttx/fs/ and nuttx/drivers/)
6beacf11bSopenharmony_ci *
7beacf11bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8beacf11bSopenharmony_ci * you may not use this file except in compliance with the License.
9beacf11bSopenharmony_ci * You may obtain a copy of the License at
10beacf11bSopenharmony_ci *
11beacf11bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
12beacf11bSopenharmony_ci *
13beacf11bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14beacf11bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15beacf11bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16beacf11bSopenharmony_ci * See the License for the specific language governing permissions and
17beacf11bSopenharmony_ci * limitations under the License.
18beacf11bSopenharmony_ci *
19beacf11bSopenharmony_ci ****************************************************************************/
20beacf11bSopenharmony_ci
21beacf11bSopenharmony_ci/****************************************************************************
22beacf11bSopenharmony_ci * Included Files
23beacf11bSopenharmony_ci ****************************************************************************/
24beacf11bSopenharmony_ci
25beacf11bSopenharmony_ci#include "vfs_config.h"
26beacf11bSopenharmony_ci#include "dirent.h"
27beacf11bSopenharmony_ci#include "errno.h"
28beacf11bSopenharmony_ci#include "stdlib.h"
29beacf11bSopenharmony_ci#include "fs/dirent_fs.h"
30beacf11bSopenharmony_ci#include "vnode.h"
31beacf11bSopenharmony_ci
32beacf11bSopenharmony_ci/****************************************************************************
33beacf11bSopenharmony_ci * Public Functions
34beacf11bSopenharmony_ci ****************************************************************************/
35beacf11bSopenharmony_ci
36beacf11bSopenharmony_ci/****************************************************************************
37beacf11bSopenharmony_ci * Name: closedir
38beacf11bSopenharmony_ci *
39beacf11bSopenharmony_ci * Description:
40beacf11bSopenharmony_ci *    The closedir() function closes the directory stream associated with
41beacf11bSopenharmony_ci *    'dirp'.  The directory stream descriptor 'dirp' is not available after
42beacf11bSopenharmony_ci *    this call.
43beacf11bSopenharmony_ci *
44beacf11bSopenharmony_ci * Input Parameters:
45beacf11bSopenharmony_ci *   dirp -- An instance of type DIR created by a previous call to opendir();
46beacf11bSopenharmony_ci *
47beacf11bSopenharmony_ci * Returned Value:
48beacf11bSopenharmony_ci *   The closedir() function returns 0 on success.  On error, -1 is
49beacf11bSopenharmony_ci *   returned, and errno is set appropriately.
50beacf11bSopenharmony_ci *
51beacf11bSopenharmony_ci ****************************************************************************/
52beacf11bSopenharmony_ci
53beacf11bSopenharmony_ciint closedir(DIR *dirp)
54beacf11bSopenharmony_ci{
55beacf11bSopenharmony_ci  struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp;
56beacf11bSopenharmony_ci  struct Vnode *vnode = NULL;
57beacf11bSopenharmony_ci  int ret;
58beacf11bSopenharmony_ci
59beacf11bSopenharmony_ci  /* Verify that we were provided with a valid directory structure */
60beacf11bSopenharmony_ci
61beacf11bSopenharmony_ci  if (!idir || idir->fd_status != DIRENT_MAGIC)
62beacf11bSopenharmony_ci    {
63beacf11bSopenharmony_ci      ret = -EBADF;
64beacf11bSopenharmony_ci      goto errout;
65beacf11bSopenharmony_ci    }
66beacf11bSopenharmony_ci
67beacf11bSopenharmony_ci  if (idir->fd_root)
68beacf11bSopenharmony_ci    {
69beacf11bSopenharmony_ci      /* This is the 'root' vnode of the directory.  This means different
70beacf11bSopenharmony_ci       * things wih different filesystems.
71beacf11bSopenharmony_ci       */
72beacf11bSopenharmony_ci      vnode = idir->fd_root;
73beacf11bSopenharmony_ci      /* Perform the closedir() operation */
74beacf11bSopenharmony_ci      if (vnode->vop && vnode->vop->Closedir)
75beacf11bSopenharmony_ci        {
76beacf11bSopenharmony_ci          ret = vnode->vop->Closedir(vnode, idir);
77beacf11bSopenharmony_ci          if (ret < 0)
78beacf11bSopenharmony_ci            {
79beacf11bSopenharmony_ci              goto errout_with_vnode;
80beacf11bSopenharmony_ci            }
81beacf11bSopenharmony_ci        }
82beacf11bSopenharmony_ci      else
83beacf11bSopenharmony_ci        {
84beacf11bSopenharmony_ci          ret = -ENOSYS;
85beacf11bSopenharmony_ci          goto errout_with_vnode;
86beacf11bSopenharmony_ci        }
87beacf11bSopenharmony_ci      VnodeHold();
88beacf11bSopenharmony_ci      vnode->useCount--;
89beacf11bSopenharmony_ci      VnodeDrop();
90beacf11bSopenharmony_ci    }
91beacf11bSopenharmony_ci
92beacf11bSopenharmony_ci  /* Then release the container */
93beacf11bSopenharmony_ci
94beacf11bSopenharmony_ci  idir->fd_status = 0;
95beacf11bSopenharmony_ci  free(idir);
96beacf11bSopenharmony_ci
97beacf11bSopenharmony_ci  return OK;
98beacf11bSopenharmony_ci
99beacf11bSopenharmony_cierrout_with_vnode:
100beacf11bSopenharmony_ci  free(idir);
101beacf11bSopenharmony_ci
102beacf11bSopenharmony_cierrout:
103beacf11bSopenharmony_ci  set_errno(-ret);
104beacf11bSopenharmony_ci  return VFS_ERROR;
105beacf11bSopenharmony_ci}
106