Commit 1e0b1296 authored by desiredeveloper's avatar desiredeveloper

reaping children in case of error

parent dda893a2
No preview for this file type
...@@ -6,94 +6,106 @@ ...@@ -6,94 +6,106 @@
#include <time.h> #include <time.h>
#include <sys/wait.h> #include <sys/wait.h>
#define MAX_INPUT_SIZE 1024 #define MAX_INPUT_SIZE 1024
#define MAX_TOKEN_SIZE 64 #define MAX_TOKEN_SIZE 64
#define MAX_NUM_TOKENS 64 #define MAX_NUM_TOKENS 64
extern char **environ; extern char **environ;
void funcExit(){ void funcExit()
{
exit(0); exit(0);
} }
void funcEnv(){ void funcEnv()
{
int i; int i;
for (i = 0; environ[i] != NULL; i++) for (i = 0; environ[i] != NULL; i++)
printf("%s\n",environ[i]); printf("%s\n", environ[i]);
} }
void funcClear(){ void funcClear()
{
printf("\e[1;1H\e[2J"); printf("\e[1;1H\e[2J");
} }
void funcDir(char **tokens){ void funcDir(char **tokens)
char a[150]="ls -la "; {
system(strcat(a,tokens[1])); char a[150] = "ls -la ";
system(strcat(a, tokens[1]));
} }
void funcPwd(){ void funcPwd()
char *temp = (char *)malloc(sizeof(char)*150); {
getcwd(temp,150); char *temp = (char *)malloc(sizeof(char) * 150);
printf("%s:$ ",temp); getcwd(temp, 150);
printf("%s:$ ", temp);
free(temp); free(temp);
} }
void funcCd(char *fpath){ void funcCd(char *fpath)
{
char *temp = (char *)malloc(sizeof(char)*150); char *temp = (char *)malloc(sizeof(char) * 150);
getcwd(temp,150); getcwd(temp, 150);
if(fpath && chdir(fpath)!=0){ if (fpath && chdir(fpath) != 0)
{
printf("ERROR: Directory doesn't exist!\n"); printf("ERROR: Directory doesn't exist!\n");
return; return;
} }
printf("BEFORE:\nOLDPWD=%s\nPWD=%s\n",getenv("OLDPWD"),getenv("PWD")); printf("BEFORE:\nOLDPWD=%s\nPWD=%s\n", getenv("OLDPWD"), getenv("PWD"));
if(fpath){ if (fpath)
setenv("OLDPWD",temp,1); {
getcwd(temp,150); setenv("OLDPWD", temp, 1);
setenv("PWD",temp,1); getcwd(temp, 150);
setenv("PWD", temp, 1);
} }
else else
setenv("OLDPWD",temp,1); setenv("OLDPWD", temp, 1);
printf("AFTER:\nOLDPWD=%s\nPWD=%s\n",getenv("OLDPWD"),getenv("PWD")); printf("AFTER:\nOLDPWD=%s\nPWD=%s\n", getenv("OLDPWD"), getenv("PWD"));
free(temp); free(temp);
} }
void ioRedirect(char **tokens,int n){ void ioRedirect(char **tokens, int n)
{
FILE *fp; FILE *fp;
char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *));
int j=0; int j = 0;
for(int i=0;strcmp(tokens[i],">>") && strcmp(tokens[i],">") && strcmp(tokens[i],"<");i++){ for (int i = 0; strcmp(tokens[i], ">>") && strcmp(tokens[i], ">") && strcmp(tokens[i], "<"); i++)
arglist[j] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); {
strcpy(arglist[j++],tokens[i]); arglist[j] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
strcpy(arglist[j++], tokens[i]);
} }
arglist[j]=NULL; arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char)*150); char *temp = (char *)malloc(sizeof(char) * 150);
switch (fork()) { switch (fork())
{
case -1: case -1:
break; break;
case 0: case 0:
if(!strcmp(tokens[n-2],">>")) if (!strcmp(tokens[n - 2], ">>"))
fp = freopen(tokens[n-1],"a",stdout); fp = freopen(tokens[n - 1], "a", stdout);
else if(!strcmp(tokens[n-2],">")) else if (!strcmp(tokens[n - 2], ">"))
fp = freopen(tokens[n-1],"w",stdout); fp = freopen(tokens[n - 1], "w", stdout);
else else
fp = freopen(tokens[n-1],"r",stdin); fp = freopen(tokens[n - 1], "r", stdin);
strcpy(temp,"/bin/"); strcpy(temp, "/bin/");
strcat(temp,arglist[0]); strcat(temp, arglist[0]);
if(execv(temp,arglist)==-1){ if (execv(temp, arglist) == -1)
strcpy(temp,"/usr/bin/"); {
strcat(temp,arglist[0]); strcpy(temp, "/usr/bin/");
execv(temp,arglist); strcat(temp, arglist[0]);
if(execv(temp, arglist)==-1)
exit(0);
} }
free(temp); free(temp);
} }
wait(NULL); wait(NULL);
for(int i=0;arglist[i]!=NULL;i++) for (int i = 0; arglist[i] != NULL; i++)
free(arglist[i]); free(arglist[i]);
free(arglist); free(arglist);
...@@ -101,146 +113,168 @@ void ioRedirect(char **tokens,int n){ ...@@ -101,146 +113,168 @@ void ioRedirect(char **tokens,int n){
// http://www.linuxquestions.org/questions/programming-9/how-a-father-process-know-which-child-process-send-the-signal-sigchld-266290/ // http://www.linuxquestions.org/questions/programming-9/how-a-father-process-know-which-child-process-send-the-signal-sigchld-266290/
void handler(int sig){ void handler(int sig)
char *buffer = (char *)malloc(sizeof(char)*100); {
char *temp = (char *)malloc(sizeof(char)*150); char *buffer = (char *)malloc(sizeof(char) * 100);
char *temp = (char *)malloc(sizeof(char) * 150);
pid_t pid; pid_t pid;
pid = wait(NULL); pid = wait(NULL);
printf("\nBackground process [%d] finished.\n", pid); printf("\nBackground process [%d] finished.\n", pid);
signal(SIGCHLD, NULL); signal(SIGCHLD, NULL);
getcwd(temp,150); getcwd(temp, 150);
sprintf(buffer,"%s:$ ",temp); sprintf(buffer, "%s:$ ", temp);
write(1,buffer,50); write(1, buffer, 50);
free(temp); free(temp);
free(buffer); free(buffer);
} }
void exBackground(char **tokens,int n){ void exBackground(char **tokens, int n)
{
char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *));
int j=0; int j = 0;
for(int i=0;i<n;i++){ for (int i = 0; i < n; i++)
while(tokens[i]!=NULL && strcmp(tokens[i],"&")!=0 ){ {
arglist[j] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); while (tokens[i] != NULL && strcmp(tokens[i], "&") != 0)
strcpy(arglist[j++],tokens[i++]); {
arglist[j] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
strcpy(arglist[j++], tokens[i++]);
} }
arglist[j]=NULL; arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char)*150); char *temp = (char *)malloc(sizeof(char) * 150);
signal(SIGCHLD, handler); signal(SIGCHLD, handler);
switch (fork()) { switch (fork())
{
case -1: case -1:
break; break;
case 0: case 0:
strcpy(temp,"/bin/"); strcpy(temp, "/bin/");
strcat(temp,arglist[0]); strcat(temp, arglist[0]);
if(execv(temp,arglist)==-1){ if (execv(temp, arglist) == -1)
strcpy(temp,"/usr/bin/"); {
strcat(temp,arglist[0]); strcpy(temp, "/usr/bin/");
execv(temp,arglist); strcat(temp, arglist[0]);
if(execv(temp, arglist)==-1)
exit(0);
} }
free(temp); free(temp);
} }
j=0; j = 0;
} }
for(int i=0;arglist[i]!=NULL;i++) for (int i = 0; arglist[i] != NULL; i++)
free(arglist[i]); free(arglist[i]);
free(arglist); free(arglist);
} }
void exSerial(char **tokens,int n){ void exSerial(char **tokens, int n)
{
char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *));
int j=0; int j = 0;
for(int i=0;i<n;i++){ for (int i = 0; i < n; i++)
{
int ioFlag = 0; int ioFlag = 0;
while(tokens[i]!=NULL && strcmp(tokens[i],"&&")!=0 ){ while (tokens[i] != NULL && strcmp(tokens[i], "&&") != 0)
if(!ioFlag) {
ioFlag=strcmp(tokens[i],">>")==0 || strcmp(tokens[i],">")==0 || strcmp(tokens[i],"<")==0; if (!ioFlag)
arglist[j] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); ioFlag = strcmp(tokens[i], ">>") == 0 || strcmp(tokens[i], ">") == 0 || strcmp(tokens[i], "<") == 0;
strcpy(arglist[j++],tokens[i++]); arglist[j] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
} strcpy(arglist[j++], tokens[i++]);
arglist[j]=NULL; }
char *temp = (char *)malloc(sizeof(char)*150); arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char) * 150);
if(!ioFlag){
switch (fork()) { if (!ioFlag)
{
switch (fork())
{
case -1: case -1:
break; break;
case 0: case 0:
strcpy(temp,"/bin/"); strcpy(temp, "/bin/");
strcat(temp,arglist[0]); strcat(temp, arglist[0]);
if(execv(temp,arglist)==-1){ if (execv(temp, arglist) == -1)
strcpy(temp,"/usr/bin/"); {
strcat(temp,arglist[0]); strcpy(temp, "/usr/bin/");
execv(temp,arglist); strcat(temp, arglist[0]);
if(execv(temp, arglist)==-1)
exit(0);
} }
free(temp); free(temp);
} }
} }
else { else
ioRedirect(arglist,j); {
ioRedirect(arglist, j);
} }
wait(NULL); wait(NULL);
j=0; j = 0;
} }
for(int i=0;arglist[i]!=NULL;i++) for (int i = 0; arglist[i] != NULL; i++)
free(arglist[i]); free(arglist[i]);
free(arglist); free(arglist);
} }
void exParallel(char **tokens,int n){ void exParallel(char **tokens, int n)
{
char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char **arglist = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *));
int j=0,forkcalls=0; int j = 0, forkcalls = 0;
for(int i=0;i<n;i++){ for (int i = 0; i < n; i++)
{
int ioFlag = 0; int ioFlag = 0;
while(tokens[i]!=NULL && strcmp(tokens[i],"&&&")!=0 ){ while (tokens[i] != NULL && strcmp(tokens[i], "&&&") != 0)
if(!ioFlag) {
ioFlag=strcmp(tokens[i],">>")==0 || strcmp(tokens[i],">")==0 || strcmp(tokens[i],"<")==0; if (!ioFlag)
arglist[j] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); ioFlag = strcmp(tokens[i], ">>") == 0 || strcmp(tokens[i], ">") == 0 || strcmp(tokens[i], "<") == 0;
strcpy(arglist[j++],tokens[i++]); arglist[j] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
} strcpy(arglist[j++], tokens[i++]);
arglist[j]=NULL; }
char *temp = (char *)malloc(sizeof(char)*150); arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char) * 150);
if(!ioFlag){
if (!ioFlag)
{
forkcalls++; forkcalls++;
switch (fork()) { switch (fork())
{
case -1: case -1:
break; break;
case 0: case 0:
strcpy(temp,"/bin/"); strcpy(temp, "/bin/");
strcat(temp,arglist[0]); strcat(temp, arglist[0]);
if(execv(temp,arglist)==-1){ if (execv(temp, arglist) == -1)
strcpy(temp,"/usr/bin/"); {
strcat(temp,arglist[0]); strcpy(temp, "/usr/bin/");
execv(temp,arglist); strcat(temp, arglist[0]);
if(execv(temp, arglist)==-1)
exit(0);
} }
free(temp); free(temp);
} }
} }
else { else
ioRedirect(arglist,j); {
ioRedirect(arglist, j);
} }
j=0; j = 0;
} }
for(int i=0;i<forkcalls;i++) for (int i = 0; i < forkcalls; i++)
wait(NULL); wait(NULL);
for(int i=0;arglist[i]!=NULL;i++) for (int i = 0; arglist[i] != NULL; i++)
free(arglist[i]); free(arglist[i]);
free(arglist); free(arglist);
} }
/* Splits the string by space and returns the array of tokens /* Splits the string by space and returns the array of tokens
*/ */
...@@ -250,118 +284,137 @@ char **tokenize(char *line) ...@@ -250,118 +284,137 @@ char **tokenize(char *line)
char *token = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char)); char *token = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
int i, tokenIndex = 0, tokenNo = 0; int i, tokenIndex = 0, tokenNo = 0;
for(i =0; i < strlen(line); i++){ for (i = 0; i < strlen(line); i++)
{
char readChar = line[i]; char readChar = line[i];
if (readChar == ' ' || readChar == '\n' || readChar == '\t'){ if (readChar == ' ' || readChar == '\n' || readChar == '\t')
{
token[tokenIndex] = '\0'; token[tokenIndex] = '\0';
if (tokenIndex != 0){ if (tokenIndex != 0)
tokens[tokenNo] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); {
tokens[tokenNo] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
strcpy(tokens[tokenNo++], token); strcpy(tokens[tokenNo++], token);
tokenIndex = 0; tokenIndex = 0;
} }
} else { }
else
{
token[tokenIndex++] = readChar; token[tokenIndex++] = readChar;
} }
} }
free(token); free(token);
tokens[tokenNo] = NULL ; tokens[tokenNo] = NULL;
return tokens; return tokens;
} }
int main(int argc, char *argv[])
int main(int argc, char* argv[]) { {
char line[MAX_INPUT_SIZE]; char line[MAX_INPUT_SIZE];
char **tokens; char **tokens;
int i; int i;
clock_t t1; clock_t t1;
FILE* fp; FILE *fp;
if(argc == 2) { if (argc == 2)
fp = fopen(argv[1],"r"); {
if(fp < 0) { fp = fopen(argv[1], "r");
if (fp < 0)
{
printf("File doesn't exists."); printf("File doesn't exists.");
return -1; return -1;
} }
} }
while(1) { while (1)
int parallel=0,serial=0,background=0,io=0,cdir=0; {
int parallel = 0, serial = 0, background = 0, io = 0, cdir = 0;
/* BEGIN: TAKING INPUT */ /* BEGIN: TAKING INPUT */
bzero(line, sizeof(line)); bzero(line, sizeof(line));
if(argc == 2) { // batch mode if (argc == 2)
if(fgets(line, sizeof(line), fp) == NULL) { // file reading finished { // batch mode
if (fgets(line, sizeof(line), fp) == NULL)
{ // file reading finished
break; break;
} }
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
} else { // interactive mode }
else
{ // interactive mode
funcPwd(); funcPwd();
scanf("%[^\n]", line); scanf("%[^\n]", line);
getchar(); getchar();
} }
if(!strlen(line)) if (!strlen(line))
continue; continue;
/* END: TAKING INPUT */ /* END: TAKING INPUT */
line[strlen(line)] = '\n'; //terminate with new line line[strlen(line)] = '\n'; //terminate with new line
tokens = tokenize(line); tokens = tokenize(line);
for(i=0;tokens[i]!=NULL;i++){ for (i = 0; tokens[i] != NULL; i++)
if(!parallel) {
parallel=strcmp(tokens[i],"&&&")==0; if (!parallel)
parallel = strcmp(tokens[i], "&&&") == 0;
if(!serial) if (!serial)
serial=strcmp(tokens[i],"&&")==0; serial = strcmp(tokens[i], "&&") == 0;
if(!background) if (!background)
background=strcmp(tokens[i],"&")==0; background = strcmp(tokens[i], "&") == 0;
if(!io)
io=strcmp(tokens[i],">>")==0 || strcmp(tokens[i],">")==0 || strcmp(tokens[i],"<")==0;
if (!io)
io = strcmp(tokens[i], ">>") == 0 || strcmp(tokens[i], ">") == 0 || strcmp(tokens[i], "<") == 0;
} }
t1 = clock(); t1 = clock();
if(parallel) if (parallel)
exParallel(tokens,i); exParallel(tokens, i);
else if(serial) else if (serial)
exSerial(tokens,i); exSerial(tokens, i);
else if(background) else if (background)
exBackground(tokens,i); exBackground(tokens, i);
else if(io) else if (io)
ioRedirect(tokens,i); ioRedirect(tokens, i);
else { else
if(!strcmp(tokens[0],"dir") && i==2){ {
if (!strcmp(tokens[0], "dir") && i == 2)
{
funcDir(tokens); funcDir(tokens);
} }
else if(!strcmp(tokens[0],"clear")){ else if (!strcmp(tokens[0], "clear"))
{
funcClear(); funcClear();
} }
else if(!strcmp(tokens[0],"quit")){ else if (!strcmp(tokens[0], "quit"))
{
funcExit(); funcExit();
} }
else if(!strcmp(tokens[0],"env")){ else if (!strcmp(tokens[0], "env"))
{
funcEnv(); funcEnv();
} }
else if(!strcmp(tokens[0],"cd")){ else if (!strcmp(tokens[0], "cd"))
{
funcCd(tokens[1]); funcCd(tokens[1]);
} }
else{ else
{
system(line); system(line);
} }
} }
t1 = clock() - t1; t1 = clock() - t1;
printf("%f sec\n",(double)t1/CLOCKS_PER_SEC); printf("%f sec\n", (double)t1 / CLOCKS_PER_SEC);
// Freeing the allocated memory // Freeing the allocated memory
for(i=0;tokens[i]!=NULL;i++){ for (i = 0; tokens[i] != NULL; i++)
{
free(tokens[i]); free(tokens[i]);
} }
free(tokens); free(tokens);
} }
return 0; return 0;
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment