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 /**************************************************************************** 22 * Included Files 23 ****************************************************************************/ 24 25 #include "vfs_config.h" 26 #include "dirent.h" 27 #include "errno.h" 28 #include "stdlib.h" 29 #include "fs/dirent_fs.h" 30 #include "vnode.h" 31 32 /**************************************************************************** 33 * Public Functions 34 ****************************************************************************/ 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 closedir(DIR * dirp)53int closedir(DIR *dirp) 54 { 55 struct fs_dirent_s *idir = (struct fs_dirent_s *)dirp; 56 struct Vnode *vnode = NULL; 57 int ret; 58 59 /* Verify that we were provided with a valid directory structure */ 60 61 if (!idir || idir->fd_status != DIRENT_MAGIC) 62 { 63 ret = -EBADF; 64 goto errout; 65 } 66 67 if (idir->fd_root) 68 { 69 /* This is the 'root' vnode of the directory. This means different 70 * things wih different filesystems. 71 */ 72 vnode = idir->fd_root; 73 /* Perform the closedir() operation */ 74 if (vnode->vop && vnode->vop->Closedir) 75 { 76 ret = vnode->vop->Closedir(vnode, idir); 77 if (ret < 0) 78 { 79 goto errout_with_vnode; 80 } 81 } 82 else 83 { 84 ret = -ENOSYS; 85 goto errout_with_vnode; 86 } 87 VnodeHold(); 88 vnode->useCount--; 89 VnodeDrop(); 90 } 91 92 /* Then release the container */ 93 94 idir->fd_status = 0; 95 free(idir); 96 97 return OK; 98 99 errout_with_vnode: 100 free(idir); 101 102 errout: 103 set_errno(-ret); 104 return VFS_ERROR; 105 } 106