0

嘿,我正在编写一个简单的 shell,它会在获取 SIGSTSP 时暂停进程并继续获取更多命令。它将暂停的进程保存在作业列表中。当我尝试唤醒挂起的进程时,我得到一个分段错误,只有在(前)挂起的进程处理了 SIGCONT 信号之后。

这是我的信号处理器

void signalhandle(int sig) {
int i,pid,id;
sigset_t mask_set;
sigset_t old_set;
signal(SIGTSTP,signalhandle);
sigfillset(&mask_set);
sigprocmask(SIG_SETMASK,&mask_set,&old_set);

//handle sigtstp
**if (sig == SIGTSTP)**{
    GPid=getpid();
    pid=fork();
    if (pid==-1){
        perror("(ctrl-z)(signal error)(fork)");
    }
    else if (pid==0){
        Susp_Bg_Pid=GPid;
        i=0;
        while (GetPid(JobsList,i)!=-1){
             i=i+1;
        }
        id=GetId(&JobsList,GPid);
        if (id==-1){
            InsertElem(&JobsList, L_Fg_Cmd, i, GPid, 1);
            }
        else{
            DelPID(&JobsList,GPid);
            InsertElem(&JobsList, L_Fg_Cmd, id, GPid, 1);
        }
        GPid=getpid();                           
    }
    else{
       susp = 1;
       pause();
    }
}


**if (sig == SIGCONT){**
    printf("process now running again\n");
    }
}

}

这就是我尝试唤醒进程的方法

else if (!strcmp(cmd, "bg")) 
{
        int pid , new_pid=0;
        int id=0;

        if (num_arg > 1) {
                illegal_cmd = 1;
        }
        else{
            if (num_arg==1)   {
                    id = atoi(args[1]);
                    new_pid= GetPid(*pJobsList,id);
                    if (new_pid!=-1){
                        pElem=*pJobsList;
                        if (pElem->VarValue!=NULL){
                            while (pElem!=NULL){
                                if (pElem->pID==new_pid){
                                    printf("%s \n", pElem->VarValue);
                                }
                                pElem=pElem->pNext;
                            }
                        }
                        **kill(new_pid,SIGCONT);**                        
                        printf("now finished\n");
                    }
                    else{
                        printf("smash error\n");
                    }
             }
            else{

            }

        }
}

我的控制台输出是

粉碎 > 睡眠 30

^Zsmash > bg 0

睡觉 30

现在完成了

粉碎 > 进程现在再次运行

分段故障

按 [Enter] 关闭终端...

int InsertElem(LIST_ELEMENT** pList, char* value, int ID, int pID, int susp){
LIST_ELEMENT *List;
LIST_ELEMENT *temp;
List = *pList;
if (value == NULL) 
    return -1; 
    if (List == NULL)
{  
    List = (LIST_ELEMENT*)malloc(sizeof(LIST_ELEMENT));
    if (List == NULL) 
        exit (-1); 

    List->VarValue=(char*)malloc(sizeof(char)*(strlen(value)+1));
    if (List->VarValue == NULL) 
        exit (-1); 

    strcpy(List->VarValue, value);
    List->VarName = NULL; // VarName doesn't mean anything for job
    List->ID = ID;
    List->pID = pID;
    List->suspended = susp;
    List->pNext = NULL;
    *pList = List;
    return 0;
    } 
else 
{    
    if (List->ID == ID) 
        return InsertElem(&List->pNext, value, ID+1, pID, susp);
    else
    {
        temp = (LIST_ELEMENT*)malloc(sizeof(LIST_ELEMENT)); 
        if (temp == NULL)  
            exit (-1); 
        temp->VarValue =(char*) malloc(sizeof(char)*(strlen(List->VarValue)+1));
        if (temp->VarValue == NULL) 
            exit (-1); 
        strcpy(temp->VarValue, List->VarValue);
        temp->VarName = NULL;
        temp->pID = List->pID;
        temp->ID = List->ID;
        temp->suspended = List->suspended;
        temp->pNext = List->pNext;

        free(List->VarValue);
        List->VarValue=(char*)malloc(sizeof(char)*(strlen(value)+1));
        if (List->VarValue == NULL) 
            exit (-1); 
        strcpy(List->VarValue, value);
        List->ID = ID;
        List->pID = pID;
        List->suspended = susp;
        List->pNext = temp;
        return 0;
    }
}
4

0 回答 0