4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
24 #include <sys/types.h>
27 #include "utils-dir.h"
29 static int clean_dirfd(int dirfd)
39 dir = fdopendir(dirfd);
46 if (readdir_r(dir, &entry.entry, &ent) != 0)
50 if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
51 || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
53 rc = unlinkat(dirfd, ent->d_name, 0);
58 rc = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
64 rc = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
74 /* removes recursively the content of a directory */
75 int remove_directory_content_fd(int dirfd)
78 return dirfd < 0 ? dirfd : clean_dirfd(dirfd);
81 /* removes recursively the content of a directory */
82 int remove_directory_content_at(int dirfd, const char *directory)
86 fd = openat(dirfd, directory, O_DIRECTORY|O_RDONLY);
89 rc = remove_directory_content_fd(fd);
94 int remove_directory_content(const char *directory)
96 return remove_directory_content_at(AT_FDCWD, directory);
99 /* removes the working directory */
100 int remove_directory(const char *directory, int force)
103 rc = force ? remove_directory_content(directory) : 0;
104 return rc ? rc : rmdir(directory);
107 int remove_directory_at(int dirfd, const char *directory, int force)
110 rc = force ? remove_directory_content_at(dirfd, directory) : 0;
111 return rc ? rc : unlinkat(dirfd, directory, AT_REMOVEDIR);
114 /* create a directory */
115 int create_directory_at(int dirfd, const char *directory, int mode, int mkparents)
121 rc = mkdirat(dirfd, directory, mode);
122 if (!rc || errno != ENOENT)
125 /* check parent of dest */
126 iter = strrchr(directory, '/');
127 len = iter ? iter - directory : 0;
130 copy = strndupa(directory, len);
134 rc = mkdirat(dirfd, copy, mode);
138 while (l && copy[l] != '/')
143 rc = mkdirat(dirfd, copy, mode);
149 rc = mkdirat(dirfd, copy, mode);
155 return mkdirat(dirfd, directory, mode);
158 int create_directory(const char *directory, int mode, int mkparents)
160 return create_directory_at(AT_FDCWD, directory, mode, mkparents);