gpt4 book ai didi

c - 在我自己实现的 shell 中 waitpid 之后 pid 的状态出现问题

转载 作者:太空宇宙 更新时间:2023-11-04 10:42:17 25 4
gpt4 key购买 nike

我正在尝试实现自己的 shell 作为作业。在 shell 中,我需要一个名为“status”的新命令,它显示 pids 的当前状态,例如:

当我输入时它必须显示

myshell>>status

PID PGID STATUS PROG

1412 1412 pwd exit(0)

1454 1454 /opt/firefox/bin/firefox running

1462 1462 ls exit(1)

1463 1463 xterm stopped

但是在我的 shell 中,我没有退出进程的子进程错误,它为停止的进程写入 signaled(29)。 You can see my output from here

这是我的进程列表结构

typedef struct 
{
pid_t ppid;
pid_t ppgid;
char *prog;
char status[30];
}Process;

这是我执行新进程的 fork :

if(forkexec){
int pid=fork();
iterator=iterator+1;
processList[iterator].prog=ptr;
processList[iterator].ppid=pid;
processList[iterator].ppgid=getpgid(pid);
strcpy(ptr,worte[0]);

switch (pid){
case -1:
perror("Fehler bei fork");
return(-1);
case 0: //child process

if(umlenkungen(k))
exit(1);
if(!setpgid(0, 0))
{
do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte); //for executing program
}

abbruch("interner Fehler 001"); //error
default: //parent process
if(k->endeabwarten){
if(!setpgid(pid, 0))
{
tcsetpgrp(0,getpgid(pid));
waitpid(pid, NULL, WUNTRACED);
tcsetpgrp(0,getpgid(shellpid));
}

}
return 0;
}
}

在子进程中它调用 do_execvp 函数,它是:

void do_execvp(int argc, char **args){
if(execvp(*args, args)==-1)
{
perror("exec-Fehler");
fprintf(stderr, "bei Aufruf von \"%s\"\n", *args);
exit(1);
}
}

对于我的新状态命令,这意味着如果用户输入状态,这部分将运行:

if (strcmp(worte[0], "status")==0) { 
int i;
fputs("PID: PGID: PROGRAM: STATUS: \n",stdout);
for(i=0; i<=iterator; i++)
{
find_status(i);
printf("%d %d %s %s\n", processList[i].ppid,processList[i].ppgid,processList[i].prog,processList[i].status);
}
return 0;
}

当我迭代进程列表以使用上层代码打印时,我还调用了 find_status 函数,它是:

void find_status(int current)  

{
pid_t w;
int status;
char stat[30];

w=waitpid(processList[current].ppid, &status, WNOHANG | WUNTRACED | WCONTINUED);

switch(w){
case -1:
strcpy(stat, "No child process");
break;

case 0:
strcpy(stat,"running");
default:
if (WIFEXITED(status)!=0) {
sprintf(stat, "exit(%d)", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)!=0) {
sprintf(stat, "signaled(%d)", WTERMSIG(status));
} else if (WIFSTOPPED(status)!=0) {
strcpy(stat,"stopped");
}
break;
}
strcpy(processList[current].status, stat);
}

顺便说一句,迭代器变量是全局变量,它保存进程列表中最后一个元素的索引。进程列表也是全局变量。那么,我的代码错误在哪里,为什么它不显示退出和停止进程的状态?谢谢。

最佳答案

无法确定,因为您还没有显示所有代码,但我推测您已经等待了这些过程。

在您的分支代码中,父分支(默认情况)有一个 waitpid 调用。该代码正在执行吗?一旦您成功地等待了一个子进程(至少一个实际上已经退出的子进程),它将从内核进程表中删除,并且您以后不能(成功地)再次调用 waitpid:它不再存在。

要了解到底发生了什么,您应该在 waitpid 失败时打印 errno 值(更好的是,打印 strerror(errno)这样您就不必去查找 errno 值)。这将告诉您 为什么 waitpid 失败,而不仅仅是失败。

关于c - 在我自己实现的 shell 中 waitpid 之后 pid 的状态出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34529743/

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