4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
26 #include <sys/types.h>
29 #include "utils-dir.h"
31 static int clean_dirfd(int dirfd)
41 dir = fdopendir(dirfd);
48 if (readdir_r(dir, &entry.entry, &ent) != 0)
52 if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
53 || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
55 rc = unlinkat(dirfd, ent->d_name, 0);
60 rc = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
66 rc = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
76 /* removes recursively the content of a directory */
77 int remove_directory_content_fd(int dirfd)
80 return dirfd < 0 ? dirfd : clean_dirfd(dirfd);
83 /* removes recursively the content of a directory */
84 int remove_directory_content_at(int dirfd, const char *directory)
88 fd = openat(dirfd, directory, O_DIRECTORY|O_RDONLY);
91 rc = remove_directory_content_fd(fd);
96 int remove_directory_content(const char *directory)
98 return remove_directory_content_at(AT_FDCWD, directory);
101 /* removes the working directory */
102 int remove_directory(const char *directory, int force)
105 rc = force ? remove_directory_content(directory) : 0;
106 return rc ? rc : rmdir(directory);
109 int remove_directory_at(int dirfd, const char *directory, int force)
112 rc = force ? remove_directory_content_at(dirfd, directory) : 0;
113 return rc ? rc : unlinkat(dirfd, directory, AT_REMOVEDIR);
116 /* create a directory */
117 int create_directory_at(int dirfd, const char *directory, mode_t mode, int mkparents)
124 rc = mkdirat(dirfd, directory, mode);
125 if (!rc || errno != ENOENT)
128 /* check parent of dest */
129 iter = strrchr(directory, '/');
130 len = iter ? (size_t)(iter - directory) : 0;
133 copy = strndupa(directory, len);
137 rc = mkdirat(dirfd, copy, mode);
141 while (l && copy[l] != '/')
146 rc = mkdirat(dirfd, copy, mode);
152 rc = mkdirat(dirfd, copy, mode);
158 return mkdirat(dirfd, directory, mode);
161 int create_directory(const char *directory, mode_t mode, int mkparents)
163 return create_directory_at(AT_FDCWD, directory, mode, mkparents);