shellÄÜÊÖ°ï¹þÊÖÀ²~``
ʵÏÖÒ»¸ö¼òµ¥µÄshellֻҪʵÏÖ4¸öÃüÁÎÒ¸Õ½Ó´¥£¬Ö»ÏþµÃÒ»µãÔÀí£¬×Ô¼ºÐ´¸ù±¾Ð´²»³öÂï
[size=3][font=Arial]ÒÔÏÂËĸöÃüÁî[/font][/size]
[size=3][font=Arial]EnvironÁгöËùÒÔ»·¾³±äÁ¿×Ö·û´®µÄÉèÖã¨ÀàËÆÓëUnixϵͳϵÄenvÃüÁ
Echo<ÄÚÈÝ>ÏÔʾechoºóµÄÄÚÈÝÇÒ»»ÐÐ
Help¼ò¶Ì¸ÅÒªµÄÊä³öÄãµÄshellµÄʹÓ÷½·¨ºÍ»ù±¾¹¦ÄÜ
JobsÊä³öshellµ±Ç°µÄһϵÁÐ×Ó½ø³Ì£¬±ØÐëÌṩ×Ó½ø³ÌµÄÃüÃûºÍPIDºÅ
Quit,exit,byeÍ˳öshell¡£[/font][/size]
[size=3][font=Arial]
[/font][/size]ËÄܰï¹þÎÒÀ²£¬Íò·Ö¸Ðл£¬µ½ÍøÉÏ¿´ÀàËÆµÄ´úÂë¾Í¼¸Ê®ÐУ¬Ï£ÍûÄÄΪºÃÐÄÈ˰ïÎÒдһÏ£¬Íò·Ö¸Ðл£¬qq±Ò·îÉÏÀ²£¡£¡£¡£¡£¡ µãÂïûÈ˰ïÊÖÀ²£¿£¿ºÃÓôÃÆ¿©£¡£¡ good good study, day day up ÎÒÒ²ÖªµÀÕâ¸öµÀÀí£¬¿ÉÊǸÕѧÔõôдµÄ³ö£¬ÏÖÔÚµÄÀÏÊ¦ÕæµÄÀ÷º¦£¬ÎÒûµÄ°ì·¨²Å³ö´Ëϲߣ¬ËÕæµÄÄܰïÏÂÎÒæ°¡ µÈµ½Á賿3µãҲûÈ˰ïæ°¡£¬ÓôÃÆÅ¶ [QUOTE=guanguan3]µÈµ½Á賿3µãҲûÈ˰ïæ°¡£¬ÓôÃÆÅ¶[/QUOTE]
¾«Éñ¿É¼Î
ºÎ¿à¸ÉµÈ×Å, Ò»ÌìµÄʱ¼äÄã¾ÍÊÇÏÖѧҲ¸ã¶¨ÁË ÎÒѧÁËÒ»ÌìÁ˰¡£¬¿Éϧû¸ãµÄºÜ¶®£¬ÖªµÀÊÇÖªµÀÔõô»ØÊÂÁË£¬¾ÍÊDz»ÖªµÀÏÂÊÖ°¡ ²»ÖªµÀÕâ¸ö¶Ô²»¶Ô£¬ÔÚ±ðÈ˵ÄÖ¸µãÏÂдµÄ
#define SIZE 100
#define BUFFSIZE 200
#define BUFFERSIZE 1024
#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<malloc.h>
#include<signal.h>
#include<stdlib.h>
//*************************************** **********************/
typedef struct SH_HISTORY //*ÓÃÑ»·Á´±í´æ´¢ÓùýµÄSH_HISTORYÃüÁî */
{
int start;
int end;
char command_his[SIZE][100];
}SH_HISTORY;
typedef struct NODE // /*°Ñ×÷ÒµÓÃÁ´±í±£´æÆðÀ´*/
{
pid_t pid; //*½ø³ÌºÅ*/
char cmd[100]; // /*ÃüÁî×Ö·û*/
char state[10]; //*״̬*/
struct NODE *next; //*Ö¸ÏòÏÂÒ»½ÓµãµÄÖ¸Õë*/
}NODE;
char *envpath[10],buff[BUFFSIZE],*input=NULL;
pid_t pid1=0;
int sig_flag=0,sig_z=0;
SH_HISTORY sh_his;
NODE *head,*end;
//*******************ÉùÃ÷³ÌÐòÖÐÓõ½µÄº¯Êý****************************/
int found_cmd(); //*²éÕÒÃüÁÊý*/
int getline(); //*¶ÁȡһÐеĺ¯Êý*/
void init_environ(); //*³õʼ»¯»·¾³±äÁ¿*/
void history_add(); //*¼Ç¼historyÃüÁîµÄº¯Êý*/
void command_history();//*ÏÔʾhistoryÃüÁîµÄº¯Êý*/
void command_cd();//*´¦ÀícdÃüÁîµÄº¯Êý*/
void command_jobs();//*´¦ÀíjobsÃüÁîµÄº¯Êý*/
void setflag();//*½«±ê־λÖÃ1µÄº¯Êý*/
void getenviron();//*³õʼ»¯²éÕÒ·¾¶µÄº¯Êý*/
void ctrl_z(); //*´¦ÀíÓû§°´ÏÂctrl-zÊÇʱµÄº¯Êý*/
void command_echo();//*´¦ÀíechoÃüÁîµÄº¯Êý*/
void dele_node();//*ÏòjobsÃüÁîµÄÁ´±íÖÐɾ³ý½ÚµãµÄº¯Êý*/
void add_node();//*ÏòjobsÃüÁîµÄÁ´±íÖÐÔö¼Ó½ÚµãµÄº¯Êý*/
void print_help(); //*´¦ÀíhelpÃüÁîµÄº¯Êý*/
void command_mkdir(); //*½¨Á¢Ä¿Â¼µÄº¯Êý*/
void command_rmdir();//*³·ÏúĿ¼µÄº¯Êý*/
void command_environ(); //*´¦ÀíenvironÃüÁîµÄº¯Êý*/
//*******************************main************************************/
main()
{
init_environ(); //*³õʼ»¯»·¾³±äÁ¿£¬½«²éÕÒ·¾¶ÖÃÓÚenvpath[]ÖÐ*/
while(1)
{
char ch,*argment[20];
int i=0,j=0,k=0,is_pr=0,is_bg=0,input_len=0,pid=0,path,status=0,tmp=0;
// ***************************ÉèÖÃsignalÐźÅ*************************/
struct sigaction action;
action.sa_sigaction=dele_node;
sigfillset(&action.sa_mask);
action.sa_flags=SA_SIGINFO;
sigaction(SIGCHLD,&action,NULL);
signal(SIGTSTP,ctrl_z);
//********************´òÓ¡Ìáʾ·û**********************/
path=get_current_dir_name();
printf("<shell@%s> ",path);
//***********»ñÈ¡Óû§ÊäÈë***************/
while((ch=getchar())==' '||ch=='\t'||ch==EOF) //*Ìø¹ý¿Õ¸ñµÈÎÞÓÃÐÅÏ¢*/
if(ch=='\n') continue; //*ÊäÈëΪ¿Õʱ½áÊø±¾´ÎÑ»·£¬´òÓ¡Ìáʾ·û*/
while(ch!='\n')
{
buff[input_len++]=ch;
ch=getchar();
}
buff[input_len]='\0'; //*¼ÓÉÏ´®½áÊø·û*/
//*·ÖÅ䶯̬´æ´¢¿Õ¼ä£¬½«ÃüÁî´Ó»º³åÇø¸´ÖƵ½inputÖÐ*/
input=(char *)malloc(sizeof(char)*(input_len+1));
strcpy(input,buff); // *½«ÃüÁî¸´ÖÆµ½inputÖÐ*/
// ******************************½âÎöÖ¸Áî**************************/
//***************ÆÕͨÃüÁî****************/
if(is_pr==1) continue;//*Èç¹ûis_pr==1£¬ÔòÖ´ÐÐÆÕͨÃüÁ·ñÔò£¬Ö´ÐйܵÀÃüÁî*/
for(i=0,j=0,k=0;i<input_len+1;i++)
{
if(input[i]==' '||input[i]=='\0') ///* Çå³ý¿Õ¸ñºÍ½áÊø·û*/
{
if(j==0) //*ÂÔÈ¥Á¬ÔÚÒ»ÆðµÄ¶à¸ö¿Õ¸ñ*/
continue;
else
{
buff[j++]='\0';
argment[k]=(char *)malloc(sizeof(char)*j);
strcpy(argment[k++],buff);//*½«Ö¸Áî»ò²ÎÊý¸´ÖƵ½argmentÖÐ*/
j=0;
}
}
else{ //*Èç¹û×Ö·û´®×îºóÊÇ&£¬½«ºǫ́ÃüÁî±êÖ¾ÖÃ1*/
if(input[i]=='&'&&input[i]=='\0')
{
is_bg=1;
continue;
}
buff[j++]=input[i];
}
}
// ***************************ÄÚ²¿ÃüÁî****************************/
if(strcmp(argment[0],"environ")==0||strcmp(argment[0],"en")==0)
{
history_add(input);
command_environ();
free(input);
continue;
}
if(strcmp(argment[0],"rmdir")==0)
{
history_add(input);
for(i=6,j=0;i<=input_len;i++)
buff[j++]=input[i];
buff[j]='\0';
argment[1]=(char *)malloc(sizeof(char)*j);
strcpy(argment[1],buff);
command_rmdir(argment[1]);
free(input);
continue;
}
if(strcmp(argment[0],"mkdir")==0)
{
history_add(input);
for(i=6,j=0;i<=input_len;i++)
buff[j++]=input[i];
buff[j]='\0';
argment[1]=(char *)malloc(sizeof(char)*j);
strcpy(argment[1],buff);
command_mkdir(argment[1]);
free(input);
continue;
}
if(strcmp(argment[0],"help")==0)
{
history_add(input);
print_help();
free(input);
continue;
}
// *********exit,bye,quit,Í˳ö*************/
if(strcmp(argment[0],"exit")==0||strcmp(argment[0],"quit")==0||strcmp(argment[0],"bye")==0) {
history_add(input);
printf("bye bye!\n");
free(input);
exit(0);
break;
}
// *************historyÃüÁÏÔʾhistoryÊý×éÖб£´æµÄÀúÊ·ÃüÁî************/
if(strcmp(argment[0],"history")==0)
{
history_add(input);
command_history();
free(input);
continue;
}
//*********echoÃüÁ ÏÔʾÊäÈë¹ýµÄ×Ö·û´®***************/
if(strcmp(argment[0],"echo")==0){
history_add(input);
for(i=0;i<=input_len;i++)
{
if(input[i]==' ')
break;
}
i++;
for(;i<=input_len;i++)
buff[j++]=input[i];
buff[j]='\0';
argment[1]=(char *)malloc(sizeof(char)*j);
strcpy(argment[1],buff);
command_echo(argment[1]);
free(input);
continue;
}
/**********************************************/
if(strcmp(argment[0],"cd")==0){
history_add(input);
for(i=3,j=0;i<=input_len;i++)
buff[j++]=input[i];
buff[j]='\0';
argment[1]=(char *)malloc(sizeof(char)*j);
strcpy(argment[1],buff);
command_cd(argment[1]);
free(input);
continue;
}
/********************************************/
if(strcmp(argment[0],"jobs")==0){
history_add(input);
command_jobs();
free(input);
continue;
}
//*********ѰÕÒÃüÁîÎļþ**********/
if(is_pr==0)
{
argment[k]=(char *)malloc(sizeof(char));
argment[k]=NULL;
if(found_cmd(argment[0])==0)
{
printf("This is an inavilable command!\n");
for(i=0;i<=k;i++){
free(argment[i]);
continue;
}
}
history_add(input);
//************** Ö´ÐÐÃüÁî*****************/
if((pid=fork())==0){ /*×Ó½ø³Ì*/
while(sig_flag==0)
signal(SIGUSR1,setflag);
sig_flag=0;
execv(buff,argment);
}
else{
pid1=pid;
add_node(input,pid1);
kill(pid,SIGUSR1);
pid1=0;
waitpid(pid,&status,0);
}
for(i=0;i<k;i++)
free(argment[i]);
free(input);
}
}
}
/***********************Ö÷³ÌÐòÍê³É********************/
/*************º¯Êý¶¨Òå*****************/
void init_environ()
{
int fd,n,i;
char buff[80];
if((fd=open("sh_profile",O_RDONLY,660))==-1)
{
printf("init wrong!");
exit(1);
while(n=getline(fd,buff))
getenviron(n,buff);
sh_his.start=0;
sh_his.end=0;
head=end=NULL;
}
//***************²éÕÒÃüÁîÎļþµÄº¯Êý********************************/
int found_cmd(char *cmd)
{
int k=0;
while(envpath[k]!=NULL){ //*²éÕÒ·¾¶ÒÑÔÚ³ÌÐò³õʼ»¯Ê±É趨ÔÚenvpath[i]ÖÐ*/
strcpy(buff,envpath[k]);
strcat(buff,cmd);
if(access(buff,F_OK)==0) //*Îļþ±»ÕÒµ½*/
return 1;
k++;
}
return 0;
}
/********************************************************/
void history_add(char *inputcmd)
{
sh_his.end=(sh_his.end+1)%SIZE; //*endÇ°ÒÆÒ»Î»*/
if(sh_his.end==sh_his.start) //*endºÍ startָͬÏòͬһÊý×é*/
sh_his.start=(sh_his.start+1)%SIZE; //*startÇ°ÒÆÒ»Î»*/
strcpy(sh_his.command_his[sh_his.end],inputcmd);
//*½«ÃüÁî¸´ÖÆµ½Ö¸ÏòendµÄÊý×éÖÐ*/
}
//*************************command-history *************************************/
void command_history()
{
int i,count=0;
if(sh_his.start==sh_his.end) //*Ñ»·Êý×éΪ¿Õ*/
return;
else if(sh_his.start<sh_his.end)
{
printf("id command \n");
for(i=sh_his.start+1;i<sh_his.end;i++)
//*ÏÔʾhistoryÃüÁîÊý×éÖÐstart+1µ½end¸öÃüÁî*/
{
printf("%d\t%s\n",count,sh_his.command_his[i]);
count++;
}
}
else {
printf("id command \n");
for(i=sh_his.start+1;i<SIZE;i++)
//*ÏÔʾhistoryÃüÁîÊý×éÖÐstart+1µ½SIZE¸öÃüÁî*/
{
printf("%d\t%s\n",count,sh_his.command_his[i]);
count++;
}
for(i=0;i<sh_his.end;i++) /*ÏÔʾ0~end¸öÃüÁî */
{
printf("%d\t%s\n",count,sh_his.command_his[i]);
count++;
}
}
}
/************************ *********************************/
void command_cd (char *route)
{
if(route!=NULL)//*·¾¶²»Îª¿Õ*/
if(chdir(route)<0) //*ϵͳµ÷ÓÃchdirº¯Êý£¬´ïµ½¸Ä±äµ±Ç°Â·¾¶µÄÄ¿µÄ*/
printf("%s file error or didn't exist!\n",route);
}
/**************************command-jobs**************************************/
void command_jobs()
{
NODE *p;
int i=1;
p=head;
if(head!=NULL)
{
printf("id pid state command\n");
printf("%d %d %s\t %s \n",i,p->pid,p->state,p->cmd);
i++;
p=p->next;
}
else
printf("no process!\n");
}
/**************************add_node***********************************/
void add_node(char *input_cmd,int node_pid)
{
NODE *p;
p=(NODE *)malloc(sizeof(NODE));
p->pid=node_pid;
strcpy(p->cmd,input_cmd);
strcpy(p->state,"running");
p->next=NULL;
if(head==NULL)
{
head=p;
end=p;
}
else
{
end->next=p;
end=p;
}
}
//************** dele_node *************************/
void dele_node(int sig,siginfo_t *sif)
{
NODE *q,*p;
int id;
if(sig_z==1)
{
sig_z=0;
return;
}
id=sif->si_pid;
p=q=head;
if(head==NULL)
return;
while(p->pid!=id&&p->next!=NULL)
{
p=p->next;
if(p->pid!=id)
return;
if(p==head)
head=head->next;
else
{
while(q->next!=p)
q=q->next;
if(p==end)
{
end=q;
q->next=NULL;
}
else q->next=p->next;
}
free(q);
}
}
/****************setflag*************************/
void setflag()
{
sig_flag=1;
}
/******************getline**************************/
int getline(int fd,char *buf)
{
int i=0;
char c;
while(read(fd,&c,1))
{
buf[i++]=c;
if(c=='\n')
{
buf[i-1]='\n';
return i;
}
}
return i;
}
/***********************getenviron****************************/
void getenviron(int n,char *s)
{
int i=0,count=0,k=0;
char c,buff1[80],*p;
while((c=s[i])!='=')
buff1[i++]=c;
buff1[i++]='\0';
if(strcmp(buff1,"PATH")==0)
{
while(s[i]!='\0')
{
if(s[i]==':')
{
buff1[count++]='/';
buff1[count]='\0';
p=(char *)malloc(strlen(buff1)+1);
strcpy(p,buff1);
envpath[k++]=p;
envpath[k]=NULL;
count=0;
i++;
}
else
{
buff1[count]=s[i];
count++;
i++;
}
}
}
else
fprintf(stderr,"no match\n");
}
/******************ctrl-z***********************************/
void ctrl_z()
{
NODE *p;
int i=1;
if(pid1==0) return;
if(head!=NULL)
{
p=head;
while(p->pid!=pid1&&p->next!=NULL)
p=p->next;
if(p->pid==pid1)
strcpy(p->state,"stopped");
else{
add_node(input,pid1);
strcpy(end->state,"stopped");
}
}
else
{
add_node(input,pid1);
strcpy(end->state,"stopped");
}
sig_z=1;
kill(pid1,SIGSTOP);
for(p=head;p->pid!=pid1;p=p->next)
i++;
printf("[%d]\t%s\t%s\n",i,end->state,end->cmd);
pid1=0;
}
/*¶¨*/
/*****************echo command**************************/
void command_echo(char *arg){
int i;
if(arg!=NULL){
for(i=0;i<strlen(arg);i++)
printf("%c",arg[i]);
printf("\n");
}
}
/*********************************************************/
void print_help(){
printf(" help -- show the all command\n");
printf(" exit or quit or bye -- exit \n ");
printf(" cd -- show the path\n");
printf(" history -- show the used command\n");
printf(" jobs -- show the running's process\n");
printf(" echo < > show the letter \n");
printf(" mkdir filename -- create a new file!\n");
printf(" rmdir filename -- delete the file!\n");
printf(" en or environ -- show the PATH!\n");
}
/***********************************************************/
void command_mkdir(const char *f){
if(f!=NULL)
if(mkdir(f,660)<0)
printf("can't create file!\n");
}
/**************************************************************/
void command_rmdir(char *fn){
if(fn!=NULL)
if(rmdir(fn)<0)
printf("can't delete the file!\n");
}
/**********************environ**********************************/
void command_environ(){
int fd,read_num,i;
char *buffer;
fd=open("sh_profile",O_RDONLY,00700);
if(fd==-1){
printf("init wrong!");
exit(1);
}
else {
buffer=(char *)malloc(sizeof(char)*BUFFERSIZE);
read_num=read(fd,buffer,BUFFERSIZE);
}
for(i=0;i<BUFFERSIZE;i++)
printf("%c",buffer[i]);
printf("\n");£ý
Ò³:
[1]