2013-04-23 2 views
-1

간단한 쉘을 작성하는 작업을 해왔지만 환경에 대한 설정 및 설정을 요구하는 단계 중 하나에 대해 몇 가지 기본적인 기능을 사용할 수있었습니다. 이것은 작업의 세부 사항입니다.경로 받기 및 설정

4 단계 : 오기 및 경로 설정 - 우리는 쉘을 종료에 원래 무엇인지에 대한 경로를 복원 할 때문에 10마르크

것은 계속 원래 경로

이 필요한 이유입니다. 쉘 환경 (예 : 위의 setenv() 함수)에 대한 변경 사항은 쉘 자체에 영향을 줄뿐만 아니라 이후에 동일한 터미널에서 실행될 다른 프로그램에도 영향을주기 때문에 중요합니다. 이러한 이유 때문에 퇴실 할 때를 되돌려 놓는 것이 좋습니다.

단일 문자열은 원래 경로를 유지하기에 충분합니다.

경로 저장은 쉘이 시작할 때 가장 먼저 수행해야합니다.

인쇄 및 경로를 변경 - C 프로그램에서 내장 명령

우리는의 GetEnv() 함수를 사용하여 환경에 액세스 할 수 있습니다 그리고 우리는에서는 setenv() 함수를 사용하여 환경을 변경할 수 있습니다. setenv()의 매뉴얼 페이지를 살펴보면 어떻게 사용되는지 (즉, 필요한 매개 변수와 반환 값)뿐만 아니라 사용하기 위해 포함해야하는 것을 찾을 수 있습니다.

getpath - 인쇄 시스템 경로 & setpath -

이 두 명령은 환경 변수 PATH에 대해있는 설정 시스템 경로. 첫 번째는 값을 가져 와서 출력하고, 두 번째는 매개 변수로 경로 (콜론으로 구분 된 디렉토리 목록의 문자열)를 가져 와서 PATH의 값으로 만듭니다. 이 목적을 위해 각각 getenv() 및 setenv()를 사용할 수 있습니다.

경로를 복원

당신은 단지 원래 값 (당신이 쉘의 최대 시작에 저장 즉 하나)에 PATH 환경 매개 변수를 변경

.

경로 복원은 쉘이 종료하기 전에 마지막으로 수행해야합니다.

4 단계 :

첫 번째 테스트는, 당신이 3 단계에 대해 수행되는 모든 테스트가 여전히 작동하는지 확인하십시오. 우리가 현재 외부 프로그램의 실행에 영향을 줄 경로를 변경하고 있기 때문에 조심하십시오.

추가 기능을 확인하려면 먼저 경로 저장 및 복원이 작동하는지 확인해야합니다. 여기서 좋은 생각은 셸 실행 시작시에 경로를 인쇄 할 때 경로를 인쇄하고 끝에서 나가면 다시 인쇄하는 것입니다. 두 경우 모두 인쇄 된 경로가 정확히 동일해야합니다!

다음에는 getpath가 호출 될 때 원래 경로와 동일한 현재 경로가 인쇄되는지 확인해야합니다.

그런 다음 setpath 테스트에 집중해야합니다. 먼저 경로를 새 값으로 설정하고 getpath가이를 테스트하는지 테스트 한 다음 경로 변경이 실제로 외부 명령의 실행에 어떻게 영향을 미치는지 확인하십시오 (예 : 경로를 '.'로 설정하고 'ls'시도 또는 시도 쉘 자체 등).

내 코드입니다 :

/* S.NO:201148541 Simple Shell Example 
Completed upto Stage 3 */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 
#include <sys/types.h> 
#define BUFFER_SIZE 1<<16 
#define ARR_SIZE 1<<16 

void parse_args(char *buffer, char** args, 
       size_t args_size, size_t *nargs) 
{ 
    char *buf_args[args_size]; 
    char **cp; 
    char *wbuf; 
    size_t i, j; 

    wbuf=buffer; 
    buf_args[0]=buffer; 
    args[0] =buffer; 

    for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){ 
     if ((*cp != '\0') && (++cp >= &buf_args[args_size])) 
      break; 
    } 

    for (j=i=0; buf_args[i]!=NULL; i++){ 
     if(strlen(buf_args[i])>0) 
      args[j++]=buf_args[i]; 
    } 

    *nargs=j; 
    args[j]=NULL; 
} 


int main(int argc, char *argv[], char *envp[]){ 
    char buffer[BUFFER_SIZE]; 
    char *args[ARR_SIZE]; 
    int *ret_status; 
    size_t nargs; 
    pid_t pid; 

    char curDir[100]; 


    while(1){ 
     getcwd(curDir, 100); 
     printf("%s->", curDir); 
     fgets(buffer, BUFFER_SIZE, stdin); 
     parse_args(buffer, args, ARR_SIZE, &nargs); 

     if (nargs==0) continue; 
     if(strcmp(args[0], "cd") == 0){ 
      chdir(args[1]); 

     } 
     else if (!strcmp(args[0], "exit")) exit(0);  
     pid = fork(); 
     if (pid){ 
      pid = wait(ret_status); 
      printf("finished\n", pid); 
     } 
     else { 

      if(execvp(args[0], args)) { 
       puts(strerror(errno)); 
       exit(127); 
      } 
     } 
     } 
    } 



    return 0; 
} 

내가 손해를보고 정말이야 및 지침 도움이 될 것입니다.

+0

당신은 더 구체적 수 있습니까? 너의 문제는 무엇인가? – Alex

+0

환경을 PATH로 설정하고 환경을 설정하기 위해 2 개의 함수를 구현하려고하면 할당에 대한 getenv 및 setenv 함수를 사용하여이 작업을 수행 할 수 있다고 나와 있습니다. 이 작업을 시작하는 방법을 모릅니다. 예를 들어 사용자 입력에서 특정 입력을 가져올 때 호출하는 함수일까요? (내가 exit와 cd 명령을 수행 한 것처럼) – whitewaltz

+0

당신이 작성했거나 과제에 주어진 코드 스 니펫이 있습니까? 그것은 어떤 경로 설정 코드도 포함하고 있지 않습니다! – hyde

답변

1

우리가 이전 단계가 무엇인지 모르는 점을 감안하고, 그런 다음 테스트 setpath에 초점을 맞추어야 조언

으로가는. 먼저 경로를 새 값으로 설정하고 getpath가이를 테스트하는지 확인한 다음 경로 변경이 실제로 외부 명령 실행에 영향을주는 방식을 확인하십시오 (예 : 경로를 '.'로 설정하고 'ls' 또는 셸 자체를 사용해보십시오 (예 : ).

당신은 다음과 같이 할 수

...

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    char *path, *old, *tobeSet; 
    path = malloc(1024); 
    path = getenv("PATH"); 
    old = malloc(strlen(path)); 
    tobeSet = malloc(10); // just to be safe 
    strcpy(tobeSet,"."); 
    if(setenv("PATH",tobeSet,1)!=0) 
    { 
     printf("Couldn't set path\n"); 
     return 0; 
    } 
    printf("\nPATH::\t%s\n",path); 
    printf("\n\nNewPath::\t%s\n",tobeSet); 
    if(setenv("PATH",path,1)!=0) 
    { 
     printf("Couldn't restore path\n"); 
     return 0; 
    } 
    printf("\n\nOld path ::\t%s\n",path); 
    free(path); 
    free(old); 
    free(tobeSet); 
    return 0; 
}