• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/vfs/fs_rmdir.c
3  *
4  *   Copyright (C) 2007-2009, 2014, 2017 Gregory Nutt. All rights reserved.
5  *   Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name NuttX nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ****************************************************************************/
35 
36 /****************************************************************************
37  * Included Files
38  ****************************************************************************/
39 
40 #include "vfs_config.h"
41 
42 #include "unistd.h"
43 #include "errno.h"
44 #include "stdlib.h"
45 #include "vnode.h"
46 #include "sys/stat.h"
47 #include "string.h"
48 #include "limits.h"
49 #include "fs/mount.h"
50 
51 /****************************************************************************
52  * Private Functions
53  ****************************************************************************/
check_target(struct Vnode * vnode,char * name)54 static int check_target(struct Vnode *vnode, char *name)
55 {
56   if (vnode == NULL)
57     {
58       return -ENOENT;
59     }
60 
61   if ((vnode->originMount) && (vnode->originMount->mountFlags & MS_RDONLY))
62     {
63       return -EROFS;
64     }
65 
66   if (vnode->type != VNODE_TYPE_DIR)
67     {
68       return -ENOTDIR;
69     }
70 
71   if (vnode->useCount > 0)
72     {
73       return -EBUSY;
74     }
75 
76   if ((vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)
77       || (vnode->flag & VNODE_FLAG_MOUNT_NEW))
78     {
79       return -EBUSY;
80     }
81 
82   char cwd[PATH_MAX];
83   char *pret = getcwd(cwd, PATH_MAX);
84   if (pret != NULL)
85     {
86       struct Vnode *cwdnode = NULL;
87       int ret = VnodeLookup(cwd, &cwdnode, 0);
88       if (ret == OK && (cwdnode == vnode))
89         {
90           return -EBUSY;
91         }
92     }
93   return OK;
94 }
95 /****************************************************************************
96  * Public Functions
97  ****************************************************************************/
98 
99 /****************************************************************************
100  * Name: do_rmdir
101  *
102  * Description:  Remove a file managed a mountpoint
103  *
104  ****************************************************************************/
105 
do_rmdir(int dirfd,const char * pathname)106 int do_rmdir(int dirfd, const char *pathname)
107 {
108   struct Vnode *vnode = NULL;
109   char             *fullpath     = NULL;
110   char             *relativepath = NULL;
111   char             *name         = NULL;
112   int               ret;
113 
114   if (pathname == NULL)
115     {
116       ret = -EINVAL;
117       goto errout;
118     }
119 
120   /* Get relative path by dirfd*/
121   ret = get_path_from_fd(dirfd, &relativepath);
122   if (ret < 0)
123     {
124       goto errout;
125     }
126 
127   if (relativepath)
128     {
129       ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
130       free(relativepath);
131       if (ret < 0)
132         {
133           goto errout;
134         }
135 
136       name = strrchr(fullpath, '/');
137       VnodeHold();
138       ret = VnodeLookup(fullpath, &vnode, 0);
139     }
140   else
141     {
142       name = strrchr(pathname, '/');
143       VnodeHold();
144       if (name == NULL)
145         {
146           name = (char *)pathname;
147         }
148       else
149         {
150           name++;
151         }
152       ret = VnodeLookup(pathname, &vnode, 0);
153     }
154 
155   if (ret != OK)
156     {
157       goto errout_with_lock;
158     }
159 
160   ret = check_target(vnode, name);
161   if (ret != OK) {
162       PRINT_ERR("rmdir failed err = %d\n", ret);
163       goto errout_with_lock;
164   }
165 
166   if (VfsVnodePermissionCheck(vnode->parent, (WRITE_OP | EXEC_OP))) {
167       ret = -EACCES;
168       goto errout_with_lock;
169   }
170 
171   if (vnode && vnode->vop && vnode->vop->Rmdir) {
172       ret = vnode->vop->Rmdir(vnode->parent, vnode, name);
173   } else {
174       ret = -ENOSYS;
175   }
176   if (ret < 0) {
177       goto errout_with_lock;
178   }
179   VnodeFree(vnode);
180   VnodeDrop();
181 
182   /* Successfully unlinked */
183   if (fullpath)
184     {
185       free(fullpath);
186     }
187 
188   return OK;
189 
190 errout_with_lock:
191   VnodeDrop();
192 
193 errout:
194   if (fullpath)
195     {
196       free(fullpath);
197     }
198 
199   set_errno(-ret);
200   return VFS_ERROR;
201 }
202 
203 /****************************************************************************
204  * Name: rmdir
205  *
206  * Description:  Remove a file managed a mountpoint
207  *
208  ****************************************************************************/
209 
rmdir(const char * pathname)210 int rmdir(const char *pathname)
211 {
212   return do_rmdir(AT_FDCWD, pathname);
213 }
214