1 #include "filesystem.h"
2 
3 #include <dirent.h>
4 #include <log/log.h>
5 #include <stdlib.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 
9 #include <sstream>
10 #include <string>
11 #include <vector>
12 
13 namespace filesystem {
14 
exists(const path & p)15 bool exists(const path& p) {
16     struct stat s;
17     return stat(p.string().c_str(), &s) == 0;
18 }
19 
is_directory(const path & p)20 bool is_directory(const path& p) {
21     struct stat s;
22     if (stat(p.string().c_str(), &s))
23         return false;
24 
25     return S_ISDIR(s.st_mode);
26 }
27 
is_symlink(const path & p)28 bool is_symlink(const path& p) {
29     struct stat s;
30     if (lstat(p.string().c_str(), &s))
31         return false;
32 
33     return S_ISLNK(s.st_mode);
34 }
35 
read_symlink(const path & p)36 path read_symlink(const path& p) {
37     char* actualPath = realpath(p.string().c_str(), NULL);
38     if (!actualPath) {
39         return path(p.string());
40     }
41 
42     path out(actualPath);
43     free(actualPath);
44     return out;
45 }
46 
directory_iterator(const path & p)47 std::vector<directory_entry> directory_iterator(const path& p) {
48     if (!exists(p) || !is_directory(p))
49         return {};
50 
51     std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(p.string().c_str()), &closedir);
52     if (!dir) {
53         ALOGE("Failed to open %s directory", p.string().c_str());
54     }
55 
56     std::vector<directory_entry> out;
57     struct dirent* dent;
58     while ((dent = readdir(dir.get()))) {
59         if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
60             continue;
61 
62         std::stringstream ss(p.string());
63         ss << "/" << dent->d_name;
64         out.emplace_back(ss.str());
65     }
66 
67     return out;
68 }
69 
70 } // namespace filesystem
71