2012-02-18 3 views
2

내 운영 체제 클래스의 경우 이전 할당을 기반으로 할당이 필요합니다. 불행히도 내 이전 프로젝트는 내가 다음 프로젝트를 시작할 필요가 있다는 것을 알지 못하고 올바르게 작동하지 않습니다. 필자가 아래에있는 코드는 execvp로 수행 할 수없는 몇 가지 추가 명령을 사용하여 간단한 UNIX/Linux 셸을 모방 한 것으로 가정합니다. 앰퍼샌드 연산자, 'jobs'셸 명령을 통한 백그라운드 처리 : 모든 살아있는 하위 프로세스의 pid 나열 '좀비'프로세스의 "수확"및 "cd"쉘 명령 : 쉘의 작업 디렉토리를 변경하십시오.C에서 구현 된 UNIX 명령어

"jobs"명령과 "cd"명령을 제외하고는 모든 것이 작동한다고 생각하지만이 두 이유가 무엇인지 모릅니다.

다음 과제는 ... 심지어 정말 시작 위치를 모르는 이는 "file.out mysh $ cmd를 ARG1 ARG2에서 argN>"의 형태로 일부 I/O 재 지정 기능을 추가하는 것입니다

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <strings.h> 
#include <unistd.h> 
#include <wait.h> 
#include <signal.h> 
#include <sys/types.h> 

int main(int argc, char **argv) { 
    char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr; 
    int jobs[100]; 
    int jobList = 0; 
    int background; 
    ssize_t rBytes; 
    int aCount; 
    pid_t pid; 
    int status; 
    while(!feof(stdin)) { 
     pid = waitpid(-1, &status, WNOHANG); 
     if (pid > 0) 
     printf("waitpid reaped child pid %d\n", pid); 
     write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27); 
     rBytes = read(0, bBuffer, BUFSIZ-1); 
     if(rBytes == -1) { 
     perror("read"); 
     exit(1); 
    } 

    bBuffer[rBytes-1] = '\0'; 
    if(!strcasecmp(bBuffer, "exit")){ 
     exit(0); 
    } 

    sPtr = bBuffer; 
    aCount = 0; 
    do { 
     aPtr = strsep(&sPtr, " "); 
     pArgs[aCount++] = aPtr; 
    } while(aPtr); 
     background = (strcmp(pArgs[aCount-2], "&") == 0); 
     if (background) 
     pArgs[aCount-2] = NULL; 

     if (strlen(pArgs[0]) > 1) { 
      pid = fork(); 
      if (pid == -1) { 
       perror("fork"); 
       exit(1); 
      } else if (pid == 0) { 
       jobs[jobList] = pid; 
       jobList++; 

       if(!strcasecmp(pArgs[0], "jobs")){           
        for(int i; i<jobList; i++) { 
         if(kill(jobs[i],0)==0){ 
          printf(jobs[i]);  
         } 
         printf("these are jobs\n"); 
         exit(1); 
        } 
        if(!strcasecmp(pArgs[0], "cd")){ 
         int ret; 
         if (!pArgs[1]) 
          strcpy(bBuffer, "pwd"); 
         ret = chdir(pArgs[1]); 
         strcpy(bBuffer, "pwd"); 
         exit(1); 
        }         
        fclose(stdin); 
        fopen("/dev/null", "r"); 
        execvp(pArgs[0], pArgs); 
        exit(1); 
       } else if (!background) { 
        pid = waitpid(pid, &status, 0); 
        if (pid > 0) 
         printf("waitpid reaped child pid %d\n", pid); 
       } 
     } 
    } 
    return 0; 
} 
+1

'chdir'는 부모 프로세스 나 형제 프로세스에 영향을 미치지 않는다는 것을 기억하십시오. 또한,'exit's 중 일부는 의심스러운 위치에 놓이게됩니다 ... –

+0

@pst 지금 당장 당신이 말하는 것을 분명히 이해합니다,하지만 chdir과 어떤 관계가 있는지 모르겠습니다 ... ? –

+0

['while (! feof (file))'은 항상 잘못되었습니다.] (http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). –

답변

2

먼저 선을 구문 분석하고 파일로 리디렉션해야하는지 확인합니다. 그래서 당신이 strsep 또는 무엇이든을 사용한다고 말하면 출력이 file.out이거나 입력이 file.in에서 오는 것으로 나타났습니다.

이 시점에서 dup/dup2을 사용하여 출력을 리디렉션하려고합니다. 예를 들어, STDOUT를 리디렉션 :

int 
do_redirect(int fileno, const char *name) 
{ 
    int newfd; 

    switch (fileno) { 
    case STDOUT_FILENO: 
     newfd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IRUSR); 
     break; 
    } 
    if (newfd == -1) { 
     perror("open"); 
     return -1; 
    } 

    return dup2(fileno, newfd); 
} 
/* ... */ 


pid = fork(); 
do_redirect(STDOUT_FILENO, name); 

사항을 참고 :

  • 나는 코드를 테스트하지 않았다 - 그것은 심지어 내가 많은 오류 검사를하지 않았다
  • 컴파일하지 않을 수 있습니다 - 당신이 당신은 내가 별도의 기능을 사용하는 방법을 자신의
  • 참고 STDIN_FILENO 리디렉션을 구현해야
  • (나는 open에 대해 그런 식으로), 당신해야은 그대로입니다.
  • 코드에는 7 단계의 들여 쓰기 수준이 있습니다 - arrow code에 대해 들었습니까?
0

숙제이므로 직접 코드를 제공하지 않겠습니다.

dup, dup2freopen은 입력/출력 리디렉션을 살펴 보는 것이 좋습니다. 당신은 자식 프로세스를 거둘 waitpid를 사용하여 올바른 궤도에 동시 처리 (앰퍼샌드)

을 시작

fork.