]> git.tdb.fi Git - libs/core.git/blob - source/fs/unix/utils.cpp
a960b4051d3e59e283137b7490be2517ccdb6113
[libs/core.git] / source / fs / unix / utils.cpp
1 #include <cstdio>
2 #include <deque>
3 #include <unistd.h>
4 #include <msp/core/systemerror.h>
5 #include "dir.h"
6 #include "stat.h"
7 #include "utils.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace FS {
13
14 Path readlink(const Path &link)
15 {
16         char buf[4096];
17         int len = ::readlink(link.c_str(), buf, sizeof(buf));
18         if(len==-1)
19                 throw system_error("readlink");
20         return string(buf, len);
21 }
22
23 Path realpath(const Path &path)
24 {
25         deque<string> queue(path.begin(), path.end());
26         if(!path.is_absolute())
27         {
28                 Path cwd = getcwd();
29                 queue.insert(queue.begin(), cwd.begin(), cwd.end());
30         }
31
32         Path real;
33         unsigned n_links = 0;
34         while(!queue.empty())
35         {
36                 Path next = real/queue.front();
37                 queue.pop_front();
38
39                 if(is_link(next))
40                 {
41                         if(++n_links>64)
42                                 throw runtime_error("too many symbolic links");
43                         Path link = readlink(next);
44                         queue.insert(queue.begin(), link.begin(), link.end());
45                 }
46                 else
47                         real = next;
48         }
49
50         return real;
51 }
52
53 void rename(const Path &from, const Path &to)
54 {
55         if(::rename(from.c_str(), to.c_str())==-1)
56                 throw system_error("rename");
57 }
58
59 void unlink(const Path &path)
60 {
61         if(::unlink(path.c_str())==-1)
62                 throw system_error("unlink");
63 }
64
65 } // namespace FS
66 } // namespace Msp