Проблема со статусом pid после waitpid в моей собственной реализованной оболочке

Я пытаюсь реализовать свою собственную оболочку в качестве домашнего задания. В оболочке мне нужна новая команда под названием '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);
}

Кстати, переменная итератора - это глобальная переменная, которая содержит индекс последнего элемента в списке процессов. Список процессов также является глобальной переменной. Итак, где моя ошибка в коде, почему он не отображает статус завершенного и остановленного процесса? Спасибо.


person Ali Can Üstünel    schedule 30.12.2015    source источник


Ответы (1)


Невозможно быть уверенным, поскольку вы не показали весь код, но я предполагаю, что вы уже дождались этих процессов.

В вашем коде вилки родительская ветвь (случай по умолчанию) имеет вызов waitpid. Этот код выполняется? После того, как вы успешно дождались дочернего процесса (по крайней мере, тот, который фактически завершился), он будет удален из таблицы процессов ядра, и вы не сможете (успешно) позже снова вызвать waitpid: он больше не существует.

Чтобы узнать, что именно происходит, вы должны распечатать значение errno, когда waitpid не удается (даже лучше, выведите strerror(errno), чтобы вам не приходилось искать значение errno). Это расскажет вам, почему waitpid не удалось, а не только то, что это не удалось.

person Gil Hamilton    schedule 30.12.2015