Skip to content

Commit

Permalink
refactor fs to support #347
Browse files Browse the repository at this point in the history
  • Loading branch information
idealvin committed Nov 2, 2023
1 parent b0c2dfc commit a2d6a4d
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 67 deletions.
6 changes: 3 additions & 3 deletions include/co/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ __coapi bool mkdir(const char* path, bool p = false);
// async-signal-safe version
__coapi bool mkdir(char* path, bool p);

// rf = false -> rm or rmdir
// rf = true -> rm -rf
__coapi bool remove(const char* path, bool rf = false);
// r = false -> rm or rmdir
// r = true -> rm -r
__coapi bool remove(const char* path, bool r = false);

__coapi bool rename(const char* from, const char* to);

Expand Down
58 changes: 40 additions & 18 deletions src/fs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,57 @@ bool mkdir(char* path, bool p) {
*s = '/';
return ::mkdir(path, 0755) == 0;
} else {
bool x = fs::mkdir(path, true);
const bool x = fs::mkdir(path, true);
*s = '/';
return x ? ::mkdir(path, 0755) == 0 : false;
}
}

bool remove(const char* path, bool rf) {
if (!fs::exists(path)) return true;
inline bool is_dot_or_dotdot(const char* p) {
return p[0] == '.' && (!p[1] || (p[1] == '.' && !p[2]));
}

if (!rf) {
if (fs::isdir(path)) return ::rmdir(path) == 0;
return ::unlink(path) == 0;
} else {
fastring cmd(strlen(path) + 10);
cmd.append("rm -rf \"").append(path).append('"');
FILE* f = popen(cmd.c_str(), "w");
return f ? pclose(f) != -1 : false;
bool _rmdir(fastring& s) {
DIR* d = ::opendir(s.c_str());
if (!d) return errno == ENOENT;

const size_t n = s.size();
struct dirent* e;
while ((e = ::readdir(d))) {
if (is_dot_or_dotdot(e->d_name)) continue; // ignore . and ..
s.resize(n);
s.append('/').append(e->d_name);
if (fs::isdir(s.c_str())) {
if (!_rmdir(s)) goto err;
} else {
if (::unlink(s.c_str()) != 0 && errno != ENOENT) goto err;
}
}

::closedir(d);
s.resize(n);
return ::rmdir(s.c_str()) == 0;

err:
::closedir(d);
return false;
}

bool remove(const char* path, bool r) {
struct stat attr;
if (::lstat(path, &attr) != 0) return true; // not exists
if (!S_ISDIR(attr.st_mode)) return ::unlink(path) == 0;
if (!r) return ::rmdir(path) == 0;

fastring s(path);
return _rmdir(s);
}

bool rename(const char* from, const char* to) {
return ::rename(from, to) == 0;
}

bool symlink(const char* dst, const char* lnk) {
fs::remove(lnk);
return ::symlink(dst, lnk) == 0;
}

Expand Down Expand Up @@ -282,10 +307,7 @@ co::vector<fastring> dir::all() const {
co::vector<fastring> r(8);
while ((d->e = ::readdir(d->d))) {
char* const p = d->e->d_name;
// ignore . and ..
if (p[0] != '.' || (p[1] && (p[1] != '.' || p[2]))) {
r.push_back(p);
}
if (!is_dot_or_dotdot(p)) r.push_back(p);
}
return r;
}
Expand All @@ -301,7 +323,7 @@ dir::iterator& dir::iterator::operator++() {
assert(d->d);
while ((d->e = ::readdir(d->d))) {
char* const p = d->e->d_name;
if (p[0] != '.' || (p[1] && (p[1] != '.' || p[2]))) break;
if (!is_dot_or_dotdot(p)) break;
}
if (!d->e) _p = NULL;
}
Expand All @@ -313,7 +335,7 @@ dir::iterator dir::begin() const {
if (d && d->d) {
while ((d->e = ::readdir(d->d))) {
char* const p = d->e->d_name;
if (p[0] != '.' || (p[1] && (p[1] != '.' || p[2]))) break;
if (!is_dot_or_dotdot(p)) break;
}
if (d->e) return dir::iterator(_p);
}
Expand Down
Loading

0 comments on commit a2d6a4d

Please sign in to comment.