web-dev-qa-db-ja.com

C-if条件を使用したcdシステムコールの実装

これは、Cを使用してcdシステムコールを実装するコードです。このコードの問題は、if条件if(strcmp(buffer,"cd") == 0)に入っていないことであり、その理由がわかりません。

#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;
  }
13
urwaCFC

他の人からの提案の後にロジックを更新しました。

子プロセスは不要ここにあります。マルチタスクが必要な場合は、スレッドを使用してください。 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;
}
9
bikram990

使用する

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

代わりに。任意の長さのプレフィックスを比較するのに適しています。また、文字列のサイズにも制限があります。独自の比較ルーチンを作成する必要はありません。

コードの他の場所で他の問題がありますが、それらは個別に対処できます。

3
Jay Stenmark

私は問題がこの行のためだと思います:

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

これにより、bufferの最後の文字がヌル文字に置き換えられます。したがって、buffer"cd"が含まれている場合、"c"のみが含まれるようになります(ヌル文字はCの文字列ターミネータであるため)。

このステートメントは必要ないようです。削除してください。

1
Barmar