【发布时间】:2015-12-30 12:38:59
【问题描述】:
我正在尝试实现我自己的 shell 作为家庭作业。在 shell 中,我需要一个名为“status”的新命令,它显示 pids 的当前状态,例如:
当我输入时它必须显示
myshell>>状态
PID PGID 状态程序
1412 1412 密码退出(0)
1454 1454 /opt/firefox/bin/firefox 正在运行
1462 1462 ls 退出(1)
1463 1463 xterm 停止
但是在我的 shell 中,我没有退出进程的子进程错误,它为停止的进程写入了 signaled(29)。You can see my output from here
这是我的进程列表结构
typedef struct
{
pid_t ppid;
pid_t ppgid;
char *prog;
char status[30];
}Process;
这是我执行新进程的分支:
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);
}
顺便说一句,迭代器变量是全局变量,它保存进程列表中最后一个元素的索引。进程列表也是全局变量。那么,我在代码中的错误在哪里,为什么它没有显示退出和停止进程的状态?谢谢。
【问题讨论】: