我在 Mac OSX 10.6.6 和 XCode 3.2.4 上运行一些代码,并且我有一些非常标准的代码:fork(), if pid == 0 then execvp with a command and the args (args include the command as the数组中的第一个元素,并且数组以 null 结尾)。
我们将在我的操作系统课上讨论这个问题,我们的任务是编写一个简单的 shell。运行带有参数和开关的命令,包括重定向(< 和 >)和管道(|)。我遇到了几个问题。
1)有时我在调试时收到 EXC_SOFTWARE 信号(到目前为止,如果我在 XCode 之外运行应用程序,我还没有收到它,但我是 Mac 新手,不知道如果我这样做会是什么样子)
2) 有时,下一个命令的 getline 会变成垃圾,似乎是由其他 couts 打印的。这开始永远循环,呈指数级中断。我已经测试过在每个提示符下打印 getpid() 并且只有开始过程会打印出这些,我似乎没有意外的“叉子炸弹”。
这是我到目前为止所拥有的:
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
char** Split(char* buffer, int &count) {
count = 1;
for (int i = 0; i < strlen(buffer); i++) {
if (buffer[i] == ' ') {
count++;
}
}
const char* delim = " ";
char* t = strtok(buffer, delim);
char** args = new char*[count + 1];
for (int i = 0; i < count; i++) {
args[i] = t;
t = strtok(NULL, delim);
}
args[count] = 0;
return args;
}
void Run(char** argv, int argc) {
int pid = 0;
if ((pid = fork()) == 0) {
//for testing purposes, print all of argv
for (int i = 0; i < argc; i++) {
cout << "{" << argv[i] << "}" << endl;
}
execvp(argv[0], argv);
cout << "ERROR 1" << endl;
exit(1);
} else if (pid < 0) {
cout << "ERROR 2" << endl;
exit(2);
}
wait(NULL);
}
int main(int argc, char * const argv[]) {
char buffer[512];
char prompt[] = ":> ";
int count = 0;
while (true) {
cout << prompt;
cin.getline(buffer, 512);
char **split = Split(buffer, count);
Run(split, count);
}
}
这正是我所拥有的,您应该能够剪切、粘贴和构建。
我在 C++ 方面不是最好的,当我不删除时可能会出现内存泄漏,split
但我的主要关注点是 EXC_SOFTWARE 信号,看看我在循环问题上做错了什么。有什么想法吗?
编辑:
分配需要非常有限的错误检查,我假设所有输入都是正确的。正确我的意思是正确格式化和限制我的应用程序运行命令,即没有奇怪的空间计数,没有 & 运行异步,没有多管道命令等。