-
Notifications
You must be signed in to change notification settings - Fork 655
Expand file tree
/
Copy pathMvCommand.cc
More file actions
123 lines (101 loc) Β· 2.87 KB
/
MvCommand.cc
File metadata and controls
123 lines (101 loc) Β· 2.87 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#include <stdio.h>
#include <sysexits.h>
#include <vector>
#include "Command.h"
#include "TraceStream.h"
#include "main.h"
#include "util.h"
using namespace std;
namespace rr {
class MvCommand : public Command {
public:
virtual int run(vector<string>& args);
protected:
MvCommand(const char* name, const char* help) : Command(name, help) {}
static MvCommand singleton;
};
MvCommand MvCommand::singleton("mv", " rr mv <trace> <new-trace>\n");
static int mv(const string& from, const string& to, FILE* out) {
string reason;
if (!is_valid_trace_name(from, &reason) ||
!is_valid_trace_name(to, &reason)) {
fprintf(stderr,
"\n"
"rr: Trace name is invalid: %s\n"
"\n",
reason.c_str());
return 1;
}
string from_path = resolve_trace_name(from);
if (!is_trace(from_path)) {
fprintf(stderr,
"\n"
"rr: Could not access / identify '%s' as a trace (errno %d).\n"
"\n",
from_path.c_str(), errno);
return 1;
}
// resolve symlinks like latest_trace
from_path = real_path(from_path);
string to_path = to;
// if 'to' is not a path, view it as trace name and move to trace_dir/to
if (to.find("/") == string::npos) {
to_path = trace_save_dir() + "/" + to;
}
string to_fname = filename(to_path.c_str());
if (to_fname == "latest-trace") {
fprintf(stderr, "\nrr: Cannot rename to latest-trace.\n\n");
return 1;
}
if (access(to_path.c_str(), F_OK) == 0) {
fprintf(stderr,
"\n"
"rr: New trace '%s' already exists or cannot be accessed.\n"
"\n",
to_path.c_str());
return 1;
} else if (errno != ENOENT) {
fprintf(stderr,
"\n"
"rr: Cannot access new trace path '%s': errno %d\n"
"\n",
to_path.c_str(), errno);
return 1;
}
// remove symlink before removing trace in case the former fails
// a bad symlink crashes e.g. rr ls and midas
if (is_latest_trace(from_path)) {
if (!remove_latest_trace_symlink()) {
return 1;
}
}
int ret = rename(from_path.c_str(), to_path.c_str());
if (ret != 0) {
const string err = strerror(errno);
fprintf(stderr,
"\n"
"rr: Cannot move '%s' to '%s': %s\n"
"\n",
from_path.c_str(), to_path.c_str(), err.c_str());
return 1;
}
fprintf(out,
"rr: Moved '%s' to '%s'\n",
from_path.c_str(),
to_path.c_str());
return 0;
}
int MvCommand::run(vector<string>& args) {
if (args.size() == 2 && verify_not_option(args)) {
string from = args[0];
args.erase(args.begin());
if (verify_not_option(args)) {
string to = args[0];
return mv(from, to, stdout);
}
}
print_help(stderr);
return 1;
};
} // namespace rr