-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
130 lines (112 loc) · 4.04 KB
/
main.cpp
File metadata and controls
130 lines (112 loc) · 4.04 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
124
125
126
127
128
129
130
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>
#include <algorithm>
class RunHelper {
public:
static void showHelp() {
std::cout << "\033[1mRun Helper - 程序启动器\033[0m\n\n";
std::cout << "用法: run <程序名> [参数...]\n\n";
std::cout << "功能:\n";
std::cout << " 自动为相对路径的程序添加 './' 前缀\n";
std::cout << " 简化手机SSH输入,无需输入 './' 或 '/'\n\n";
std::cout << "示例:\n";
std::cout << " run a.sh # 执行 ./a.sh\n";
std::cout << " run ../script.sh # 执行 ../script.sh\n";
std::cout << " run script arg1 arg2 # 执行 ./script 带参数\n";
std::cout << " run /bin/ls -la # 执行绝对路径程序\n\n";
std::cout << "提示: 程序需要具有执行权限 (chmod +x)\n";
}
static std::string fixPath(const std::string& path) {
// 如果是绝对路径,直接返回
if (!path.empty() && path[0] == '/') {
return path;
}
// 如果已经是相对路径(以 ./ 或 ../ 开头),直接返回
if (path.find("./") == 0 || path.find("../") == 0) {
return path;
}
// 否则是当前目录下的文件,添加 ./
return "./" + path;
}
static bool checkExecutable(const std::string& path) {
return access(path.c_str(), X_OK) == 0;
}
static int execute(const std::vector<std::string>& args) {
// 转换为C风格字符串数组
std::vector<char*> c_args;
for (const auto& arg : args) {
c_args.push_back(strdup(arg.c_str()));
}
c_args.push_back(nullptr);
// fork并执行
pid_t pid = fork();
if (pid == 0) {
// 子进程
execv(c_args[0], c_args.data());
// exec失败时的错误信息
std::cerr << "错误: 无法执行程序 '" << c_args[0] << "'\n";
// 根据错误码提供更详细的提示
if (errno == ENOENT) {
std::cerr << "原因: 文件不存在\n";
} else if (errno == EACCES) {
std::cerr << "原因: 没有执行权限 (使用 chmod +x)\n";
} else {
std::cerr << "原因: 系统错误码 " << errno << "\n";
}
// 清理内存
for (auto ptr : c_args) {
if (ptr) free(ptr);
}
exit(127);
} else if (pid > 0) {
// 父进程
int status;
waitpid(pid, &status, 0);
// 清理内存
for (auto ptr : c_args) {
if (ptr) free(ptr);
}
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
return -1;
} else {
std::cerr << "错误: 创建进程失败\n";
for (auto ptr : c_args) {
if (ptr) free(ptr);
}
return 1;
}
}
};
int main(int argc, char* argv[]) {
if (argc < 2) {
RunHelper::showHelp();
return 0;
}
// 处理第一个参数(程序路径)
std::string program = RunHelper::fixPath(argv[1]);
// 检查是否可执行
if (!RunHelper::checkExecutable(program)) {
std::cerr << "错误: '" << program << "' 不可执行或不存在\n";
std::cerr << "请确认:\n";
std::cerr << " 1. 文件存在 (ls -la " << program << ")\n";
std::cerr << " 2. 具有执行权限 (chmod +x " << program << ")\n";
std::cerr << " 3. 当前目录: ";
system("pwd");
return 1;
}
// 构建参数列表
std::vector<std::string> args;
args.push_back(program);
// 添加其他参数
for (int i = 2; i < argc; i++) {
args.push_back(argv[i]);
}
// 执行
return RunHelper::execute(args);
}