gpt4 book ai didi

c++ - 为什么 execvp 只适用于在我的 shell 中输入的第一个命令?

转载 作者:行者123 更新时间:2023-11-30 17:01:53 27 4
gpt4 key购买 nike

#include <stdio.h>
#include <string.h>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>

char input[100];
#define DELIMITERS " \t\n"
char * tokens[100];
int numTokens = 0;
int i = 0;
int n = 0;
char * cmd;

// function prototype
void nonBuiltin(char * inputs[]);
void handlePipe(char * cmds[]);

// this breaks the input into tokens and returns them
char * tokenize(char input[100])
{
n = 0;
// grabs input and separates by delimiters until the char is null
for(cmd = strtok(input, DELIMITERS); cmd; cmd = strtok(NULL, DELIMITERS))
{
if(n >= 100)
{
break;
}
tokens[n++] = cmd;
numTokens++;
}

for(size_t i = 0; i != n; i++)
{
printf("Tokens %zu is %s\n", i, tokens[i]);
}
return * tokens;
}

// handles the commands you enter
// checks if builtin or non builtin command
// if builtin, execute command
// else, send command to nonbuiltin function
void handleCommands(char * inputs)
{
// changes directory
if(strcmp(tokens[0], "cd") == 0)
{
int change = chdir(tokens[1]);
if(change == 0)
{
chdir(tokens[1]);
}
else
{
perror("Cannot find path specified...\n");
}
}
// prints working directory
else if(strcmp(tokens[0], "pwd") == 0)
{
printf("Your current working directory is: %s\n", getenv("PWD"));
}
// implements set command
else if(strcmp(tokens[0], "set") == 0)
{
// do this
}
// exits program
else if(strcmp(tokens[0], "exit") == 0)
{
printf("Now exiting...\n");
exit(3);
}
// input contains a nonbuiltin command
// sends input to nonbuiltin function
else
{
printf("Your command is a nonbuilt-in command\n");
nonBuiltin(tokens);
}
}

void nonBuiltin(char * inputs[])
{
int fp;
int status;

// create a new process
pid_t pid;
pid = fork();
// process creation was unsuccessful
if(pid < 0)
{
perror("Fork unsuccessful...\n");
exit(-1);
}
// child process
else if(pid == 0)
{
// printf("Fork successful...\n");
if(numTokens >= 3)
{
for(int i = 0; i < numTokens; i++)
{
if(strcmp(tokens[i], "<") == 0)
{
tokens[i] = tokens[i+1];
fp = open(tokens[i], O_RDONLY, 0);
dup2(fp, 0);
execvp(tokens[0], tokens);
}
else if(strcmp(tokens[i], ">") == 0)
{
tokens[i] = tokens[i+1];
fp = open(tokens[i], O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
dup2(fp, 1);
close(fp);
tokens[i]= NULL;
execvp(tokens[0], tokens);

}
else if(strcmp(tokens[i], "|") == 0)
{
tokens[i] = tokens[i+1];
handlePipe(tokens);
}
}
}

else
{
// printf("Nothing special as far as commands go\n");
execvp(tokens[0], tokens);


}
}
// wait for child process to end
else
{
waitpid(-1, &status, WUNTRACED);
printf("the child process has now terminated\n");
// exit(0);
}

}


void handlePipe(char * cmds[])
{
printf("Initiate piping\n");
// file descriptors
int fd[2];
// fd[0] is the read end of pipe
// fd[1] is the write end of pipe
pipe(fd);

if(!fork())
{
// first close the write end
close(1);
// fd[1] can now take stdout
dup(fd[1]);
close(fd[0]);
execvp(cmds[0], cmds);

}
else
{
// close read end
close(0);
// fd[1] can now take stdin
dup(fd[0]);
close(fd[1]);
execvp(cmds[1], cmds);
}


}

// starts the program and asks the user to enter input
// loops until the user enters 'exit'
int main()
{
while(1)
{
printf("Enter a command...\n");
fgets(input, 100, stdin);
handleCommands(tokenize(input));
}
}

When I run my shell program, I enter in a command, like ls or cat, and the command executes properly. If I run another command after that one, the command will not execute at all. It could even be the same command as the first one I entered, and it will still not run for the second time. No error messages are given. It just doesn't output what the command calls it to output. I'm currently using execvp, and I believe I am passing in the arguments currently, so I'm not sure where to go from here. Could someone give me some input on why this is happening?

最佳答案

只要你觉得合适(它在主循环中对我有用,尽管我将设计留给你):

numTokens = 0;

您没有重置在 tokenize 函数中增加的标记数量。使用全局变量很容易错过这样的小事情。

关于c++ - 为什么 execvp 只适用于在我的 shell 中输入的第一个命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36784049/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com