📄 wxly.c
字号:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#include "analysis.c"
int main()
{
init(); //初始化运行环境
while(1)
{
char c,*arg[PARANUM+1];
int i=0,j=0,k=0,is_pr=0,is_bg=0,input_len=0,path,pid=0,status=0;
/*初始化操作符*/
cmd_flag=SIMPLE_CMD;
io_flag=NO_IO;
pipe_len=0;
/*设置signal信号*/
struct sigaction action;
action.sa_sigaction=delNode;
sigfillset(&action.sa_mask);
action.sa_flags=SA_SIGINFO;
sigaction(SIGCHLD,&action,NULL);
signal(SIGTSTP,ctrl_z_cmd);
/*打印提示符*/
path=get_current_dir_name();
printf("wxly@%s> ",path);
yyparse();
if(cmd_flag==SIMPLE_CMD)
{
if(cmdStr.cmd==NULL)
continue;
addHistory(cmdStr);
cmdStr.io_flag=io_flag;
if(strcmp(cmdStr.cmd,"cd")==0)
{
cd_cmd(cmdStr.para[0]);
freeSpace(&cmdStr);
continue;
}
else if(strcmp(cmdStr.cmd,"history")==0)
{
history_cmd();
freeSpace(&cmdStr);
continue;
}
else if(strcmp(cmdStr.cmd,"jobs")==0)
{
jobs_cmd();
freeSpace(&cmdStr);
continue;
}
else if(strcmp(cmdStr.cmd,"fg")==0)
{
fg_cmd(atoi(&(cmdStr.para[0][1])));
freeSpace(&cmdStr);
continue;
}
else if(strcmp(cmdStr.cmd,"bg")==0)
{
bg_cmd(atoi(&(cmdStr.para[0][1])));
freeSpace(&cmdStr);
continue;
}
else if(strcmp(cmdStr.cmd,"exit")==0)
{
printf("Thanks for your support! Bye~\n");
freeSpace(&cmdStr);
break;
}
else
{
/*寻找命令文件*/
if(isFounded(cmdStr.cmd)==0)
{
printf("This command is not founded!\n");
freeSpace(&cmdStr);
continue;
}
/*执行命令*/
if((pid=fork())==0)
{
if(is_back==1)
while(sig_flag==0)
signal(SIGUSR1,setFlag);
sig_flag=0;
arg[0]=(char *)malloc(sizeof(char)*(strlen(cmdStr.cmd)+1));
strcpy(arg[0],cmdStr.cmd);
for(i=1;i<PARANUM+1&&cmdStr.para[i-1]!=NULL;i++)
{
arg[i]=(char *)malloc(sizeof(strlen(cmdStr.para[i-1])+1));
strcpy(arg[i],cmdStr.para[i-1]);
}
arg[i]=NULL;
execv(buf,arg);
for(i=0;i<PARANUM+1&&arg[i]!=NULL;i++)
{
free(arg[i]);
arg[i]=NULL;
}
}
else
{
pid1=pid;
if(is_back==1)
{
addNode(cmdStr,pid1);
kill(pid,SIGUSR1);
pid1=0;
}
else if(is_back==0)
waitpid(pid,&status,0);
}
if(is_back==1)
sleep(1);
freeSpace(&cmdStr);
}
}
else if(cmd_flag==REDIRECT_CMD)
{
addHistory(cmdStr);
redirect();
freeSpace(&cmdStr);
}
else if(cmd_flag==PIPE_CMD)
{
addPHistory(pipeStr);
pipel();
for(i=0;i<pipe_len;i++)
{
freeSpace(&pipeStr[i]);
}
}
}
return 0;
}
/*初始化环境*/
void init()
{
int fd,n,i;
char buff[80];
if((fd=open("wxly_profile",O_RDONLY,660))==-1)
{
printf("Init environment variable error!\n");
exit(1);
}
while(n=getLine(fd,buff))
getEnvironment(n,buff);
hRec.start=0; //初始化历史记录
for(i=0;i<HISNUM;i++)
mallocSpace(&(hRec.cList[i]));
hRec.end=0;
head=end=NULL; //初始化jobs链表头尾结点
}
int getLine(int fd,char *buff)
{
int i=0;
char c;
while(read(fd,&c,1))
{
buff[i++]=c;
if(c=='\n')
{
buff[i-1]='\0';
return i;
}
}
return i;
}
void getEnvironment(int n,char *s)
{
int i=0,j=0,k=0;
char c,buff[80],*p;
while((c=s[i])!='=')
buff[i++]=c;
buff[i++]='\0';
if(strcmp(buff,"PATH")==0)
{
while(s[i]!='\0')
{
if(s[i]==':')
{
buff[j++]='/';
buff[j]='\0';
p=(char *)malloc(sizeof(char)*(strlen(buff)+1));
strcpy(p,buff);
envpath[k++]=p;
envpath[k]=NULL;
j=0;
i++;
}
else
{
buff[j]=s[i];
j++;
i++;
}
}
}
else
fprintf(stderr,"Not match");
}
/*重定向的处理 */
void redirect()
{
char *arg[PARANUM+1];
int fd_in,fd_out;
int status=0,i=0;
pid_t pid;
/*寻找命令文件*/
if(isFounded(cmdStr.cmd)==0)
{
printf("This command is not founded!\n");
return;
}
/*命令的执行*/
if((pid=fork())==0)
{
if(io_flag==FD_WRITE)
{
if((fd_out=open(cmdStr.filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1)
{
printf("Can't open %s \n",cmdStr.filename);
return;
}
if(dup2(fd_out,STDOUT_FILENO)==-1)
{
printf("Redirect standard out error!\n");
exit(1);
}
close(fd_out);
}
if(io_flag==FD_READ)
{
if((fd_in=open(cmdStr.filename,O_RDONLY,S_IRUSR|S_IWUSR))==-1)
{
printf("Can't open %s \n",cmdStr.filename);
return;
}
if(dup2(fd_in,STDIN_FILENO)==-1)
{
printf("Redirect standard in error!\n");
}
close(fd_in);
}
arg[0]=(char *)malloc(sizeof(char)*(strlen(cmdStr.cmd)+1));
strcpy(arg[0],cmdStr.cmd);
for(i=1;i<PARANUM+1&&cmdStr.para[i-1]!=NULL;i++)
{
arg[i]=(char *)malloc(sizeof(char)*(strlen(cmdStr.para[i-1])+1));
strcpy(arg[i],cmdStr.para[i-1]);
}
arg[i]=(char *)malloc(sizeof(char));
arg[i]=(char *)0;
execv(buf,arg);
for(i=0;i<PARANUM+1&&arg[i]!=NULL;i++)
{
free(arg[i]);
arg[i]=NULL;
}
}
else
{
if(is_back==0)
waitpid(pid,&status,0);
}
return;
}
/*管道的处理*/
int pipel()
{
char *argv[PIPENUM][30],*filename[10];
int i,j,k;
int fd[PIPENUM][2],pipe_in=-1,pipe_out=-1;
pid_t pid;
for(i=0;i<pipe_len;i++)
{
argv[i][0]=(char *)malloc(sizeof(char)*(strlen(pipeStr[i].cmd)+1));
strcpy(argv[i][0],pipeStr[i].cmd);
for(j=1;j<PARANUM+1&&pipeStr[i].para[j-1]!=NULL;j++)
{
argv[i][j]=(char *)malloc(sizeof(char)*(strlen(pipeStr[i].para[j-1])+1));
strcpy(argv[i][j],pipeStr[i].para[j-1]);
}
argv[i][j]=NULL;
}
argv[i][0]=NULL;
for(i=0;i<PIPENUM;i++)
{
fd[i][FD_READ]=NO_PIPE;
fd[i][FD_WRITE]=NO_PIPE;
}
for(i=0;i<pipe_len;i++)
{
if(pipe(fd[i])==-1)
{
printf("Can't open pipe!\n");
return 0;
}
}
/*寻找命令文件*/
for(i=0;i<pipe_len;i++)
{
if(isFounded(pipeStr[i].cmd)==0)
{
printf("Can't found command!\n");
break;
}
if(i!=0)
{
pipe_in=fd[i-1][FD_READ];
}
else
{
if(pipeStr[i].io_flag==FD_READ)
{
if((pipe_in=open(pipeStr[i].filename,O_RDONLY,S_IRUSR|S_IWUSR))==-1)
{
printf("Can't open %s \n",pipeStr[i].filename);
break;
}
}
else
pipe_in=NO_PIPE;
}
if(i!=pipe_len-1)
{
pipe_out=fd[i][FD_WRITE];
}
else
{
if(pipeStr[i].io_flag==FD_WRITE)
{
if((pipe_out=open(pipeStr[i].filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1)
{
printf("Can't open %s \n",pipeStr[i].filename);
break;
}
}
else
{
pipe_out=NO_PIPE;
}
}
if((pid=fork())<0)
{
printf("Fork failed!\n");
return 0;
}
if(pid==0)
{
if(pipe_in==NO_PIPE)
close(pipe_in);
if(pipe_out==NO_PIPE)
close(pipe_out);
if(pipe_out!=NO_PIPE)
{
dup2(pipe_out,1);
close(pipe_out);
}
if(pipe_in!=NO_PIPE)
{
dup2(pipe_in,0);
close(pipe_in);
}
execv(buf,argv[i]);
}
else
{
if(is_back==0)
{
waitpid(pid,NULL,0);
close(pipe_in);
close(pipe_out);
}
}
}
return 0;
}
/*查找命令文件*/
int isFounded(char *cmd)
{
int k=0;
while(envpath[k]!=NULL)
{
strcpy(buf,envpath[k]);
strcat(buf,cmd);
if(access(buf,F_OK)==0)
return 1;
k++;
}
return 0;
}
/*增加一条历史记录*/
void addHistory(CmdStr cStr)
{
int i=0;
hRec.end=(hRec.end+1)%HISNUM;
if(hRec.end==hRec.start)
hRec.start=(hRec.start+1)%HISNUM;
mallocSpace(&(hRec.cList[hRec.end]));
strcpy(hRec.cList[hRec.end].cmd,cStr.cmd);
for(i=0;i<PARANUM;i++)
{
if(cStr.para[i]!=NULL)
strcpy(hRec.cList[hRec.end].para[i],cStr.para[i]);
else
hRec.cList[hRec.end].para[i]=NULL;
}
if(io_flag!=NO_IO)
{
strcpy(hRec.cList[hRec.end].filename,cStr.filename);
hRec.cList[hRec.end].io_flag=io_flag;
}
else
{
hRec.cList[hRec.end].filename=NULL;
hRec.cList[hRec.end].io_flag=NO_IO;
}
hRec.p_len[hRec.end]=0;
}
void addPHistory(CmdStr *pStr)
{
int i=0,j=0;
hRec.end=(hRec.end+1)%HISNUM;
if(hRec.end==hRec.start)
hRec.start=(hRec.start+1)%HISNUM;
for(i=0;i<pipe_len;i++)
{
mallocSpace(&(hRec.pList[hRec.end][i]));
strcpy(hRec.pList[hRec.end][i].cmd,pStr[i].cmd);
for(j=0;j<PARANUM;j++)
{
if(pStr[i].para[j]!=NULL)
strcpy(hRec.pList[hRec.end][i].para[j],pStr[i].para[j]);
else
hRec.pList[hRec.end][i].para[j]=NULL;
}
if(pStr[i].io_flag!=NO_IO)
{
strcpy(hRec.pList[hRec.end][i].filename,pStr[i].filename);
hRec.pList[hRec.end][i].io_flag=pStr[i].io_flag;
}
else
{
hRec.pList[hRec.end][i].filename=NULL;
hRec.pList[hRec.end][i].io_flag=NO_IO;
}
}
hRec.p_len[hRec.end]=pipe_len;
}
/*history命令*/
void history_cmd()
{
int i=0,j=0,k=0;
if(hRec.start==hRec.end)
return;
else if(hRec.start<hRec.end)
{
for(i=hRec.start+1;i<=hRec.end;i++)
{
printf("%d\t",k++);
if(hRec.p_len[i]==0)
{
printCmd(hRec.cList[i]);
printf("\n");
}
else
{
for(j=0;j<hRec.p_len[i]-1;j++)
{
printCmd(hRec.pList[i][j]);
printf(" | ");
}
printCmd(hRec.pList[i][hRec.p_len[i]-1]);
printf("\n");
}
}
}
else
{
for(i=hRec.start;i<HISNUM;i++)
{
printf("%d\t",k++);
if(hRec.p_len[i]==0)
{
printCmd(hRec.cList[i]);
printf("\n");
}
else
{
for(j=0;j<hRec.p_len[i]-1;j++)
{
printCmd(hRec.pList[i][j]);
printf(" | ");
}
printCmd(hRec.pList[i][hRec.p_len[i]-1]);
printf("\n");
}
}
for(i=0,j=0;i<=hRec.end;i++)
{
printf("%d\t",k++);
if(hRec.p_len[i]==0)
{
printCmd(hRec.cList[i]);
printf("\n");
}
else
{
for(j=0;j<hRec.p_len[i]-1;j++)
{
printCmd(hRec.pList[i][j]);
printf(" | ");
}
printCmd(hRec.pList[i][hRec.p_len[i]-1]);
printf("\n");
}
}
}
}
/*cd命令*/
void cd_cmd(char *route)
{
if(route!=NULL)
if(chdir(route)<0)
printf("cd:%s Error file or directory!\n",route);
}
/*jobs命令*/
void jobs_cmd()
{
JobsNode *p;
int i=1,j=0;
p=head;
if(head!=NULL)
{
do
{
printf("%d %d %s\t",i++,p->pid,p->state);
printCmd(p->cStr);
printf("\n");
p=p->link;
}while(p!=NULL);
}
else
printf("No jobs!\n");
}
void addNode(CmdStr cStr,int node_pid)
{
int i;
JobsNode *p;
p=(JobsNode *)malloc(sizeof(JobsNode));
p->pid=node_pid;
mallocSpace(&(p->cStr));
memcpy(&(p->cStr),&cStr,sizeof(p->cStr));
strcpy(p->state,"running");
p->link=NULL;
if(head==NULL)
{
head=p;
end=p;
}
else
{
end->link=p;
end=p;
}
}
void delNode(int sig,siginfo_t *sip)
{
JobsNode *q,*p;
int id;
if(sig_z==1)
{
sig_z=0;
return;
}
id=sip->si_pid;
p=q=head;
if(head==NULL)
return;
while(p->pid!=id&&p->link!=NULL)
p=p->link;
if(p->pid!=id)
return;
if(p==head)
head=head->link;
else
{
while(q->link!=p)
q=q->link;
if(p==end)
{
end=q;
q->link=NULL;
}
else
q->link=p->link;
}
free(p);
return;
}
void setFlag()
{
sig_flag=1;
}
void ctrl_z_cmd()
{
JobsNode *p;
int i=1;
if(pid1==0)
return;
if(head!=NULL)
{
p=head;
while(p->pid!=pid1&&p->link!=NULL)
p=p->link;
if(p->pid==pid1)
strcpy(p->state,"stopped");
else
{
addNode(cmdStr,pid1);
strcpy(end->state,"stopped");
}
}
else
{
addNode(cmdStr,pid1);
strcpy(end->state,"stopped");
}
sig_z=1;
kill(pid1,SIGSTOP);
for(p=head;p->pid!=pid1;p=p->link)
i++;
printf("[%d]\t%s\t",i,end->state);
printCmd(end->cStr);
printf("\n");
pid1=0;
return;
}
/*前后台切换命令*/
void bg_cmd(int job_num)
{
JobsNode *p;
int i=0;
p=head;
for(i=1;i<job_num;i++)
p=p->link;
kill(p->pid,SIGCONT);
strcpy(p->state,"running");
}
void fg_cmd(int job_num)
{
JobsNode *p;
int i=0;
p=head;
for(i=1;i<job_num;i++)
p=p->link;
strcpy(p->state,"running");
mallocSpace(&(p->cStr));
memcpy(&cmdStr,&(p->cStr),sizeof(CmdStr));
/*
strcpy(cmdStr.cmd,p->cStr.cmd);
for(i=0;i<PARANUM;i++)
{
if(p->cStr.para[i]!=NULL)
strcpy(cmdStr.para[i],p->cStr.para[i]);
else
cmdStr.para[i]=NULL;
}
*/
pid1=p->pid;
signal(SIGTSTP,ctrl_z_cmd);
kill(p->pid,SIGCONT);
waitpid(p->pid,NULL,0);
}
/*打印一条命令到屏幕上*/
void printCmd(CmdStr cStr)
{
int i=0;
printf("%s ",cStr.cmd);
for(i=0;i<PARANUM&&cStr.para[i]!=NULL;i++)
printf("%s ",cStr.para[i]);
if(cStr.io_flag==FD_READ)
printf(" < %s ",cStr.filename);
else if(cStr.io_flag==FD_WRITE)
printf(" > %s ",cStr.filename);
}
/*为命令结构体中相应字段分配空间*/
void mallocSpace(CmdStr *cStr)
{
int i=0;
cStr->cmd=(char *)malloc(sizeof(char)*10);
cStr->filename=(char *)malloc(sizeof(char *)*10);
for(i=0;i<PARANUM;i++)
cStr->para[i]=(char *)malloc(sizeof(char)*10);
}
/*释放命令结构体占用的空间*/
void freeSpace(CmdStr *cStr)
{
int i=0;
free(cStr->cmd);
free(cStr->filename);
for(i=0;i<PARANUM;i++)
{
free(cStr->para[i]);
cStr->para[i]=NULL;
}
cStr->cmd=NULL;
cStr->filename=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -