-
Notifications
You must be signed in to change notification settings - Fork 37
/
fs.cc
90 lines (83 loc) · 2.21 KB
/
fs.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "libpstack/global.h"
#include "libpstack/fs.h"
#include "libpstack/exception.h"
namespace pstack {
std::vector<std::pair<std::string,std::string>> pathReplacements;
std::string
dirname(const std::string &in)
{
auto it = in.rfind('/');
if (it == std::string::npos)
return ".";
return in.substr(0, it);
}
std::string
basename(const std::string &in)
{
auto it = in.rfind('/');
auto out = it == std::string::npos ? in : in.substr(it + 1);
return out;
}
std::string
linkResolve(std::string name)
{
char buf[1024];
std::string orig = name;
int rc;
for (;;) {
rc = readlink(name.c_str(), buf, sizeof buf - 1);
// some files in /proc are links, but report "(deleted)" in the name if
// the original has gone away. Opening such files works, and uses the
// in-core inode, so use that if we can
if (rc == -1) {
return errno == EINVAL ? name : orig;
}
buf[rc] = 0;
if (buf[0] != '/') {
auto lastSlash = name.rfind('/');
name = lastSlash == std::string::npos
? std::string(buf)
: name.substr(0, lastSlash + 1) + std::string(buf);
} else {
name = buf;
}
}
return name;
}
namespace {
int
openFileDirect(const std::string &name_, int mode, int mask)
{
auto fd = ::open(name_.c_str(), mode, mask);
if (verbose > 2) {
if (fd != -1)
*debug << "opened " << name_ << ", fd=" << fd << "\n";
else
*debug << "failed to open " << name_ << ": " << strerror(errno) << "\n";
}
return fd;
}
}
int
openfile(const std::string &name, int mode, int mask)
{
int fd = -1;
for (auto &r : pathReplacements) {
if (name.compare(0, r.first.size(), r.first) == 0) {
fd = openFileDirect(r.second + std::string(name, r.first.size()), mode, mask);
if (fd != -1)
return fd;
}
}
fd = openFileDirect(name, mode, mask);
if (fd != -1)
return fd;
throw (Exception() << "cannot open file '" << name << "': " << strerror(errno));
}
}