如何使 shell 在 C++ 中的 execv 之后不断要求输入
How to make shell continually ask for input after execv in C++
我正在尝试使用 fork()
和 exec()
在 C++ 中实现 shell。我的代码如下:
#include <iostream>
#include <string>
#include <unistd.h>
#include <sstream>
#include <vector>
using namespace std;
int main(int argc, char** argv){
while(true){
cout << "minish> ";
string input = "";
getline(cin, input);
int count = 1;
int shouldCount = 1;
if(input.length() == 0) shouldCount = 0;
if(shouldCount == 1){
int didFindLetter = 0;
for(int i = 1; i < input.length()-1;i++){
if(input[i] ==' ' && didFindLetter == 1){
count++;
didFindLetter = 0;
}
else if(input[i]!=' '){
didFindLetter = 1;
}
}
}
//need to create a wordArray here...
vector<string> wordArray;
std::istringstream iss (input);
string tempWord;
for(int i = 0; i < count; i++){
iss >> tempWord;
wordArray.push_back(tempWord);
}
char* argsArray[1024];
count = 0;
for (int i = 0; i < wordArray.size(); i++) {
//strdup returns pointer to a char array copy of its parameter
argsArray[count++] = strdup(wordArray[i].c_str());
}
argsArray[count++] = (char *)NULL;
pid_t pid = fork();
if(pid == 0){
//child
execvp(argsArray[0], argsArray);
fprintf(stderr, "exec: %s\n", strerror(errno));
exit(errno);
}
else if(pid == 1){
//int waitStatus;
//pid_t terminated_child_pid = wait(&waitStatus);
wait(NULL);
}
}
return 0;
}
当我运行这段代码并尝试执行单个命令时,它似乎工作正常
Elliots-MacBook-Pro:minish Elliot$ ./minish
minish> ls
minish> makefile minish minish.cpp test
在通过 execv 运行ning ls 之后,代码不会打印“minish>”来提示我进行更多输入,但是,如果我继续键入命令,即“ls”,代码能够继续执行。
这个问题的原因是什么,我该如何解决?
您的问题是您在子进程设法完成其自己的输出之前收到 minish
提示。
您可以通过在子进程上 wait
ing 来防止这种情况。子进程永远不会有 pid == 1
或 0
,所以你的 else 子句应该是
else if(pid >= 0) /*instead of `if pid==1`*/ {
wait(NULL);
}else { /*report fork failure */; }
我不太确定我是按照你的例子做的,但是你fork()
的语义是错误的:
RETURN VALUE
On success, the PID of the child process is returned
in the parent, and 0 is returned in the child. On
failure, -1 is returned in the parent, no child
process is created, and errno is set appropriately.
您的代码让父级检查 1
的 return 值 - 这意味着它跳过等待子级;它立即继续进行另一次迭代。
我正在尝试使用 fork()
和 exec()
在 C++ 中实现 shell。我的代码如下:
#include <iostream>
#include <string>
#include <unistd.h>
#include <sstream>
#include <vector>
using namespace std;
int main(int argc, char** argv){
while(true){
cout << "minish> ";
string input = "";
getline(cin, input);
int count = 1;
int shouldCount = 1;
if(input.length() == 0) shouldCount = 0;
if(shouldCount == 1){
int didFindLetter = 0;
for(int i = 1; i < input.length()-1;i++){
if(input[i] ==' ' && didFindLetter == 1){
count++;
didFindLetter = 0;
}
else if(input[i]!=' '){
didFindLetter = 1;
}
}
}
//need to create a wordArray here...
vector<string> wordArray;
std::istringstream iss (input);
string tempWord;
for(int i = 0; i < count; i++){
iss >> tempWord;
wordArray.push_back(tempWord);
}
char* argsArray[1024];
count = 0;
for (int i = 0; i < wordArray.size(); i++) {
//strdup returns pointer to a char array copy of its parameter
argsArray[count++] = strdup(wordArray[i].c_str());
}
argsArray[count++] = (char *)NULL;
pid_t pid = fork();
if(pid == 0){
//child
execvp(argsArray[0], argsArray);
fprintf(stderr, "exec: %s\n", strerror(errno));
exit(errno);
}
else if(pid == 1){
//int waitStatus;
//pid_t terminated_child_pid = wait(&waitStatus);
wait(NULL);
}
}
return 0;
}
当我运行这段代码并尝试执行单个命令时,它似乎工作正常
Elliots-MacBook-Pro:minish Elliot$ ./minish
minish> ls
minish> makefile minish minish.cpp test
在通过 execv 运行ning ls 之后,代码不会打印“minish>”来提示我进行更多输入,但是,如果我继续键入命令,即“ls”,代码能够继续执行。
这个问题的原因是什么,我该如何解决?
您的问题是您在子进程设法完成其自己的输出之前收到 minish
提示。
您可以通过在子进程上 wait
ing 来防止这种情况。子进程永远不会有 pid == 1
或 0
,所以你的 else 子句应该是
else if(pid >= 0) /*instead of `if pid==1`*/ {
wait(NULL);
}else { /*report fork failure */; }
我不太确定我是按照你的例子做的,但是你fork()
的语义是错误的:
RETURN VALUE
On success, the PID of the child process is returned
in the parent, and 0 is returned in the child. On
failure, -1 is returned in the parent, no child
process is created, and errno is set appropriately.
您的代码让父级检查 1
的 return 值 - 这意味着它跳过等待子级;它立即继续进行另一次迭代。