?? shell.cpp
字號:
real_order[i]='\0';
i++;
if(flag_out==1&&input[i]=='>')
{
flag_out=2;
i++;
}
else if (flag_in==1&&input[i]=='<')
{
flag_in=2;
i++;
}
//讀出前面的空格
while ((input[i]==' '||input[i]==' ')&&i<len)
i++;
j=0;
out_filename[0]='\0';
in_filename[0]='\0';
//讀取定向輸入或輸出的文件
if(flag_out>0)
{
while (i<=len)
{
if(input[i]=='<')
{
out_filename[j]='\0';
break;
}
out_filename[j]=input[i];
i++;
j++;
}
}
if(flag_in>0)
while (i<=len)
{
if (input[i]=='>')
{
in_filename[j]='\0';
break;
}
in_filename[j]=input[i];
i++;
j++;
}
//既存在輸出重定向也存在輸入重定向
if (i<len)
{
j=0;
if (flag_out>0&&input[i]=='<')
{
i++;
flag_in=1;
if(input[i]=='>')
{
flag_in=2;
i++;
}
//讀出前面的空格
while ((input[i]==' '||input[i]==' ')&&i<len)
i++;
while (i<=len)
{
in_filename[j]=input[i];
i++;
j++;
}
}
else if (flag_in>0&&input[i]=='>')
{
i++;
flag_out=1;
if(input[i]=='>')
{
flag_out=2;
i++;
}
//讀出前面的空格
while ((input[i]==' '||input[i]==' ')&&i<len)
i++;
while (i<=len)
{
out_filename[j]=input[i];
i++;
j++;
}
}
else
{
fprintf(stderr,"ERROR!can't find the file!\n");
return -1;
}
}
//for debug
/*printf("real_order: %s\n",real_order);
printf("out_filename: %s\n",out_filename);
printf("in_filename: %s\n",in_filename);*/
k=number(real_order);
analized_order=analize(real_order);//命令已經保存在*analized_order[]中
if(strcmp(analized_order[0], "leave") == 0) //退出命令
{
printf("bye-bye\n");
// 釋放申請的空間
for(i=0;i<k;i++)
free(analized_order[i]);
free(analized_order);
free(real_order);
exit(1);
return 1;
}
/*如果輸入的是cd命令*/
if (strcmp(analized_order[0],"cd")==0)
{
do_cd(analized_order);
// 釋放申請的空間
for(i=0;i<k;i++)
free(analized_order[i]);
free(analized_order);
free(real_order);
return 1;
}
order_path=is_file_exist(analized_order[0]);
if(order_path==NULL) //can't find the order
{
fprintf(stderr,"This is command is not founded ?!\n");
// 釋放申請的空間
for(i=0;i<k;i++)
free(analized_order[i]);
free(analized_order);
free(real_order);
return -1;
}
//創建子進程用于執行命令
if((pid = fork()) == 0)
{
/* 存在輸出輸入重定向*/
if(flag_out==1)
fd_out = open(out_filename,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
if(flag_out==2)
fd_out = open(out_filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR );
if(flag_in==1)
fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR );
if(flag_in==2)
fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR );
if(fd_out==-1)
{
printf("Open out %s error \n", out_filename);
return -1;
}
if(fd_in==-1)
{
fprintf(stderr,"Open in %s error \n", in_filename);
return -1;
}
//使用dup2函數將標準輸出重定向到fd_out上
if(flag_out>0)
if(dup2(fd_out, STDOUT_FILENO) == -1)
{
fprintf(stderr,"Redirect Standard Out Error !\n");
exit(1);
}
//使用dup2函數將標準輸入重定向到fd_in上
if(flag_in>0)
if (dup2(fd_in,STDIN_FILENO)==-1)
{
fprintf(stderr,"Redirect Standard Out Error !\n");
exit(1);
}
execv(order_path,analized_order);
exit(1); //子進程推出
}
else //父進程
if(back==0) // 并非后臺執行指令
pid=waitpid(pid, &status, 0);
// 釋放申請的空間
free(out_filename);
free(in_filename);
free(order_path);
for(i=0;i<k;i++)
free(analized_order[i]);
free(analized_order);
return 1;
}
int is_back(char *order) //分析是否為后臺進程,并且將字符&去掉
{
int len=strlen(order);
if(order[len]=='&')
{
order[len]='\0';
return 1;
}
else return 0;
}
char *is_file_exist(const char *order) //判斷命令是否存在
{
char * path, * p;
char *buffer;
int i,max_length;
i = 0;
/* 使用getenv函數來獲取系統環境變量,用參數PATH表示獲取路徑*/
path=getenv("PATH");
p=path;
max_length=strlen(path)+strlen(order)+2;
if((buffer=(char *)malloc(max_length*(sizeof(char))))==0)
{
fprintf(stderr,"error! can't malloc enough space for buffer\n");
return NULL;
}
while(*p != '\0')
{
/* 路徑列表使用":"來分隔路徑*/
if(*p != ':')
buffer[i++] = *p;
else
{
buffer[i++] = '/';
buffer[i] = '\0';
/* 將指令和路徑合成,形成pathname,并使用access函數來判斷該文件是否存在*/
strcat(buffer,order);
if(access(buffer,F_OK) == 0) /* 文件被找到*/
return buffer;
else /* 繼續尋找其他路徑*/
i=0;
}
p++;
}
/* 搜索完所有路徑,依然沒有找到則返回 NULL*/
return NULL;
}
int number(const char *input) //分析命令和參數數量,來劃分相應字符串
{
int i=0,k=0;
int input_len=strlen(input);
k=0; //k記錄命令和參數數量
int flag=0;
for (i=0;i<input_len;i++)
{
if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]==' ')
{
flag=0;
continue;
}
else
{
if(flag==0)
{
flag=1;
k++;
}
}
}
return k;
}
char **analize(const char *input) //分析鍵入的命令,獲取命令和參數并保存在arg中
{
int number(const char *input); //分析命令和參數數量,來劃分相應字符串
int i,j,k; //k記錄命令和參數數量
int input_len;
int is_back=0;
char *buffer;
char **arg;//存放命令及相應參數
input_len=strlen(input);
if((buffer=(char *)malloc((input_len+1)*(sizeof(char))))==0)
{
fprintf(stderr,"error! can't malloc enough space for buffer\n");
return NULL;
}
//分析命令和參數數量
k=number(input);
if((arg=(char **)malloc((k+1)*sizeof(char *)))==0)
{
fprintf(stderr,"error! can't malloc enough space for arg\n");
return NULL;
}
//將輸入命令劃分為相應命令和參數
for (i=0,j=0,k=0;i<=input_len;i++)
{
if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]==' '||input[i]=='\0')
{
if(j == 0) /*這個條件可以略去連在一起的多個空格或者TAB */
continue;
else
{
buffer[j] = '\0';
j++;
arg[k] = (char *)malloc(sizeof(char)*j);
/* 將指令或參數從緩存拷貝到arg中*/
strcpy(arg[k], buffer);
j=0; /* 準備去下一個參數*/
k++;
}
}
else
{ /* 如果字符串最后是 '&',則置后臺運行標記為 1 */
if(input[i]== '&' && input[i+1]=='\0')
{
is_back = 1;
continue;
}
buffer[j]=input[i];
j++;
}
}
/* 在使用exec執行命令的時候,最后的參數必須是NULL指針,所以將最后一個參數置成空值*/
arg[k]=NULL;
//釋放申請空間
free(buffer);
return arg;
}
char *read_order(char *buffer) //從鍵盤中讀取命令
{
char lc_char;
char *input;
int input_lenth=0;
lc_char = getchar();
while(lc_char != '\n' && input_lenth < BUFFERSIZE)
{
buffer[input_lenth] = lc_char;
lc_char = getchar();
input_lenth++;
}
if(input_lenth >= BUFFERSIZE) //超過允許緩沖區最大長度則抱錯退出
{
fprintf(stderr,"Your command too long ! Please reenter your command !\n");
input_lenth = 0; /* Reset */
return NULL;
}
else
buffer[input_lenth] = '\0'; //加上串結束符,形成字符串
if((input=(char *)malloc(sizeof(char)*(input_lenth+1)))==0)
{
fprintf(stderr,"error! can't malloc enough space for input\n");
return NULL;
}
strcpy(input, buffer);
return input;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -