Добавил:
Fragga
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:лабораторки по ОС препод Челноков / prog / Shell_03
.c#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#define EXIT 0
#define PROGRAM 1
#define CAT 2
#define ECHO 3
#define OR 4
#define AND 5
#define IN 6
#define OUT 7
#define CONV 8
static int status=0;
static int count=0;
int filestart(char *file_param[])
{
int pid,stat_loc;
pid=fork();
if (pid<0)
{
printf(" ! Error fork\n");
return -1;
}
else
if (pid==0)
{
execvp(file_param[0],file_param);
printf(" ! Can not execute %s\n",file_param[0]);
kill(getpid(),SIGKILL);
}
else
{
wait(&stat_loc);
return (stat_loc>>8);
}
}
int detect(char *com[],char *cmd_param[])//DETECTION
{
int id_com,i=0;
int fd_buf,fd_in;
while (com[count]!=NULL)
{
if (id_com=strcmp(com[count],"exit")==0)
{
return EXIT;
}
else
if (id_com=strcmp(com[count],"cat")==0)
{
cmd_param[0]=com[count+1];
count++;
return CAT;
}
else
if (id_com=strcmp(com[count],"echo")==0)
{
while (com[count+1]!=NULL)
{
count++;
cmd_param[i]=com[count];
i++;
}
count++;
cmd_param[i]=NULL;
return ECHO;
}
else
{
while(com[count]!=NULL)
{
if (id_com=strcmp(com[count],"||")==0)
{
cmd_param[i]=0;
status=filestart(cmd_param);
count++;
return OR;
}
if (id_com=strcmp(com[count],"&&")==0)
{
cmd_param[i]=0;
status=filestart(cmd_param);
count++;
return AND;
}
if (id_com=strcmp(com[count],">")==0)
{
cmd_param[i]=NULL;
fd_buf=dup(1);
close(1);
count++;
fd_in=open(com[count],O_RDWR|O_CREAT);
status=filestart(cmd_param);
dup2(fd_buf,1);
return IN;
}
if (id_com=strcmp(com[count],"<")==0)
{
cmd_param[i]=NULL;
fd_buf=dup(0);
close(0);
count++;
fd_in=open(com[count],O_RDONLY);
status=filestart(cmd_param);
dup2(fd_buf,0);
return OUT;
}
if (*com[count]=='|')
{
cmd_param[i]=NULL;
count++;
return CONV;
}
cmd_param[i]=com[count];
i++;
count++;
}
cmd_param[i]=NULL;
return PROGRAM;
}
}
}
int len_com(char *data_buf)
{
int len=0;
while(*data_buf)
{
data_buf++;
len++;
}
return len+1;
}
main()
{
char data_buf[1000];
char *commands[100];
char *cmd_param[99];
char *xx[2];
char *next_com;
char sym;
int command,s_det,i=0;
FILE *fd;
int std_in,std_out,buf,buf1;
int fdes[2];
xx[1]=NULL;
while (1)
{//MAIN
printf("$");//insert
commands[0]=next_com=data_buf;
count=0;
do
{
scanf("%s",next_com);
sym=getchar();
count++;
next_com+=len_com(next_com);
commands[count]=next_com;
}
while (sym!='\n');//insert
commands[count]=NULL;
count=0;
command=detect(commands,cmd_param);
switch (command)
{
case EXIT:
return 0;
break;
case CAT:
fd=fopen(cmd_param[0],"r");
if (fd==NULL)
{
printf("Error of read in %s\n",cmd_param[0]);
break;
}
i=0;
while ((sym=getc(fd))!=EOF)
{
printf("%c",sym);
i++;
if ((i%12)==0) printf("\n");
}
printf("\n");
fclose(fd);
break;
case ECHO:
i=0;
if (s_det=strcmp(cmd_param[i+1],"$?")==0)
{
printf("%d\n",status);
i++;
}
while (cmd_param[i]!=NULL)
{
printf("%s ",cmd_param[i]);
i++;
}
printf("\n");
break;
case OR:
xx[0]=commands[count];
if (status==0) command=filestart(xx);
break;
case AND:
xx[0]=commands[count];
if (status!=0) command=filestart(xx);
break;
case CONV:
buf=dup(1);
buf1=dup(0);
std_in=dup(0);
do
{
pipe(fdes);
std_out=fdes[1];
dup2(std_in,0);
dup2(std_out,1);
close(std_in);
close(std_out);
s_det=filestart(cmd_param);
std_in=fdes[0];
}
while (s_det=detect(commands,cmd_param)==CONV);
case PROGRAM:
dup2(buf,1);
dup2(std_in,0);
s_det=filestart(cmd_param);
dup2(buf1,0);
break;
}
}//MAIN
return 1;
}