Commit 1e0b1296 authored by desiredeveloper's avatar desiredeveloper

reaping children in case of error

parent dda893a2
No preview for this file type
...@@ -3,365 +3,418 @@ ...@@ -3,365 +3,418 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#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: {
break; case -1:
case 0: break;
if(!strcmp(tokens[n-2],">>")) case 0:
fp = freopen(tokens[n-1],"a",stdout); if (!strcmp(tokens[n - 2], ">>"))
else if(!strcmp(tokens[n-2],">")) fp = freopen(tokens[n - 1], "a", stdout);
fp = freopen(tokens[n-1],"w",stdout); else if (!strcmp(tokens[n - 2], ">"))
else fp = freopen(tokens[n - 1], "w", stdout);
fp = freopen(tokens[n-1],"r",stdin); else
strcpy(temp,"/bin/"); fp = freopen(tokens[n - 1], "r", stdin);
strcat(temp,arglist[0]); strcpy(temp, "/bin/");
if(execv(temp,arglist)==-1){ strcat(temp, arglist[0]);
strcpy(temp,"/usr/bin/"); if (execv(temp, arglist) == -1)
strcat(temp,arglist[0]); {
execv(temp,arglist); strcpy(temp, "/usr/bin/");
} strcat(temp, arglist[0]);
free(temp); if(execv(temp, arglist)==-1)
exit(0);
}
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);
} }
// 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: {
break; case -1:
case 0: break;
strcpy(temp,"/bin/"); case 0:
strcat(temp,arglist[0]); strcpy(temp, "/bin/");
if(execv(temp,arglist)==-1){ strcat(temp, arglist[0]);
strcpy(temp,"/usr/bin/"); if (execv(temp, arglist) == -1)
strcat(temp,arglist[0]); {
execv(temp,arglist); strcpy(temp, "/usr/bin/");
} strcat(temp, arglist[0]);
free(temp); if(execv(temp, arglist)==-1)
exit(0);
}
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; arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char)*150); char *temp = (char *)malloc(sizeof(char) * 150);
if(!ioFlag){ if (!ioFlag)
switch (fork()) { {
case -1: switch (fork())
break; {
case 0: case -1:
strcpy(temp,"/bin/"); break;
strcat(temp,arglist[0]); case 0:
if(execv(temp,arglist)==-1){ strcpy(temp, "/bin/");
strcpy(temp,"/usr/bin/"); strcat(temp, arglist[0]);
strcat(temp,arglist[0]); if (execv(temp, arglist) == -1)
execv(temp,arglist); {
} strcpy(temp, "/usr/bin/");
free(temp); strcat(temp, arglist[0]);
if(execv(temp, arglist)==-1)
exit(0);
}
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; arglist[j] = NULL;
char *temp = (char *)malloc(sizeof(char)*150); char *temp = (char *)malloc(sizeof(char) * 150);
if(!ioFlag){ if (!ioFlag)
{
forkcalls++; forkcalls++;
switch (fork()) { switch (fork())
case -1: {
break; case -1:
case 0: break;
strcpy(temp,"/bin/"); case 0:
strcat(temp,arglist[0]); strcpy(temp, "/bin/");
if(execv(temp,arglist)==-1){ strcat(temp, arglist[0]);
strcpy(temp,"/usr/bin/"); if (execv(temp, arglist) == -1)
strcat(temp,arglist[0]); {
execv(temp,arglist); strcpy(temp, "/usr/bin/");
} strcat(temp, arglist[0]);
free(temp); if(execv(temp, arglist)==-1)
exit(0);
}
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
*/ */
char **tokenize(char *line) char **tokenize(char *line)
{ {
char **tokens = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char **tokens = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *));
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'){
token[tokenIndex] = '\0'; if (readChar == ' ' || readChar == '\n' || readChar == '\t')
if (tokenIndex != 0){ {
tokens[tokenNo] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); token[tokenIndex] = '\0';
strcpy(tokens[tokenNo++], token); if (tokenIndex != 0)
tokenIndex = 0; {
} tokens[tokenNo] = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char));
} else { strcpy(tokens[tokenNo++], token);
token[tokenIndex++] = readChar; tokenIndex = 0;
}
}
else
{
token[tokenIndex++] = readChar;
}
} }
}
free(token);
free(token); tokens[tokenNo] = NULL;
tokens[tokenNo] = NULL ; return tokens;
return tokens;
} }
int main(int argc, char *argv[])
{
char line[MAX_INPUT_SIZE];
char **tokens;
int i;
clock_t t1;
FILE *fp;
if (argc == 2)
{
fp = fopen(argv[1], "r");
if (fp < 0)
{
printf("File doesn't exists.");
return -1;
}
}
while (1)
{
int parallel = 0, serial = 0, background = 0, io = 0, cdir = 0;
int main(int argc, char* argv[]) { /* BEGIN: TAKING INPUT */
char line[MAX_INPUT_SIZE]; bzero(line, sizeof(line));
char **tokens; if (argc == 2)
int i; { // batch mode
clock_t t1; if (fgets(line, sizeof(line), fp) == NULL)
{ // file reading finished
FILE* fp; break;
if(argc == 2) { }
fp = fopen(argv[1],"r"); line[strlen(line) - 1] = '\0';
if(fp < 0) { }
printf("File doesn't exists."); else
return -1; { // interactive mode
}
}
while(1) {
int parallel=0,serial=0,background=0,io=0,cdir=0;
/* BEGIN: TAKING INPUT */
bzero(line, sizeof(line));
if(argc == 2) { // batch mode
if(fgets(line, sizeof(line), fp) == NULL) { // file reading finished
break;
}
line[strlen(line) - 1] = '\0';
} 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)
serial=strcmp(tokens[i],"&&")==0; if (!serial)
serial = strcmp(tokens[i], "&&") == 0;
if(!background)
background=strcmp(tokens[i],"&")==0; if (!background)
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
for(i=0;tokens[i]!=NULL;i++){
free(tokens[i]);
}
free(tokens);
} // Freeing the allocated memory
return 0; for (i = 0; tokens[i] != NULL; i++)
{
free(tokens[i]);
}
free(tokens);
}
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