C でシェルを作成しようとしていますが、問題が発生しています。シェルは、標準入力からテキストを読み取って解析するたびに、毎回ユーザーにプロンプトを表示して、ループで動作することになっています。次に、引数がトークンに分割され、各トークンが引数ベクトルに配置されます。次に、コードは子をフォークし、引数ベクトルをパラメーターとして使用してコマンドを実行します。次に、コードは子が終了するのを待ち、子に関する統計 (ランタイムなど) を出力します。問題は、プログラムを実行するたびに ls /home と入力すると (たとえば)、ホーム ディレクトリが一覧表示されず、現在のディレクトリが一覧表示されることです。さらに、新しいディレクトリを追加しようとすると、コードに変数を追加すると、コードは機能しなくなります。これを解決する方法はありますか?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <string.h>
#define TRUE 1
#define BUFFERSIZE 129
int main (int argc, char* argv[]){
int status;
int who = RUSAGE_CHILDREN;
struct rusage usage;
struct rusage before_usage;
struct timeval start, end;
while(TRUE){
printf("==>: ");
char input_string[BUFFERSIZE];
memset(input_string, '\0', BUFFERSIZE);
fgets(input_string, BUFFERSIZE-1, stdin);
int i = 0;
char* input_arguments[32]; //Pointers to what the commands will be
char* token; //The specific piece of the input "ls" or "/home"
char* program;
int run_exec = 1; //To say whether execvp will run
token = strtok(input_string, " ");
char* prog = malloc(strlen(token)+1);
memset(prog, '\0', strlen(token));
strncpy(prog, token, strlen(token));
program = prog;
printf("PROGRAM: %s\n", prog);
token = strtok(NULL, " ");
if(strncmp(program, "exit", 4) ==0)
exit(0);
while(token != NULL && i < 32){
printf("TOKEN: %s \n", token);
char* tmp = malloc(strlen(token)+1);
memset(tmp, '\0', strlen(token)+1);
strncpy(tmp, token, strlen(token));
input_arguments[i]=tmp;
printf("INPUT: %s \n", input_arguments[i]);
if(strcmp(program, "cd") == 0){
chdir(input_arguments[0]);
run_exec = 0;
printf("EXEC: %d\n", run_exec);
}
printf("%d\n", i);
i++;
size_t tmp2 = 50;
printf("%s\n", getcwd(tmp, tmp2));
token = strtok(NULL, " ");
printf("IN LOOP\n");
}
input_arguments[i] = NULL;
printf("AFTER LOOP\n");
if(fork() != 0){
int start_time = gettimeofday(&start, NULL);
if(run_exec == 1){
getrusage(who, &before_usage);
waitpid(-1, &status, 0);
int end_time = gettimeofday(&end, NULL);
double wall_time_passed = (end.tv_sec -start.tv_sec)*1000
+ (end.tv_usec - start.tv_usec)/1000;
getrusage(who, &usage);
double user_time = (usage.ru_utime.tv_sec*1000 +
usage.ru_utime.tv_usec/1000);
double system_time = (usage.ru_stime.tv_sec*1000
+ usage.ru_stime.tv_usec/1000);
//long page_faults = 0;
//long soft_faults = 0;
//long invol = 0;
//long vol = 0;
printf("Number of Page Faults: %ld \n", usage.ru_majflt -before_usage.ru_majflt);
//printf("soft_faults: %lu\n", soft_faults);
printf("Number of Page Reclaims: %ld \n", usage.ru_minflt - before_usage.ru_minflt);
//printf("soft_faults: %lu\n", soft_faults);
printf("Number of times preempted involuntarily: %ld \n", usage.ru_nivcsw - before_usage.ru_nivcsw);
printf("Number of times preempted Voluntarily: %ld \n", usage.ru_nvcsw - before_usage.ru_nivcsw);
printf("User Time: %f \n", user_time);
printf("System Time: %f \n", system_time);
printf("Wall-Time: %f \n", (wall_time_passed));
}
}
else{
if(run_exec == 1){
printf("RUNNING EXEC: %s, %s \n", program, *input_arguments);
printf("EXEC: \n", execvp(program, input_arguments));
}
}
}
return 0;
}