Я пытаюсь реализовать свою собственную оболочку в качестве домашнего задания. В оболочке мне нужна новая команда под названием 'status', которая отображает текущий статус pid, например:
Когда я печатаю, он должен отображать
myshell >> статус
ПРОГРАММА СОСТОЯНИЯ ПИД-ПИД-регулятора
1412 1412 pwd выход (0)
1454 1454 / opt / firefox / bin / firefox работает
1462 1462 лс выезд (1)
1463 1463 xterm остановлен
Однако в моей оболочке у меня нет ошибки дочернего процесса для завершенного процесса, и он пишет signaled (29) для остановленного процесса. Вы можете увидеть мои результаты здесь
Это моя структура списка процессов
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);
}
Кстати, переменная итератора - это глобальная переменная, которая содержит индекс последнего элемента в списке процессов. Список процессов также является глобальной переменной. Итак, где моя ошибка в коде, почему он не отображает статус завершенного и остановленного процесса? Спасибо.