我正在尝试用 C 编写 shell,但遇到了问题。shell应该循环运行,每次都提示用户,每次从stdin读取和解析文本。然后将参数划分为标记,并将每个标记放入参数向量中。然后代码派生一个孩子,然后使用参数向量作为参数运行命令。然后代码等待子进程终止,并打印有关子进程的统计信息(运行时等)。问题是,每当我们运行程序时,当我们输入 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;
}