Mac OSX 10.6.6과 Xcode 3.2.4에서 몇 가지 코드를 실행 중입니다. 상당히 표준적인 코드가 있습니다. : pid == 0, execvp, args (args에 명령이 포함되어있는 경우) 배열의 첫 번째 요소로, 배열은 null로 끝납니다.EXC_SOFTWARE 및 기괴한 cin.getline 루프가 발생하는 execvp()?
내 운영 체제 클래스에서이 문제를 해결할 것이며 간단한 쉘을 작성하는 과제가 있습니다. args 및 스위치와 함께 명령을 실행하면 리디렉션 (< 및>)과 파이프 (|)가 모두 리디렉션됩니다. 몇 가지 문제가 있습니다.
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 신호이며 루핑 문제가 무엇인지 잘보아야합니다. 이견있는 사람?
편집 :
할당은 매우 제한적인 오류 검사를 필요로하고 내가 모든 입력이 올바른지 있으리라 믿고있어. 올바른 말은 올바른 형식의 응용 프로그램 및 명령을 실행하는 데 제한이 있다는 것입니다. 즉, 기괴한 공간 수가없고 & 비동기를 실행할 수 없으며 다중 파이프 명령이 없습니다.
EOF를 cin으로 넣을 수있는 것은 무엇입니까? 그게 내 문제의 뿌리라고 생각해. 난 당신의 코드를 시도하고 지금 루핑 대신 종료. 개인적으로 그것은 개선 하하입니다. 나는 "ls"와 "ls -l"을 따옴표없이 단지 (현재는) 테스트하고있다. 두 명령이 무엇인지에 관계없이 항상 두 번째 명령을 실행하면 항상 실패하는 것으로 보입니다. –
@corey : 쉘을 종료하려면 어떻게해야합니까? 누군가 인터럽트를 입력하도록 강요하는 것은 불쾌합니다. 파일에서 입력을 리다이렉트하면 파일은 EOF에 도달하고 코드는 '포크 폭탄'이 아니더라도 '프롬프트 폭탄'으로 엉망이됩니다. 빈 입력, 빈 줄은 항상 축약 된 경우를 처리해야합니다. –
우리는 Ctrl + C를 사용하여 끝내라고했습니다. Ctrl + D에 대해 알고 있으며 나중에 설명 할 수 있습니다. 네가 말하는 정확한 폭탄 테러 문제가있어. 포크에서 명령을 실행하면 (입출력 방향이 바뀐 명령 포함), EOF가 주 프로세스의 cin.getline (...)에 영향을 미치지 않을까요? –