#define _GNU_SOURCE
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>//include the function"get_current_dir_name""fork""execv""getpid""wait""sleep""access""chdir"
#include <string.h>
#include <stdlib.h>//include the function"free""atoi"
#include <sys/types.h>//include the type"pid_t""open"
#include <sys/stat.h>//include the function"open"
#include <sys/wait.h>//define the function"wait"
#include <signal.h>//include the function"kill"
#include <fcntl.h>//include the function"open"
#include <stdlib.h>
#include "ysh.h"
#define TRUE 1
#define FALSE 0
#define MaxLen 40
#define NO_PIPE -1
#define FD_READ 0
#define FD_WRITE 1
char tokenString[MaxLen+1];
int new_flag;//to show that a new command begin;
int end_flag;//to show if exit is performed
typedef enum{
END,INPUT,OUTPUT,PIPE,BACK,STRING,ERROR
}TokenType;
typedef enum{
START,INSTRING,DONE
}StateType;
typedef enum{
BEGIN,PROGA,PROGB,INR,OUTR,FINISH
}StepMark;
struct result{
int kind;//represent different struct
char *filein;
char *fileout;
int n;//used for pipe
};
int getaline(int fd,char *buf);
void getenviron(int n,char *s);
void init_environ();
TokenType getToken();
void analyze();
int is_founded(char *cmd);
void cd_cmd(char *cmd);
void add_node(char *input_cmd,int node_pid);
void bg_cmd(int job_num);
void fg_cmd(int job_num);
void jobs_cmd();
void ctrl_z();
void del_node(int sig,siginfo_t *sip,void *notused);
void setflag();
void clean();
int perform_normal();
int perform_special();
struct result *direction;
char *argv[10][10];//store the parameters
int is_bg;
int echo_status=0;
int curpath;//store the current path number
int main()
{
char c,*path;
int input_len,is_pr,pid;
int i;
init_environ();
curpath=0;
while(1){
input_len=0;
is_bg=0;
new_flag=1;
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);
/*****Print the Prompt*****/
path=get_current_dir_name();
envpath[curpath]=(char *)malloc(strlen(path)+2);//?
strcpy(envpath[curpath],path);
strcat(envpath[curpath],"/");
envpath[curpath+1]=NULL;
printf("ysh@%s>",path);
/*****Get the user's input*****/
while((c=getchar()) == ' ' || c == '\t' || c == EOF)//EOF???
;
if(c == '\n')
continue;
while(c != '\n'){
buf[input_len++] = c;
c=getchar();
}
buf[input_len]='\0';
input = (char *)malloc(input_len+1);
strcpy(input,buf);
/*****Parse the Command*****/
analyze();
/*****Perform the command*****/
if(direction == NULL)
continue;
else{
/*Command:exit*/
if(strcmp(argv[0][0],"exit") == 0){
//while(head != NULL){
// kill(head->pid,SIGKILL);
// head=head->link;
//}
printf("GoodBye!\n");
clean();
break;
}
/*Command:jobs*/
if(strcmp(argv[0][0],"jobs") == 0){
jobs_cmd();
clean();
continue;
}
/*Command:fg*/
if(strcmp(argv[0][0],"fg") == 0){
if(argv[0][1][0] != '%'){
printf("error:the command 'fg' doesn't have the symbol '%'!\n");
clean();
continue;
}
for(i=0; argv[0][1][i] != '\0'; i++)
argv[0][1][i]=argv[0][1][i+1];
fg_cmd(atoi(argv[0][1]));
clean();
continue;
}
/*Command:bg*/
if(strcmp(argv[0][0],"bg") == 0){
if(argv[0][1][0] != '%'){
printf("error:the command 'bg' doesn't have the symbol '%'!\n");
clean();
continue;
}
for(i=0; argv[0][1][i] != '\0'; i++)
argv[0][1][i]=argv[0][1][i+1];
bg_cmd(atoi(argv[0][1]));
clean();
continue;
}
/*Command:echo*/
if(strcmp(argv[0][0],"echo") == 0){
if(strcmp(argv[0][1],"$status") == 0)
printf("%d\n",echo_status);
else
printf("error:the command 'echo' isn't written rightly!\n");
clean();
continue;
}
/*Command:cd*/
if(strcmp(argv[0][0],"cd") == 0){
cd_cmd(argv[0][1]);
clean();
continue;
}
if(direction->kind == 1){
if(is_founded(argv[0][0]) == 0){
printf("error:this command is not found!\n");
clean();
continue;
}
perform_normal();//no pipe
}else
perform_special();//with pipe
}
}
return 0;
}
/*****Initialize the program*****/
int getaline(int fd, char *buf)
{
int i=0;
char c;
while(read(fd,&c,1)){
buf[i++]=c;
if(c == '\n'){
buf[i-1]='\0';
return i;
}
}
return i;
}
void getenviron(int n,char *s)
{
int i,j,k;
char c,buff[80],*p;
i=k=j=0;
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(strlen(buff)+1);
strcpy(p,buff);
envpath[k++]=p;
envpath[k]=NULL;
curpath=k;
j=0;
i++;
}else{
buff[j]=s[i];
j++;
i++;
}
}
}else
printf("error:no match\n");
}
void init_environ()
{
int fd,n,i;
char buf[80];
if((fd=open("ysh_profile",O_RDONLY,660)) == -1){
printf("init environ variable error!\n");
exit(1);
}
envpath[0]=NULL;
curpath=0;
while(n=getaline(fd,buf))
getenviron(n,buf);
head=end=NULL;
}
/*****Implement Function:scan*****/
TokenType getToken()
{
int tokenStringIndex;
TokenType currentToken;
StateType state=START;
int save;
static int i;
char c;
tokenStringIndex=0;
if(new_flag == 1)
i=0;
while(state != DONE){
new_flag=0;
c=input[i++];
save=TRUE;
switch(state){
case START:
if( c == ' ' || c == '\t')
save = FALSE;
else
if(isdigit(c) || isalpha(c) || c == '_' || c == '.' || c == '%' || c == '$')
state=INSTRING;
else{
save=FALSE;
state=DONE;
switch(c){
case '<':
currentToken=INPUT;
break;
case '>':
currentToken=OUTPUT;
break;
case '|':
currentToken=PIPE;
break;
case '&':
currentToken=BACK;
break;
case '\0':
currentToken=END;
break;
default:
currentToken=ERROR;
printf("symbol %c can't be discerned!\n",c);
break;
}
}
break;
case INSTRING:
if(!isdigit(c) && !isalpha(c) && c != '_' && c != '.' && c != '%'){
state=DONE;
i--;
save=FALSE;
currentToken=STRING;
}
break;
default:
printf("Scanner Bug: state=%d\n",state);
state=DONE;
currentToken=ERROR;
break;
}
if(save && tokenStringIndex <= MaxLen)
tokenString[tokenStringIndex++]=c;
if(state == DONE)
tokenString[tokenStringIndex]='\0';
}
return currentToken;
}
void analyze()
{
StepMark step;
TokenType token;
int i,j;
step=BEGIN;
i=j=0;
direction=(struct result *)malloc(sizeof(struct result));
direction->filein=NULL;
direction->fileout=NULL;
argv[i][j]=NULL;
while(step != FINISH){
token=getToken();
switch(step){
case BEGIN:
if(token == STRING){
direction->kind=1;
step=PROGA;
direction->n=1;
argv[i][j]=(char *)malloc(strlen(tokenString)+1);
strcpy(argv[i][j++],tokenString);
argv[i][j]=NULL;
}else
if(token == END){
step=FINISH;
clean();
}else{
step=FINISH;
clean();
printf("error: the command can't be analyzed!\n");
}
break;
case PROGA:
switch(token){
case STRING:
argv[i][j]=(char *)malloc(strlen(tokenString)+1);
strcpy(argv[i][j++],tokenString);
argv[i][j]=NULL;
break;
case INPUT:
step=INR;
break;
case OUTPUT:
step=OUTR;
break;
case PIPE:
direction->kind=2;
step=PROGB;
argv[i][j]=(char *)malloc(1);//?????
argv[i][j++]=(char *)0;
argv[i][j]=NULL;
i++;
j=0
简单的shell C程序 源码 可执行文件
4星 · 超过85%的资源 需积分: 12 134 浏览量
2010-05-19
11:26:16
上传
评论
收藏 11KB RAR 举报
Iamtheodore
- 粉丝: 5
- 资源: 95
最新资源
- 基于图像的三维模型重建C++源代码+文档说明(高分课程设计)
- 基于聚焦法的工件立体测量方案,根据数据进行三维重建 使用HALCON处理图像,MATLAB拟合数据+源代码+数据集+效果图
- 锄战三国村 修改:货币使用不减 v1.10(2) 原创 (中文).apk
- 基于python实现的单目双目视觉三维重建+源代码+图像图片(高分课程设计)
- 基于C+++OPENCV的全景图像拼接源码(课程设计)
- 基于Python+OpenCV对多张图片进行全景图像拼接,消除鬼影,消除裂缝+源代码+文档说明+界面截图(高分课程设计)
- 基于C++实现的全景图像拼接源码(课程设计)
- 基于SIFT特征点提取和RASIC算法实现全景图像拼接python源码+文档说明+界面截图+详细注释(95分以上课程大作业)
- 基于matlab实现眼部判别的疲劳检测系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的异常姿势识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈