2013-04-18 5 views
9

다음은 C를 사용하여 cd 시스템 호출을 구현하는 코드입니다.이 코드의 문제점은 if 조건 if(strcmp(buffer,"cd") == 0) 을 입력하지 않아서 그 이유를 이해할 수 없다는 것입니다.조건부 일 경우 C-를 사용하여 cd 시스템 호출 구현

#include<sys/stat.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include<dirent.h> 
#include<error.h> 

#define BUFFERSIZE 20 
int main(){ 

char *args[80]; 
char buffer[BUFFERSIZE]; 
char *prompt = "OS"; 
char *a = ">"; 
printf("%s%s",prompt,a); 
fgets(buffer, BUFFERSIZE, stdin); 

char *tok; 
tok = strtok (buffer," "); 


while(buffer != NULL){ 
    buffer[strlen(buffer)-1] = '\0'; 
    pid_t pid; 
    pid = fork(); 
    if(pid < 0){ 
     fprintf(stderr, "Fork failed"); 
     return 1; 
    } 
    else if(pid == 0){ 

     if(strcmp(buffer,"cd") == 0){ 
     tok = strtok(NULL,"\n"); 
     cd(tok); 
     } 
     printf("%s%s",prompt,a); 
     fgets(buffer, BUFFERSIZE, stdin); 
    } 
    else{ 
    wait(NULL); 
    } 
} 
return 0; 
} 


int cd(char *pth){ 
    char path[1000]; 
    strcpy(path,pth); 

    static char *prompt = "OS"; 
    static char *a = ">"; 
    char *token; 

    char cwd[256]; 
    getcwd(cwd,sizeof(cwd)); 

    strcat(cwd,"/"); 
    strcat(cwd,path); 
    chdir(cwd);  

    printf("%s-%s%s",prompt,path,a); 
    return 0; 
    } 
+1

Q : 선택한 디버거에서 "temp"의 값을 보았습니까? 실제로 "cd"와 같은가요? 다음은 "gdb"에 대한 좋은 자습서입니다 : http://www.cs.cmu.edu/~gilpin/tutorial/ – paulsm4

+4

1)'buffer [strlen (buffer) -1] = '\ 0';'IMHO . strlen() *은 0을 반환 할 수 있습니다. 2)'tok = strtok (temp, "");'tok'은 다른 토큰을 가리킨다. – wildplasser

+2

'cd' *는 독립 실행 형 프로그램이 될 수 없다. 쉘 내장이어야한다. 너 정확히 뭘 하려구? –

답변

6

다른 사람들의 제안을 받아 로직을 업데이트했습니다.

여기에는 자식 프로세스가 필요하지 않습니다. 여기에. 멀티 태스킹을 원하면 스레드를 사용하십시오. Child process may be required for process running in background.

다음 프로그램은 나를 위해 노력하고 있습니다 :

#include <stdio.h> 

#include <sys/stat.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <dirent.h> 
//#include <error.h> 

int hasPrefix(char const *, char const *); 
int cd(char *pth); 

#define BUFFERSIZE 200 
int main(){ 

    char buffer[BUFFERSIZE]; 
    char *prompt = "OS"; 
    char *a = ">"; 

    char *tok; 
    tok = strtok (buffer," "); 


    while(buffer != NULL){ 
     bzero(buffer, BUFFERSIZE); 
     printf("%s%s",prompt,a); 
     fgets(buffer, BUFFERSIZE, stdin); 
     if(hasPrefix(buffer,"cd") == 0){ 
      tok = strchr(buffer,' '); //use something more powerful 
      if(tok) { 
       char *tempTok = tok + 1; 
       tok = tempTok; 
       char *locationOfNewLine = strchr(tok, '\n'); 
       if(locationOfNewLine) { 
        *locationOfNewLine = '\0'; 
       } 
       cd(tok); 
      } 
     }else{ 
      system("ls"); //for testing the CWD/PWD 
     } 
    } 
    return 0; 
} 

int hasPrefix(char const *p, char const *q) 
{ 
    int i = 0; 
    for(i = 0;q[i];i++) 
    { 
     if(p[i] != q[i]) 
      return -1; 
    } 
    return 0; 
} 

int cd(char *pth){ 
    char path[BUFFERSIZE]; 
    strcpy(path,pth); 

    char cwd[BUFFERSIZE]; 
    if(pth[0] != '/') 
    {// true for the dir in cwd 
     getcwd(cwd,sizeof(cwd)); 
     strcat(cwd,"/"); 
     strcat(cwd,path); 
     chdir(cwd); 
    }else{//true for dir w.r.t./
     chdir(pth); 
    } 

    return 0; 
} 
+0

덕분에 백만이 .. 매우 도움이되었습니다. – urwaCFC

+3

자신의 글을 쓰는 표준'strcmp()'에 무슨 문제가 있습니까? – Barmar

+0

당신은 homebrew'mystrcmp'을 사용하지 말았어야했는데, 우연히 그 이유 만 설명했습니다. 표준'strcmp'는 여러분이하는 동안 여기서 아무런 잘못이 없습니다. 1.'q'가 빈 문자열 ('''')이면, 항상 평등을보고합니다 2. 문자열'p'에 접두어로'q' 문자열이 있지만 추가 문자가 뒤에 있습니다 , 그것은 평등을보고 할 것입니다. 이 한 줄로'fgets()'에서 개행을 자르는 것이 더 좋았을 것입니다. (http://stackoverflow.com/a/28462221/2809095). –

1

나는 문제가 있기 때문에이 라인의 생각 :

buffer[strlen(buffer)-1] = '\0'; 

이 널 문자로 buffer의 마지막 문자를 대체합니다. 따라서 buffer"cd"이 포함 된 경우 이제는 "c" 만 포함됩니다 (null 문자는 C의 문자열 터미네이터이므로).

이 문장이 필요하지는 않지만 제거하면됩니다.

+0

그냥 우연히 만났습니다. 그리고 이것은 정말로 유일한 정답입니다. –

2

사용

... 
if(strncmp(buffer,"cd",2) == 0){ 
... 

대신. 임의 길이의 접두어를 비교하는 데 좋습니다. 또한 문자열 크기에 제한이 있습니다. 자신 만의 비교 루틴을 작성할 필요가 없습니다.

코드에 다른 문제가 있지만 별도로 해결할 수 있습니다.