2014-11-15 4 views
0

클래스 용 간단한 쉘에 대한 도움이 필요합니다. execvp() 함수가 어떻게 작동하는지 잘 모르겠습니다.간단한 리눅스 쉘 - execvp() 실패

셸은 많은 작업을 수행하지 않으며 파이핑, 리디렉션, 스크립팅 또는 그런 멋진 기능을 지원하지 않습니다. 명령을 읽고 옵션 (옵션 [0]으로 명령 사용) 및 포크 만 읽습니다.

몇 번 일한 후 명령을 찾을 수 없다는 오류가 나기 시작했습니다. 여기에 게시 된 다른 비슷한 질문은 배관 또는 리디렉션과 관련이 있습니다.

가 noobcode를 용서하십시오, 그것은 꽤 아니지만, 나는 그것이 읽기 쉬운 희망 : 노골적으로 잘못

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

#define OPT_AMT 10 

const size_t SIZE = 256; 
int i = 0; 
int o = 0; 

int main(void) { 

    // initializing data 

    int exit = 0; 
    char cwd[SIZE]; 
    char cmd[SIZE]; 
    char input[SIZE * OPT_AMT]; 
    char *opt[OPT_AMT]; 
    getcwd(cwd, SIZE); 

    // main loop 

    while (exit == 0) { 
     // reset everything 
     o = 1; 
     i = 0; 
     cmd[0] = "\0"; 
     while (i < OPT_AMT) { 
      opt[i++] = "\0"; 
     } 

     // get input 
     printf("%s $ ", cwd); 
     scanf("%s", cmd); 
     gets(input); 
     opt[0] = cmd; 

     char *t = strtok(input, " "); 
     while (t != NULL) { 
      opt[o++] = t; 
      t = strtok(NULL, " "); 
     } 

     // if exit, exit 
     if (strcmp(cmd, "exit") == 0) { 
      exit = 1; 
     } 
     // else fork and execute 
     else { 
      pid_t pID = fork(); 

      if (pID == 0) { // child process 
       execvp(cmd, opt); 
      } else if (pID < 0) { // failed to fork 
       printf("\nFailed to fork\n"); 
      } else { // parent process 
       wait(0); 
      } 
     } 
    } 

    // cleanup 

    printf("\nFinished! Exiting...\n"); 
    return 0; 
} 

아무것도? 가장 최근에 exit 조건을 추가하고 options 배열을 다시 설정했습니다.

또한 이것이 내 첫 번째 질문이기 때문에 깨뜨린 규칙을 생각 나게하십시오.

우선 들어
+2

'gets()'를 사용하지 마십시오. 그것은 본질적으로 안전하지 않으며 더 이상 C의 일부가 아닙니다. 대신'fgets()'를 사용하고, 필요하다면 마지막에 줄 바꿈 문자를 제거하는 것을 잊지 마라. –

답변

2

cmd[0] = "\0"; 

cmd[0] = '\0'; 

이 컴파일러의 경고를 듣고되어야한다.

사용 설정하려면 -Wall -Wextra -pedantic (gcc 용) 옵션을 사용하십시오.


또한 당신은 더 나은 그 NULL하지만 문자 "\0"에,에 "아무것도"지적 없습니다 opt의 요소를 initalise 할 수 있습니다 : execvp()

while (i < OPT_AMT) { 
     opt[i++] = NULL; 
    } 

NULLopt이 필요합니다 - C- "strings"의 끝 배열 (관련 배경 언급/문언에 대한 감사 Paul).


또한^2 : 그것은 더 이상 C 표준 심지어 일부 악이 아니라으로, gets()를 사용하지 마십시오. 대신

gets(input); 

사용의

fgets(input, sizeof input, stdin); 

gets()은 easyly 사용자 오버 플로우 (입력) 버퍼에 전달하자. (이것은 Paul이 없다면 내 마음에 떠 올랐습니다. btw ... ;-))

+1

사실,'execvp()'는'NULL'으로 끝나는 문자열 목록이되도록'opt'를 요구합니다. –

+1

고마워, 나는 변화를 만들었지 만 나에게도 같은 오류가 발생했다. 이것은 fgets의 개행 문자와 관련이 있습니까? – Will

+0

@Will :'cmd'의 값을 출력하는'printf()'와'opt'의 각 요소에 대해 여러분이하는 일을 이해하기 위해 몇 가지 조치를 취한다면 정말 도움이 될 것입니다. 'execvp()'호출 전에 호출하면 실제로 전달할 것을 볼 수 있습니다. 그렇게하면 이런 유형의 질문에 대부분 답할 수 있습니다. –