【发布时间】:2021-02-22 02:14:56
【问题描述】:
我目前正在开发一个必须用 C 语言编写 shell 的程序。我无法让程序的 fork() 部分正常工作。这是我的代码:
void execute_func(char** tok)
{
pid_t pid = fork();
if (pid == -1)
{
printf("\nERROR: forking child process failed\n");
return;
}
else if (pid == 0)
{
if (execvp(tok[0], tok) < 0)
{
printf("ERROR: exec failed\n");
}
exit(0);
}
else
{
wait(NULL);
return;
}
}
例如,如果我要输入任何类型的函数,例如“ls”或“wc”,它会给我“错误:执行失败”消息,这意味着 fork() 没有正确运行。在我对 fork() 的理解中,这可能是一个小问题,但我完全被难住了。
这是我的整个程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
char str[129];
enum {NOT_FOUND=0,FOUND};
enum {false=0,true};
static char *ptr;
const char *del;
int ReadLine(char *, int , FILE *);
char *mystrtok(char* string,const char *delim)
{
int j,flag=NOT_FOUND;
char *p;
if(string != NULL)
{
ptr=string;
p=string;
}
else
{
if(*ptr == '\0')
return NULL;
p=ptr;
}
while(*ptr != '\0')
{
del=delim;
while(*del != '\0')
{
if(*ptr == *del)
{
if(ptr == p)
{
p++;
ptr++;
}
else
{
*ptr='\0';
ptr++;
return p;
}
}
else
{
del++;
}
}
ptr++;
}
return p;
}
void execute_func(char** tok)
{
pid_t pid = fork();
if (pid == -1)
{
printf("\nERROR: forking child process failed\n");
return;
}
else if (pid == 0)
{
if (execvp(tok[0], tok) < 0)
{
printf("ERROR: exec failed\n");
}
exit(0);
}
else
{
wait(NULL);
return;
}
}
int main()
{
int i;
char *p_str,*token;
char delim[10];
delim[0] = ' ';
delim[1] = '\t';
delim[2] = '\n';
delim[3] = '\0';
char cwd[1024];
char *tok[129];
while(1)
{
tok[0] = NULL;
fflush(stdin);
fflush(stdout);
printf("\n Enter a string to tokenize: ");
// printf("\n before scan");
fflush(stdin);
// printf("\n fflush");
ReadLine(str, 128, stdin);
/* scanf("%[^\n]",str); */
printf("\n after scan");
for (i = 1, p_str = str; ; i++, p_str = NULL)
{
token = mystrtok(p_str,delim);
if (token == NULL)
break;
printf("%d: %s\n",i,token);
tok[i-1] = token;
printf("%s\n",tok[i-1]);
}
if(tok[0] != NULL)
{
if(strcmp(tok[0],"cd") == 0)
{
if (chdir(tok[1]) != 0)
perror("chdir() error()");
getcwd(cwd, sizeof(cwd));
printf("current working directory is: %s\n", cwd);
}
else if(strcmp(tok[0],"pwd") == 0)
if (getcwd(cwd, sizeof(cwd)) == NULL)
perror("getcwd() error");
else
printf("current working directory is: %s\n", cwd);
else if(strcmp(tok[0],"exit") == 0)
exit(3);
else
{
execute_func(tok);
}
}
}
}
int ReadLine(char *buff, int size, FILE *fp)
{
buff[0] = '\0';
buff[size - 1] = '\0'; /* mark end of buffer */
char *tmp;
if (fgets(buff, size, fp) == NULL)
{
*buff = '\0'; /* EOF */
return false;
}
else
{
/* remove newline */
if ((tmp = strrchr(buff, '\n')) != NULL)
{
*tmp = '\0';
}
}
return true;
}
【问题讨论】:
-
请提供complete minimal verifiable example。我们需要看看这个函数是如何被调用的。也许
tok没有正确的内容。另外,请致电perror获取更具体的错误消息。 -
@kaylum 我在我的主函数中编辑了我正在调用的函数。
-
请阅读链接。您提供的代码既不完整也不最小。如果您尝试创建一个最小示例,例如通过删除用户输入并对字符串进行硬编码,您甚至可以自己找到问题。
-
@kaylum 我不明白你为什么需要我的其余代码。我的问题在于函数本身,因为 fork() 命令没有按我的预期工作。
-
你怎么知道的?根据定义,您在这里是因为您不知道问题出在哪里。该功能看起来是正确的。问题更可能在于token解析有问题。调试的输出是什么?如果在错误情况下调用
perrror,它的输出是什么?