?? ysh.c
字號:
#include "ysh.h"
#include "extern.h"
char *envpath[10],buf[BUFSIZE],*input=NULL;
pid_t pid1=0;
int sig_flag=0,sig_z=0,history_number;
ENV_HISTORY envhis;
NODE *head,*end;
int main()
{
init_environ(); /*初始化環(huán)境變量,將查找路徑至于envpath[]中,初始化history,和jobs的頭尾指針*/
while (1)
{
char c,*arg[20];
int i=0,j=0,k=0,is_pr=0,is_bg=0,input_len=0,path,pid=0,status=0;
history_number=envhis.end;
/********************設(shè)置signal信號********************/
struct sigaction action;
action.sa_sigaction=del_node;
sigfillset(&action.sa_mask);
action.sa_flags=SA_SIGINFO;
sigaction(SIGCHLD,&action,NULL);
// signal(SIGTSTP,ctrl_z);
signal(SIGTSTP,up_history);
/********************打印提示符************************/
path=get_current_dir_name();
printf("ysh@%s> ",path);
/********************獲取用戶輸入**********************/
while ((c=getchar())==' ' || c=='\t'|| c==EOF)
; /*跳過空格等無用信息*/
while (c!='\n') {
buf[input_len++]=c;
c=getchar();
}
buf[input_len]='\0'; /*加上串結(jié)束符*/
/*分配動態(tài)存儲空間,將命令從緩存拷貝到input中*/
input=(char *) malloc(sizeof(char)*(input_len+1));
strcpy(input,buf);
/********************解析指令**************************/
/*管道和重定向命令單獨(dú)處理*/
for (i=0,j=0,k=0;i<=input_len;i++){
if (input[i]=='<' || input[i]=='>' ||input[i]=='|'){
if (input[i]=='|'){
pipel(input,input_len); /*管道命令*/
add_history(input);
free(input);
}else{
redirect(input,input_len); /*重定向命令*/
add_history(input);
free(input);
}
is_pr=1;
break;
}
}
/********************普通命令**************************/
if (is_pr==1) continue;
for (i=0,j=0,k=0;i<=input_len;i++){
if (input[i]==' ' || input[i]=='\0'){
if (j==0) /*這個條件略去連在一起的多個空格*/
continue;
else{
buf[j++]='\0';
arg[k]=(char *)
malloc(sizeof(char)*j);
strcpy(arg[k++],buf); /*將指令或參數(shù)拷到arg中*/
j=0; /*準(zhǔn)備取下一參數(shù)*/
}
}else{
/*如果字符串最后是“&”,將后臺命令標(biāo)志置一*/
if (input[i]=='&' && input[i+1]=='\0'){
is_bg=1;
continue;
}
buf[j++]=input[i];
}
}
/********************內(nèi)部命令的處理*********************/
/*exit命令,退出*/
if (strcmp(arg[0],"exit")==0) {
add_history(input);
printf("Bye bye!\n");
free(input);
break;
}
/*history命令,顯示history數(shù)組中保存的歷史命令*/
if (strcmp(arg[0],"history")==0) {
add_history(input);
history_cmd();
free(input);
continue;
}
/*cd命令,改變當(dāng)前路徑*/
if (strcmp(arg[0],"cd")==0) {
add_history(input);
for (i=3,j=0;i<=input_len;i++) /*獲取路徑*/
buf[j++]=input[i];
buf[j]='\0';
arg[1]=(char *) malloc(sizeof(char)*j);
strcpy(arg[1],buf);/*將路徑保存到arg[1]中*/
cd_cmd(arg[1]);/*cd_cmd()函數(shù),改變路徑到指定路徑*/
free(input);
continue;
}
/*jobs命令,顯示現(xiàn)有工作*/
if (strcmp(arg[0],"jobs")==0) {
add_history(input);
jobs_cmd(); /*jobs_cmd()函數(shù),遍歷鏈表,顯示所有工作*/
free(input); continue;
}
/*bg命令,將作業(yè)放到后臺執(zhí)行*/
if (strcmp(arg[0],"bg")==0) {
add_history(input);
/*獲取制定的作業(yè)號,作業(yè)號在%后*/
for (i=0;i<=input_len;i++) {
if (input[i]=='%')
break;
}
i++;
for (;i<=input_len;i++)
buf[j++]=input[i];
buf[j]='\0';
arg[1]=(char *) malloc(sizeof(char)*j);
strcpy(arg[1],buf); /*將作業(yè)號保存在arg[1]中*/
bg_cmd(atoi(arg[1])); /*bg_cmd命令,將指定作業(yè)放到后臺運(yùn)行*/
free(input);
continue;
}
/*fg命令,將作業(yè)放到前臺執(zhí)行*/
if (strcmp(arg[0],"fg")==0) {
add_history(input);
/*獲取制定的作業(yè)號,作業(yè)號在%后*/
for (i=0;i<=input_len;i++) {
if (input[i]=='%')
break;
}
i++;
for (;i<=input_len;i++)
buf[j++]=input[i];
buf[j]='\0';
arg[1]=(char *) malloc(sizeof(char)*j);
strcpy(arg[1],buf); /*將作業(yè)號保存在arg[1]中*/
fg_cmd(atoi(arg[1])); /*fg_cmd命令,將指定作業(yè)放到后臺運(yùn)行*/
free(input);
continue;
}
/********************尋找命令文件***********************/
if (is_pr==0){/*非管道、重定向命令*/
/*在使用exec執(zhí)行命令時,最后的參數(shù)必須是NULL指針,所以將其置空*/
arg[k]=(char *) malloc(sizeof(char));
arg[k]=NULL;
if (is_founded(arg[0])==0){ /*查找arg[0]中的命令是否存在*/
printf("This command is not founded!\n");
for (i=0;i<=k;i++)
free (arg[i]);
continue;
}
}
add_history(input);
/********************執(zhí)行命令***************************/
if ((pid=fork())==0){ /*子進(jìn)程*/
if (is_bg==1) /*若為后臺命令,等待父進(jìn)程增加節(jié)點(diǎn)*/
while (sig_flag==0) /*若sig_flag==0,等待父進(jìn)程完成增加節(jié)點(diǎn)*/
/*等待父進(jìn)程SIGUSR1信號,表示節(jié)點(diǎn)已加到鏈表中*/
signal(SIGUSR1,setflag); /*收到信號,setflag函數(shù)將sig_flag置一,以跳出循環(huán)*/ sig_flag=0; /*置零,為下一命令作準(zhǔn)備*/
execv(buf,arg); /*執(zhí)行命令*/
}else { /*父進(jìn)程*/
pid1=pid; /*保存子進(jìn)程進(jìn)程號*/
if (is_bg==1) { /*后臺命令*/
add_node(input,pid1);/*增加節(jié)點(diǎn)*/
kill(pid,SIGUSR1); /*向子進(jìn)程發(fā)信號,表示節(jié)點(diǎn)已加進(jìn)鏈表*/
pid1=0; /*pid1置零,為下一命令作準(zhǔn)備*/
}
if (is_bg==0) /*前臺命令*/
waitpid(pid,&status,0);
}
if (is_bg==1)
sleep(1); /*等待命令(如:ls &)輸出后,再打印Shell提示符*/
for (i=0;i<k;i++) /*釋放空間*/
free (arg[i]);
free(input);
}
return 0;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -