2012-05-22 2 views
5

쉘을 만들고 있는데 시스템 호출 'execvp'에 문제가 있습니다. 나는이 주제에 관해 몇 가지 다른 질문을 보았지만 막연했고 완전히 다루어지지 않은 것처럼 보였다. (누가 질문을했는지 많은 정보를 제공하지 못했고 좋은 대답을 얻지 못했다.) 분명히C 쉘 빌드. execvp는 'No such file'오류를 반환합니다.

난 내 자신의 명령 행을하고 난

mysh some/path $ ps -a 

처럼 stdin에서 사용자의 입력을 읽고 있어요 그리고 나는 문자로서 인수 배열을 건물입니다 ** 및 배열 자체가 이후 (내가 생각하는) 작동 내 함수 내에서 값을 출력 할 때 I는 CMND은 "PS"인 및 인수는 perror는 등의 위이며, 내 과정에서 포크 execvp는 (CMND, 인수)를 호출 그래서

args[0] = 'ps' 
args[1] = '-a' 
args[2] = '(null)' 

를 도시

내가 얻을

'Error: no such file or directory.' 

$ PATH 변수를 넣어야합니까? 내가 뭔가 다른 것을하고 있니?

여기 args 배열 생성하기위한 내 코드입니다 : 그럼

char ** get_args(char * cmnd) { 
int index = 0; 
char **args = (char **)emalloc(sizeof(char *)); 
char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy,cmnd,strlen(cmnd)); 
char * tok = strtok(copy," "); 
while(tok != NULL) { 
    args[index] = (char *) emalloc(sizeof(char)*(strlen(tok)+1)); 
    strncpy(args[index],tok,strlen(tok)+1); 
    index++; 
    tok = strtok(NULL," "); 
    args = (char**) erealloc(args,sizeof(char*)*(index+1)); 
} 
args[index] = NULL; 
return args; 
} 

(emalloc 및 erealloc가 내장 검사 단지의 malloc 오류와 realloc을 수 있습니다)

을 I이 수행

void exec_cmnd(char*cmnd, char**args) { 
pid_t pid; 
if((pid=fork())==0) { 
    execvp(cmnd, args); 
    perror("Error"); 
    free(args); 
    free(cmnd); 
    exit(1); 
} 
else { 
    int ReturnCode; 
    while(pid!=wait(&ReturnCode)) { 
     ; 
    } 
} 
} 

그리고 위에서 말했듯이 execvp가 내 프로세스 내부에서 호출 될 때 어떤 인수도 제공하지만 실패 할 때 실패합니다 (예 : argv == { 'ps', NULL})

자세한 정보가 필요하면 언제든지 물어보십시오. 나는 이것을 해결할 필요가있다.

답변

6

그것은 당신이 execvp 당신이

로 호출 할 수 있습니다 execvp

의로 첫 번째 인수를 전달하는 cmnd에서 첫 번째 토큰 (명령 이름)을 분리해야

에 첫 번째 인수에 전체 명령 줄을 통과 생각 당신의 결과로 비 끝나는 문자열이 지나가는

execvp(args[0], args);

+0

정확하게 맞습니다. 'ps -a'를 실행하려면'execvp ("ps", { "ps", "-a", NULL})'를 호출해야합니다. – caf

+0

ack. 이마에 손바닥. 예, 감사합니다. :) – matchdav

+0

frikkin ockham 's 면도칼 – matchdav

1

참고 :

char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy, cmnd, strlen(cmnd)); 

strncpy() 이렇게 사용하면 널 종료하지 않습니다. 널 (NULL)로 1 바이트 더 할당해야합니다. 사용 가능한 경우 strdup()을 사용하는 것이 좋습니다. 그렇지 않다면, 그것을 작성하는 것을 고려하십시오. 이 오류는 emalloc()erealloc()의 오류 검사 버전에서도 문제가됩니다.

+1

또는 테마를 유지하면서'estrdup()'를 사용 (또는 구현 및 사용)하십시오. –

+0

전 그렇게 할거예요. – matchdav

+0

나는 지금 당장 그것을하고있다. 내 껍데기에서 정력을 발휘하고있다. – matchdav