これは、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;
}
他の人からの提案の後にロジックを更新しました。
子プロセスは不要ここにあります。マルチタスクが必要な場合は、スレッドを使用してください。 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;
}
使用する
...
if(strncmp(buffer,"cd",2) == 0){
...
代わりに。任意の長さのプレフィックスを比較するのに適しています。また、文字列のサイズにも制限があります。独自の比較ルーチンを作成する必要はありません。
コードの他の場所で他の問題がありますが、それらは個別に対処できます。
私は問題がこの行のためだと思います:
buffer[strlen(buffer)-1] = '\0';
これにより、buffer
の最後の文字がヌル文字に置き換えられます。したがって、buffer
に"cd"
が含まれている場合、"c"
のみが含まれるようになります(ヌル文字はCの文字列ターミネータであるため)。
このステートメントは必要ないようです。削除してください。