【发布时间】:2016-05-16 05:16:56
【问题描述】:
我目前正在制作自己的 shell 程序。我必须保留用户输入的最后 10 个命令的历史记录。每当用户输入一个不是常规命令的命令(例如 history、hi、fakecommand 等)时,它就会被放置在历史记录中。但是每当用户输入一个真正的命令(例如 ls、ps、top、cat 等)时,它都不会添加到历史记录中。
我认为这可能与 execvp 命令有关,因为我相信该命令会创建一个 fork 并使子进程执行该命令。但我不确定它是否应该这样做,因为我什至在执行 execvp 之前就将命令放在了历史记录中。
//A method which increments the histIndex
int incrementIndex(int index) {
if (index != 9)
return index+1;
else
return 0;
}
//A method which adds the current command to history
void updateHistory(char *history[], char command[], int histIndex) {
history[histIndex] = realloc(history[histIndex], MAX_LENGTH); //Allocating space
strcpy(history[histIndex], command); //Put the current command in history
}
int main(int argc, char *argv[]) {
//while true, do
while (1) {
int pid = fork(); //fork, or start the first process
if (pid != 0) { //if pid is not 0, then this is the parent,
wait(NULL);
}
else { //Otherwise, we have the child
printf("%s> ", getenv("USER")); //print out the user's name + >
fgets(input, MAX, stdin); //Get the users input
strtok(input, "\n"); //Take the entire line and set it to input
updateHistory(history, input, histIndex); //Updating history
histIndex = incrementIndex(histIndex);
if (strcmp(input, "exit")==0) { //If the input is exit, then exit
exit(0);
}
//Else if the current command is history, then print the last 10 commands
else if (strcmp(input, "history")==0) {
getHistory(history, histIndex);
}
//Otherwise, do
else {
numTokens = make_tokenlist(input, tokens);
tokens[numTokens] = NULL;
char cmd[MAX_LENGTH];
strcpy(cmd, tokens[0]);
execvp(cmd, tokens);
printf("Error: %s not found.\n", cmd);
}
}
}
}
【问题讨论】:
-
updateHistory()函数导致内存泄漏,因为它在进行新分配之前没有将history[]中的任何现有内存分配指针传递给free()。 -
请发布
incrementHistory()函数 -
在此行之后:
printf("Error: %s not found.\n", cmd)插入行:exit(EXIT_FAILURE);,因为您不希望孩子表现得像父母一样。 -
@user 我添加了 incrementIndex 函数。而且我不确定您所说的内存泄漏是什么意思。你是说我必须在重新分配之前释放数据?
-
history[] 的更新正在子进程中执行。子进程拥有history[] 数组的副本,因此父进程不会看到更新。
标签: c debugging exec parent-child pid