2 Copyright 2015, 2016, 2017 IoT.bzh
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)
37 dir = fdopendir(dirfd);
51 if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
52 || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
54 rc = unlinkat(dirfd, ent->d_name, 0);
59 rc = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
65 rc = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
75 /* removes recursively the content of a directory */
76 int remove_directory_content_fd(int dirfd)
79 return dirfd < 0 ? dirfd : clean_dirfd(dirfd);
82 /* removes recursively the content of a directory */
83 int remove_directory_content_at(int dirfd, const char *directory)
87 fd = openat(dirfd, directory, O_DIRECTORY|O_RDONLY);
90 rc = remove_directory_content_fd(fd);
95 int remove_directory_content(const char *directory)
97 return remove_directory_content_at(AT_FDCWD, directory);
100 /* removes the working directory */
101 int remove_directory(const char *directory, int force)
104 rc = force ? remove_directory_content(directory) : 0;
105 return rc ? rc : rmdir(directory);
108 int remove_directory_at(int dirfd, const char *directory, int force)
111 rc = force ? remove_directory_content_at(dirfd, directory) : 0;
112 return rc ? rc : unlinkat(dirfd, directory, AT_REMOVEDIR);
115 /* create a directory */
116 int create_directory_at(int dirfd, const char *directory, mode_t mode, int mkparents)
123 rc = mkdirat(dirfd, directory, mode);
124 if (!rc || errno != ENOENT)
127 /* check parent of dest */
128 iter = strrchr(directory, '/');
129 len = iter ? (size_t)(iter - directory) : 0;
132 copy = strndupa(directory, len);
136 rc = mkdirat(dirfd, copy, mode);
140 while (l && copy[l] != '/')
145 rc = mkdirat(dirfd, copy, mode);
151 rc = mkdirat(dirfd, copy, mode);
157 return mkdirat(dirfd, directory, mode);
160 int create_directory(const char *directory, mode_t mode, int mkparents)
162 return create_directory_at(AT_FDCWD, directory, mode, mkparents);