X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Ffs%2Funix%2Futils.cpp;fp=source%2Ffs%2Funix%2Futils.cpp;h=c832343f76e822bacf4184ddc11379f750ee950d;hb=609c9a508cfdc7b42c46c4f21d17639204165a00;hp=0000000000000000000000000000000000000000;hpb=b4806214e905752617691f851717033fd3f266c2;p=libs%2Fcore.git diff --git a/source/fs/unix/utils.cpp b/source/fs/unix/utils.cpp new file mode 100644 index 0000000..c832343 --- /dev/null +++ b/source/fs/unix/utils.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include "dir.h" +#include "stat.h" +#include "utils.h" + +using namespace std; + +namespace Msp { +namespace FS { + +Path readlink(const Path &link) +{ + char buf[4096]; + int len = ::readlink(link.c_str(), buf, sizeof(buf)); + if(len==-1) + throw system_error("readlink"); + return string(buf, len); +} + +Path realpath(const Path &path) +{ + list queue(path.begin(), path.end()); + if(!path.is_absolute()) + { + Path cwd = getcwd(); + queue.insert(queue.begin(), cwd.begin(), cwd.end()); + } + + Path real; + unsigned n_links = 0; + while(!queue.empty()) + { + Path next = real/queue.front(); + queue.pop_front(); + + if(is_link(next)) + { + if(++n_links>64) + throw runtime_error("too many symbolic links"); + Path link = readlink(next); + queue.insert(queue.begin(), link.begin(), link.end()); + } + else + real = next; + } + + return real; +} + +void rename(const Path &from, const Path &to) +{ + if(::rename(from.c_str(), to.c_str())==-1) + throw system_error("rename"); +} + +void unlink(const Path &path) +{ + if(::unlink(path.c_str())==-1) + throw system_error("unlink"); +} + +} // namespace FS +} // namespace Msp