waitpid() 总是返回“-1”

问题描述

我接到了一个用 C 语言制作类 Unix 外壳的任务。 用户可以输入打印所有正在运行的进程的“procs”,在执行此函数之前,我必须使用函数“updateProcessList”,它遍历进程列表并在 waitpid() 的帮助下更新进程的状态。如果一个进程“刚刚”终止,我必须从列表中删除这个进程(仍然没有实现它)。 我遇到的问题是更新功能。对 waitpid() 的每次调用都返回 -1,错误号为“10”,这意味着在父进程下不存在给定 id 的子进程,这当然不是真的(这个子进程处于僵尸状态),甚至是正在运行的进程像“sleep 5 &”(“&”表示它是非阻塞的,因此父进程不会被阻塞)没有找到。 手册页很难理解,这个特定部分对作业的解释也很蹩脚(直到现在我已经在手册页的帮助下自己完成了所有工作,但是对于这个我迷失了,花了已经几个小时了,我被卡住了)。 如果有人能指出我在这里遗漏了什么,我会很高兴。 谢谢!

#include "LineParser.h"
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#define TERMINATED  -1
#define RUNNING 1
#define SUSPENDED 0
#define SIZE 2048
#define FORKED(x) (strcmp(x,"cd") != 0 && strcmp(x,"procs") != 0)
int debugMode = 0;

typedef struct process{
    cmdLine* cmd;                         /* the parsed command line*/
    pid_t pid;                        /* the process id that is running the command*/
    int status;                           /* status of the process: RUNNING/SUSPENDED/TERMINATED */
    struct process *next;                     /* next process in chain */
} process;

process **processList;


void updateProcessstatus(process* process_list,int pid,int status) {
    process* temp = process_list;
    while (temp != NULL) {
        if (temp -> pid == pid) {
            temp -> status = pid;
            return;
        }
        temp = temp -> next;
    }
}

void updateProcessList(process **process_list) {
    int status;
    process **curr = process_list;
    while ((*curr) !=  NULL) {
        pid_t statusChangedId = waitpid((*curr) -> pid,&status,WNOHANG | WUNTRACED | WCONTINUED);
        if (statusChangedId == -1) {
            perror("");
            printf("%d\n",errno);
            printf("%d\n",(*curr) -> pid);
        }
        if (statusChangedId > 0) {
            updateProcessstatus(*curr,statusChangedId,status);
        }
        curr = &((*curr) -> next);
    }
}


void addProcess(process** process_list,cmdLine* cmd,pid_t pid) {
    process **tail = process_list;
    while (*tail != NULL) {
        tail = &((*tail) -> next);
    }
    *tail = (process *) malloc(sizeof(process));
    (*tail) -> cmd = cmd;
    (*tail) -> pid = pid;
    (*tail) -> status = RUNNING;
    (*tail) -> next = NULL;
}


void printProcessList(process** process_list) {
    updateProcessList(process_list);
    process *curr = *process_list;
    while (curr != NULL) {
        printf("%-13s%-13s%s\n","PID","Command","STATUS");
        printf("%-13d%-13s%s\n",curr -> pid,curr -> cmd -> arguments[0],(curr -> status) == -1 ? "TERMINATED" :
                                                                        (curr -> status) == 0 ? "SUSPENDED" :
                                                                                                "RUNNING");
        curr = curr -> next;
    }
}


void execute(cmdLine *pCmdLine) {
    if (!FORKED(pCmdLine -> arguments[0])) {
        if (strcmp(pCmdLine -> arguments[0],"cd") == 0) {
            if (chdir(pCmdLine -> arguments[1]) < 0) {
                perror("");
                fprintf(stderr,"%d\n",errno);
            }
        }
        else if (strcmp(pCmdLine -> arguments[0],"procs") == 0) {
            printProcessList(processList);
        }
        free(pCmdLine);
    } 
    else {
        // if we're here,it means user input wasn't "cd" nor "procs"
        pid_t id = fork();
        if (id == -1) {
            fprintf(stderr,"fork() Couldn't open child,terminating...");
            _exit(-1);
        }
        if (id != 0) {                                                  // this is the parent and it will be blocked if needed
            addProcess(processList,pCmdLine,id);
            if (pCmdLine -> blocking) {
                waitpid(id,NULL,0);
            }
        }
        else {
            execvp(pCmdLine -> arguments[0],pCmdLine -> arguments);
            perror("Error ");                                           // returns here only if execv encounterd some error
            _exit(errno);
        }
    }
    //_exit(0);
    if (debugMode) {
        fprintf(stderr,"Process ID: %d\nExecuting command: %s\n",getpid(),pCmdLine -> arguments[0]);
    }
    // if (!FORKED(pCmdLine -> arguments[0]))
    //     freeCmdLines(pCmdLine);

}


int main(int argc,char **argv) {
    processList = (process **) malloc(4);
    char cmdBuffer[SIZE];
    char cwdName[PATH_MAX];

    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i],"-d") == 0) {
            debugMode = 1;
        }
    }
    getcwd(cwdName,PATH_MAX);
    printf("%s\n",cwdName);
    while (fgets(cmdBuffer,SIZE,stdin) != NULL) {
        if (strncmp(cmdBuffer,"quit",4) == 0) {
            break;
        }
        cmdLine* currCmd = parseCmdLines(cmdBuffer);
        execute(currCmd);
    }

    freeProcessList(*processList);
    return 0;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)