#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include "rio.h"
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
void handler(){
int status;
while(waitpid(-1,&status,0)>0){//回收所有终止子进程
}
return;
}
int try_to_exec(char*buf){
char temp;
int line_len=strlen(buf);
int p=0;
int cnt=0;
int flag=0;//0代表之前的字符是 空格 1代表非空格
for(p=0;p<=line_len;p++){
temp=*(buf+p);
if(temp=='\0'||temp==' '){
if(flag==0){
}else{
cnt++;
flag=0;
}
}else{
if(flag==0){
flag=1;
}else{
}
}
}//知道有多少个子段
int argc=cnt;
char**argv=(char**)malloc(sizeof(char*)*(cnt+1));//cnt+1 最后一个为null
cnt=0;
int start=0;
int child_len=0;
for(p=0;p<=line_len;p++){
temp=*(buf+p);
if(temp=='\n'){
if(flag==0){
}else{
char* temp1=(char*)malloc(sizeof(char)*(child_len+1));//child_len+1,结尾有'\0'
memcpy(temp1,buf+start,child_len);
temp1[child_len]='\0';
argv[cnt]=temp1;
cnt++;
flag=0;
}
break;
}
if(temp=='\0'||temp==' '){
if(flag==0){
}else{
char* temp1=(char*)malloc(sizeof(char)*(child_len+1));//child_len+1,结尾有'\0'
memcpy(temp1,buf+start,child_len);
temp1[child_len]='\0';
argv[cnt]=temp1;
cnt++;
flag=0;
}
}else{
if(flag==0){
child_len=1;
start=p;
flag=1;
}else{
child_len++;
}
}
}
argv[argc]=NULL;//标识结尾
pid_t p1=fork();
int status;
if(p1==0){//子进程
int i;
int fd;
for(i=0;i<argc-1;i++){
if(strcmp(argv[i],">")==0){
fd=open(argv[i+1],O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
if(fd<0){
printf("no such file!\n");
exit(1);
}
dup2(fd,STDOUT_FILENO);//重定向输出 将描述符表里fd文件条目对应的
//内容复制到STDOUT条目里,实现了I/O
}
}
if(strcmp(argv[argc-1],"&")==0){//关闭终端显示
close(STDOUT_FILENO);
}
if(execve(argv[0],argv,__environ)<0){
printf("executable file does not exits!\n");
exit(1);
}
}
if(strcmp(argv[argc-1],"&")==0){//后台运行
}else{
waitpid(-1,&status,0);
}
return argc;
}
int main(){
signal(SIGCHLD,handler);
rio_t std_int_rio;
rio_init(STDIN_FILENO,&std_int_rio);
char buf[MAX_RIO_BUF_SIZE];
while(1){
rio_readLineb(&std_int_rio,buf,MAX_RIO_BUF_SIZE);
int a=try_to_exec(buf);
}
}