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