#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
extern char **getline();
main(int argc, char *argv[], char *envp[]) {
char **args;
static char p[39]="> ";
pid_t pid;
FILE *fp;
int BG = 0;
while(1) {
fprintf(stderr,"user@user-laptop:%s%s",getcwd(NULL,NULL),p);
args = getline();
int jj = 0;
if(strcmp(*args,"cd") == 0){ //implement the "cd" function, so that you can enjoy your work at
chdir(*(args + 1)); //different directories that you want.
}
while(*(args+jj) != NULL)
jj++;
jj--; //*(args+j) indicating the last char of the line.
int status; //a flag indicates wether it is a background process.
switch(pid = fork()){ //fork a new child process.
case -1:
printf("Unable to fork. Will now exit./n");
break;
case 0:
if(strcmp(*args,"help")==0){
printf("Most of the linux command has been implemented.../n");
printf("Although it is not perfect.../n");
}
else if(strcmp(*args,"add")==0){//sum-result of the addition, i-iterator of the array "args".
//printf("--- argc= %d%d%d ,args= ",segs,start,end);
//the command of "add".
int sum=0;int i=1;
while(*(args+i)!=NULL){ //loop part.
if(i==1) printf("--- ");
if(i>=2) printf(" + ");
printf(*(args+i));
if((*(args+i))[0]=='0'&&(*(args+i))[1]=='x'){//check and convert heximal number to decimal.
int length=2;char temp=(*(args+i))[2];
while(temp!='/0'){length++;temp=(*(args+i))[length];}
int index=2;int hex=0;
while(index<length){
double exp=length-index-1;
if((*(args+i))[index]-48<=9)
hex=hex+((*(args+i))[index]-48)*(int)pow((double)16,exp);
else hex=hex+((*(args+i))[index]-96+9)*(int)pow((double)16,exp);
index++;
}
sum=sum+hex;
}//end if.
else
sum=sum+atoi(*(args+i));
i++;
}
printf(" = %d ---/n",sum);
//end the command of "add"
}
else if(strcmp(*args,"arg")==0){ //the "arg" function.
int tag[20]={0};
int i=0;int segs=0;
while(*(args+i)!=NULL){
if(strcmp(*(args+i),"/"")==0)
tag[i]=1;
i++;
}
printf("--- args = ");
int start=0;int end=0;int temp=0;int index=0;
while(index<i){
if(tag[index]==1){
if(start==0) {start=index;}
else{end=index;segs=segs-(end-start);start=0;}
}
if(index>0){
printf(*(args+index));
if(start==0) printf(", ");
else printf(" ");
}
index++;segs++;
}
printf(" argc is %d ---/n",segs-1);
}
else{
int choice = 0;
int i = 0;
while(*(args+i) != NULL){ //get data from files and do something.
if(strcmp(*(args+i),"<") == 0){
if(strcmp(*(args + jj),"&")==0)
*(args + jj) = '/0';
execvp(*args,args + 1);
}
i ++;
}
i = 0;
while(*(args+i) != NULL){
if(strcmp(*(args+i),">") == 0){ //output data to files.
if(strcmp(*(args + jj),"&")==0)
*(args + jj) = '/0';
args[i]='/0';
choice=1;
freopen(*(args+1+i),"w",stdout);
execvp(*args,args);
fclose(stdout); //return the standard outputstream to screen.
}
i ++;
}
i = 0;
while(*(args+i) != NULL){ //using pipe
if(strcmp(*(args+i),"|") == 0){
choice = 2;
args[i]='/0';
int pp[2]; //pp[2] are for the argments to pass signals.
pipe(pp);
pid_t pid2 = fork();
if(pid2 == 0){
close(pp[0]);
close(1);
dup(pp[1]);
execvp(*args,args);
}
else{ //waiting for child.
waitpid(pid2,NULL,0);
close(pp[1]);
}
pid_t pid3 = fork();
if(pid3 == 0){ //child 2 to do using information of child 1.
close(pp[1]);
close(0);
dup(pp[0]);
execvp(*(args+i+1),args+i+1);
}
else{
waitpid(pid3,NULL,0);
close(pp[0]);
}
}
i++;
}//end while
if(choice == 0){
if(strcmp(*(args + jj), "&") == 0)
*(args + jj)='/0';
execvp(*args,args);}
}
return;
break;
default:
//put it to the background to exec.
if(strcmp(*(args + jj), "&") != 0){
waitpid(pid,NULL,0);
}
//exit.
if(strcmp(*args,"exit")==0)
return;
}//end switch
}//end while
}
/*lex.c use flex to convert*/
%{
int _numargs = 100;
char *_args[100];
int _argcount = 0;
%}
WORD [a-zA-Z0-9///.-]+
SPECIAL [()><|&;*/"]
%%
_argcount = 0;
_args[0] = NULL;
{WORD}|{SPECIAL} {
if(_argcount < _numargs-1) {
_args[_argcount++] = (char *)strdup(yytext);
_args[_argcount] = NULL;
}
}
/n return (int)_args;
[ /t]+
.
%%
char **getline() {
return (char **)yylex();
}