Esempio n. 1
0
/* execute build in command bg - send fg job to bg*/
static void bg_func(commandT* cmd){
  if (cmd->argc > 2)
  {
    PrintPError("Error: bg only takes one or no arguments");
  }

  if(bgjobs != NULL)
  {
    bgjobL *temp;
    if (cmd->argc == 1)//get most recent job
      temp = GetMostRecentJob();
    else if (FindJobId(atoi(cmd->argv[1])))
      temp = FindJobId(atoi(cmd->argv[1]));   //find job in list
    else
    {
      PrintPError("Error: job ID not found");
      return;
    }

    pid_t pid = temp->pid;
    kill(-pid, SIGCONT);  //send SIGCONT to job and all processes
    temp->status = RUNNING;
  }

}
Esempio n. 2
0
/*
 * Exec
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *   bool forceFork: whether to fork
 *
 * returns: none
 *
 * Executes a command.
 */
static void
Exec(commandT* cmd, bool forceFork)
{
  
  if (forceFork) { // Do this if you should fork
  int pid;
  sigset_t x;
  sigemptyset (&x);
  sigaddset(&x,SIGCHLD);
  if (sigprocmask(SIG_BLOCK,&x,NULL) != 0) {
    PrintPError("Signal Block Failure");
  }
    if ((pid = fork()) < 0) { // fork returns negative if it fails.
    PrintPError("Fork failed");
  } else {
      if (pid == 0) { // Child - to exec
        setpgid(0,0); // remove from foreground process group
        argZeroConverter(cmd);
        sigprocmask(SIG_UNBLOCK,&x,NULL);
        execv(cmd->name,cmd->argv);
          PrintPError("Execv failed");
      }
      else {  // Parent - wait for child to be reaped.
        fgpid = pid; // foreground process id
        int * status = malloc(sizeof(int));
        int * freethis = status;
        waitpid(pid,status,0);
        fgpid = 0;
        free(freethis);
      }
  }
  free(cmd->name);
  }
} /* Exec */
Esempio n. 3
0
int main (int argc, char *argv[])
{
  /* Initialize command buffer */
  char* cmdLine = malloc(sizeof(char*)*BUFSIZE);

  /* shell initialization */
  if (signal(SIGINT, sig_handler) == SIG_ERR) PrintPError("SIGINT");
  if (signal(SIGTSTP, sig_handler) == SIG_ERR) PrintPError("SIGTSTP");

  while (!forceExit) /* repeat forever */
  {
    /* read command line */
    getCommandLine(&cmdLine, BUFSIZE);

    if(strcmp(cmdLine, "exit") == 0)
    {
      forceExit=TRUE;
      continue;
    }
    //printf("after exit\n");
    /* checks the status of background jobs */
    //if(strcmp(cmdLine, "jobs") != 0){
    CheckJobs();
      //printf("after checkjobs\n");
    //}
    /* interpret command and line
     * includes executing of commands */
    Interpret(cmdLine);

  }

  /* shell termination */
  free(cmdLine);
  return 0;
} /* end main */
Esempio n. 4
0
/*
 * RunCmdRedirOut
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *   char *file: the file to be used for standard output
 *
 * returns: none
 *
 * Runs a command, redirecting standard output to a file.
 */
void
RunCmdRedirOut(commandT* cmd, char* file)
{
	int standardout = dup(1);
	int fileout = open(file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
	//write only. if not exists, create it. if exists, delete it. rwxr--r--
	
	if(fileout < 0){
		PrintPError("OpenOutFile");
		return;
	}
	close(1);	//close standard output
	if(dup(fileout) != 1){
		PrintPError("DupOutFile");
		return;
	}
	close(fileout);
	
	RunCmd(cmd);
	
	close(1);	//close redir out, and back to normal
	if(dup(standardout)!=1){
		PrintPError("DupStdOutFile");
		return;
	}
} /* RunCmdRedirOut */
Esempio n. 5
0
/*
 * RunCmdRedirIn
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *   char *file: the file to be used for standard input
 *
 * returns: none
 *
 * Runs a command, redirecting a file to standard input.
 */
void
RunCmdRedirIn(commandT* cmd, char* file)
{
	int standardin = dup(0);
	int filein = open(file, O_RDONLY);
	//write only. if not exists, create it. if exists, delete it. rwxr--r--
	
	if(filein < 0){
		PrintPError("OpenInFile");
		return;
	}
	close(0);	//close standard output
	if(dup(filein) != 0){
		PrintPError("DupInFile");
		return;
	}
	close(filein);
	
	RunCmd(cmd);
	
	close(0);	//close redir out, and back to normal
	if(dup(standardin)!=0){
		PrintPError("DupStdInFile");
		return;
	}
}  /* RunCmdRedirIn */
Esempio n. 6
0
static void Exec(commandT* cmd, bool forceFork)
{
  pid_t pid;
  //create sigset containing sigchld
  sigset_t chldsigset;
  sigemptyset(&chldsigset);
  sigaddset(&chldsigset, SIGCHLD);
  sigprocmask(SIG_BLOCK, &chldsigset, NULL);
  //fork child process
  pid = fork();
  if (pid >= 0)
  {
    if (pid == 0)   //execute cmd, exit child
    {
      setpgid(0,0);
      sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);
      if (execv(cmd->name, cmd->argv) < 0)
      {
        PrintPError("Error in executing the command");
      }
      exit(0);
    }
    else
    {
      if (!cmd->bg) //foreground, wait for foreground to finish
      {
        fgpid = pid;
        strcpy(fgcommands, cmd->cmdline);
        fgstatus = RUNNING;
        sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);

        while (fgstatus)
          sleep(1);
      }
      else //background
      {

        char * ampersand = "&";
        strcat(cmd->cmdline, ampersand);
        int jobnumber = AddJob(pid, RUNNING, cmd->cmdline, BGJOBL);
        if (jobnumber == 0)
          PrintPError("error adding job");
        sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);
      }
    }
  }
  else
  {
    PrintPError("Error in fork");
  }
}
Esempio n. 7
0
File: tsh.c Progetto: esun9064/tsh
int main (int argc, char *argv[])
{
  /* Initialize command buffer */
  char* cmdLine = malloc(sizeof(char*)*BUFSIZE);
  fgcommands = (char *) malloc(500 * sizeof(char));

  /* shell initialization */
  if (signal(SIGINT, sig) == SIG_ERR) PrintPError("SIGINT");
  if (signal(SIGTSTP, sig) == SIG_ERR) PrintPError("SIGTSTP");
  if (signal(SIGCHLD, sig) == SIG_ERR) PrintPError("SIGCHLD");

  // printPrompt();
 
     
  while (!forceExit) /* repeat forever */
  {
    //printPrompt();
    /* read command line */
    getCommandLine(&cmdLine, BUFSIZE);

    //cmdLine  = strdup(checkAlias2(cmdLine));

    //printf("The new is %s\n", cmdLine);
    if(strcmp(cmdLine, "exit") == 0 )
    {
      forceExit=TRUE;
      continue;
    }
    else if (feof(stdin)){
  //printf("\n");
  forceExit = TRUE;
        break;
  } 
    fgpid = 0;
    /* checks the status of background jobs */
    CheckJobs();

    /* interpret command and line
     * includes executing of commands */
    Interpret(cmdLine);
    //fflush(stdout);
    fgpid = 0;
  }

  /* shell termination */
  free(cmdLine);
  free(fgcommands);
  return 0;
} /* end main */
Esempio n. 8
0
/*
 * main
 *
 * arguments:
 *	 int argc: the number of arguments provided on the command line
 *	 char *argv[]: array of strings provided on the command line
 *
 * returns: int: 0 = OK, else error
 *
 * This sets up signal handling and implements the main loop of tsh.
 */
int main(int argc, char *argv[])
{
	/* Initialize command buffer */
	char* cmdLine = malloc(sizeof(char*) * BUFSIZE);

	/* shell initialization */
	if (signal(SIGINT, sig) == SIG_ERR)
		PrintPError("SIGINT");
	if (signal(SIGTSTP, sig) == SIG_ERR)
		PrintPError("SIGTSTP");

	while (!forceExit) /* repeat forever */ {
		char* prompt = getenv("PS1");
		if (prompt != NULL) {
			printf("%s", prompt);
		}
		
		/* read command line */
		getCommandLine(&cmdLine, BUFSIZE);

		if (strcmp(cmdLine, "exit") == 0)
			forceExit = TRUE;
		
		/* checks the status of background jobs */
		if (!forceExit) {
			CheckJobs();
		}

		/* interpret command and line
		 * includes executing of commands */
		Interpret(cmdLine);

	}

	bgjobL* curr = bgjobs;
	while (curr != NULL) {
		curr = bgjobs;
		int status;
		int res = waitpid(curr->pid, &status, WNOHANG | WUNTRACED | WCONTINUED);
		if (!(res == curr->pid && !WIFCONTINUED(status))) {
			kill(curr->pid, SIGKILL);
		}
		RemoveJob(curr->jid);
	}
	
	/* shell termination */
	free(cmdLine);
	return 0;
} /* main */
Esempio n. 9
0
int main (int argc, char *argv[])
{
    /* Initialize command buffer */
    char* cmdLine = malloc(sizeof(char*)*BUFSIZE);

    /* shell initialization */
    if (signal(SIGINT, sig_handler) == SIG_ERR) PrintPError("SIGINT");
    if (signal(SIGTSTP, sig_handler) == SIG_ERR) PrintPError("SIGTSTP");

    while (TRUE) /* repeat forever */
    {
        /* print prompt */
        printf("%%");
        //printf("my status: %d", waitpid(getpid(), &status, WNOHANG));
        //printf("%%");
        /* read command line */
        getCommandLine(&cmdLine, BUFSIZE);

        if(strcmp(cmdLine, "exit") == 0 || feof(stdin))
        {
            forceExit=TRUE;
            break;
        } else {
            // If we juse printf(cmdLine), compiler gives a warning because the cmdLine can contain things like  %s
            // and the program will try to find some string that does not exist. This could be exploited to run virus.
            //fprintf(stderr, "%s", cmdLine);
        }

        /* checks the status of background jobs */
        CheckJobs();

        /* interpret command and line
         * includes executing of commands */
        Interpret(cmdLine);
    }

    // make sure all the shell's child processes are terminated
    if (forceExit == TRUE) {
        while (bgjobs != NULL) {
            kill(bgjobs->pid, SIGINT);
            bgjobs = bgjobs->next;
        }
    }

    /* shell termination */
    free(cmdLine);
    return 0;
} /* end main */
Esempio n. 10
0
/*
 * RunBuiltInCmd
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *
 * returns: none
 *
 * Runs a built-in command.
 */
static void
RunBuiltInCmd(commandT* cmd)
{
  if (strcmp(cmd->argv[0],"echo") == 0) { // runs command echo
    int i;
    for(i = 1; i < cmd->argc; i++) {
      printf("%s ",cmd->argv[i]);
    }
    PrintNewline();
  }

  if (strcmp(cmd->argv[0],"cd") == 0) { // runs command cd
    int dir = 0;
    if (cmd->argc > 1) {
    dir = chdir(cmd->argv[1]);
    } else {
      dir = chdir(getenv("HOME"));
    }
      //0 if success, -1 if failure
  if (dir != 0) {
    PrintPError("cd error");
  }
  }
  if (strcmp(cmd->argv[0],"exit") == 0) { // escapes if command is exit
    return;
  }

} /* RunBuiltInCmd */
Esempio n. 11
0
/* bring background job to foreground */
static void fg_func(commandT* cmd){
  if (cmd->argc > 2)
  {  
    PrintPError("Error: fg only takes one or no arguments");
    return;
  }

  if (bgjobs != NULL)
  {
    bgjobL *temp;
    if (cmd->argc == 1)
      temp = GetMostRecentJob();
    else if (FindJobId(atoi(cmd->argv[1])))
      temp = FindJobId(atoi(cmd->argv[1]));
    else
    {
      PrintPError("Error: job ID not found");
      return;
    }


    fgpid = temp->pid;

    strcpy(fgcommands, temp->commands); //copy bg job cmdline to global fgcommands variable

    if (fgcommands[strlen(fgcommands) -1] == '&')   //remove &
    {
      fgcommands[strlen(fgcommands) -1] = '\0';
    }

    if (temp->status == STOPPED)  //send SIGCONT if bg job was stopped
      kill(-fgpid, SIGCONT);

    if (!RemoveJob(temp, BGJOBL, 1))    //remove from ll
      PrintPError("Error: Not a job");

    fgstatus = RUNNING;   
    while (fgstatus)    //wait for sigchld
    {
      sleep(1);
    }
  }

}
Esempio n. 12
0
char *
getFullPath(char * name) {
  bool found = FALSE;
  char * pathlist = getenv("PATH"); // prepare the memory for the possible paths
  char * home = getenv("HOME");
  char * homeCopy = malloc(MAXPATHLEN*sizeof(char*));
  strcpy(homeCopy,home);
  char * pathCopy = malloc(MAXPATHLEN*sizeof(char*));
  strcpy(pathCopy,pathlist);
  char * result = malloc(MAXPATHLEN*sizeof(char*)); // prepare memory to store the result
  char * current = getCurrentWorkingDir();
  strcat(homeCopy,"/");
  strcat(homeCopy,name);
  if (name[0] == '/') { // if it is an absolute path, store result.
    if (doesFileExist(name)) {
      strcpy(result,name);
      found = TRUE;
    }
  } else {
      if (doesFileExist(homeCopy)) { // If it is in the home directory
        strcpy(result,homeCopy);
        found = TRUE;
      }  else {
        strcat(current,"/");
        strcat(current,name);
        if (doesFileExist(current)) { // If it is in the current directory
          strcpy(result,current);
          found = TRUE;
        } else { // Else, check every path in PATH environment variable
          char* fullpath = strtok(pathCopy, ":");
            while (fullpath != NULL) {
              char * path = malloc(MAXPATHLEN*sizeof(char*));
              strcpy(path,fullpath);
              strcat(path,"/");
              if (doesFileExist(strcat(path,name))) {
                strcpy(result,path);
                found = TRUE;
              } 
              fullpath = strtok(NULL, ":");
              free(path);
            }
          }
      }
  }
free(current);
free(pathCopy);
free(homeCopy);
if (found) {
  return result;
} else {
  free(result);
  PrintPError(name);
  return NULL;
}
} /* getFullPath */
Esempio n. 13
0
/*
 * RunCmdPipe
 *
 * arguments:
 *   commandT *cmd1: the commandT struct for the left hand side of the pipe
 *   commandT *cmd2: the commandT struct for the right hand side of the pipe
 *
 * returns: none
 *
 * Runs two commands, redirecting standard output from the first to
 * standard input on the second.
 */
void
RunCmdPipe(commandT* cmd1, commandT* cmd2)
{
	int pipefp[2];
	int standardout = dup(1);
	int standardin  = dup(0);
	
	if(pipe(pipefp)==-1)PrintPError("Pipe Create Error");

	/*	redirect the cmd1 output to pipe	*/
	close(1);	//close standard output
	if(dup(pipefp[1]) != 1){
		PrintPError("Pipe Write");
		return;
	}
	close(pipefp[1]);
	
	RunCmd(cmd1);
	
	close(1);	//close redir out, and back to normal
	if(dup(standardout)!=1){
		PrintPError("DupStdOutFile");
		return;
	}
	
	/*	redirect the pipe to cmd2 input		*/
	close(0);	//close standard output
	if(dup(pipefp[0]) != 0){
		PrintPError("Pipe read");
		return;
	}
	close(pipefp[0]);
	
	RunCmd(cmd2);
	
	close(0);	//close redir out, and back to normal
	if(dup(standardin)!=0){
		PrintPError("DupStdInFile");
		return;
	}
	
} /* RunCmdPipe */
Esempio n. 14
0
/*
 * main
 *
 * arguments:
 *   int argc: the number of arguments provided on the command line
 *   char *argv[]: array of strings provided on the command line
 *
 * returns: int: 0 = OK, else error
 *
 * This sets up signal handling and implements the main loop of tsh.
 */
int
main(int argc, char *argv[])
{
  /* Initialize command buffer */
  char* cmdLine = malloc(sizeof(char*) * BUFSIZE);

  /* shell initialization */
  if (signal(SIGINT, sig) == SIG_ERR)
    PrintPError("SIGINT");
  if (signal(SIGTSTP, sig) == SIG_ERR)
    PrintPError("SIGTSTP");
    /* Terminated or stopped child */
  
  while (!forceExit) /* repeat forever */
    {
      /*Insert tsh$ prompt*/
      printPrompt();
      
      /* read command line */
      getCommandLine(&cmdLine, BUFSIZE);

      if (strcmp(cmdLine, "exit") == 0)
        forceExit = TRUE;
      
      /* checks the status of background jobs */
      if(!forceExit){
	CheckJobs();
	fflush(NULL);
      }
      /* interpret command and line
       * includes executing of commands */
      Interpret(cmdLine);
      fflush(NULL);
      //getPath();


    }

  /* shell termination */
  free(cmdLine);
  return 0;
} /* main */
Esempio n. 15
0
int main (int argc, char *argv[])
{
  /* Initialize command buffer */
  char* cmdLine = malloc(sizeof(char*)*BUFSIZE);

  /* shell initialization */
  if (signal(SIGINT, sig) == SIG_ERR) PrintPError("SIGINT");
  if (signal(SIGTSTP, sig) == SIG_ERR) PrintPError("SIGTSTP");
  if (signal(SIGCONT, sig) == SIG_ERR) PrintPError("SIGCONT");
  if (signal(SIGCHLD, sigHandler) == SIG_ERR) PrintPError("SIGCHLD");

  while (!forceExit) /* repeat forever */
  {
	printPrompt();
    /* read command line */
    getCommandLine(&cmdLine, BUFSIZE);

	// strcmp: string compare
    if(strcmp(cmdLine, "exit") == 0)
    {
      forceExit=TRUE;
      continue;
    }

    /* checks the status of background jobs */
    CheckJobs();

    /* interpret command and line
     * includes executing of commands */
    Interpret(cmdLine);

  }

  /* shell termination */
  free(cmdLine);
  releaseAlias(aliasList);
  /* print all lists and check 
  printf("\n\n ---------TERMINATE SHELL--------\n");
  printf("Alias:\n");
  printAlias();*/
  return 0;
} /* end main */
Esempio n. 16
0
/* handles redirect in */
void RunCmdRedirIn(commandT* cmd, char* file)
{
  //rcreate file, set inputstream to file
  int stdin = dup(0);
  int filein = open(file, O_RDONLY);
  close(0);
  if ( dup(filein) != 0)
  {
    PrintPError("Error dup filein: ");
    return;
  }
  close(filein);
  //run cmd with file as input
  RunCmd(&cmd, 1);
  close(0);
  //set input back to stdin
  if (dup(stdin) != 0)
  {
    PrintPError("Error dup stdin: ");
    return;
  }
}
Esempio n. 17
0
/* handles redirect out */
void RunCmdRedirOut(commandT* cmd, char* file)
{
  //create file, set ouputsrtream to file
  int stdout = dup(1);
  int fileout = open(file, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
  close(1);
  if (dup(fileout) != 1)
  {
    PrintPError("Error dup fileout: ");
    return;
  }
  close(fileout);
  //RunCmd with outputream as file
  RunCmd(&cmd, 1);
  close(1);
  //reset to stdout
  if (dup(stdout) != 1)
  {
    PrintPError("Error dup stdout: ");
    return;
  }

}
Esempio n. 18
0
/*
 * Job Functions
 */
int addjob(pid_t jobpid, int jobstatus, char* jobcommands, int whichlist) // Makes and adds job to the job list or done list and returns index of job
{
	int i = getnewindex(); // grab what the index should be
	bgjobL* temp;
	if (whichlist == _JOBLIST)
		temp = bgjobs; // temporary header
	else
		temp = donejobs;

	bgjobL* newJob = malloc(sizeof(bgjobL)); // malloc memory for new job
	if (newJob == NULL)
		PrintPError("Error in allocating memory for job");
	// Initialize new job
	newJob->pid = jobpid;
	newJob->status = jobstatus;
	newJob->commands = (char*)malloc(500*sizeof(char));
	newJob->index = i;
	strcpy(newJob->commands, jobcommands);
	newJob->next = NULL;

	if (temp == NULL) // start of list
	{
		if (whichlist == _JOBLIST)
			bgjobs = newJob; // move header
		else
			donejobs = newJob;
		return i;
	}
	else // something at start of list
	{
		while (TRUE)
		{
			if (temp->next == NULL)
			{
				temp->next = newJob;
				break;
			}
			temp = temp->next;
		}
		return i;
	}
}
Esempio n. 19
0
/*
 * RunCmdFork
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *   bool fg: whether to fg
 *
 * returns: none
 *
 * Runs a command, switching between built-in and external mode
 * depending on cmd->argv[0]
 */
void
RunCmdFork(commandT* cmd, bool fg)
{
  if (cmd->argc <= 0)
    return;
  if (IsBuiltIn(cmd->argv[0]))
	{
		RunBuiltInCmd(cmd);
	}
  else if (ResolveExternalCmd(cmd))
	{
		RunExternalCmd(cmd, fg);
	}
	else
	{
		char* temp = (char*)malloc(500*sizeof(char));
		char* unfoundCommand = cmd->argv[0];
		char* unresolvedCommand = "line 1: "; // does line 1 refer to error in first argument?
		strcpy(temp, unresolvedCommand);
		strcat(temp, unfoundCommand);
		PrintPError(temp);
		free(temp);
	}
} /* RunCmdFork */
Esempio n. 20
0
/*
 * RunBuiltInCmd
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *
 * returns: none
 *
 * Runs a built-in command.
 */
static void
RunBuiltInCmd(commandT* cmd)
{
	if (strcmp(cmd->argv[0], "pwd") == 0)
	{
		if (cmd->argc != 1) //something other than just pwd entered
			PrintPError("The command pwd takes no arguments.");
		else
			Print(currentdir);	
	}

	if (strcmp(cmd->argv[0], "cd") == 0) //cd needs to account for no argument, absolutes, and ..
	{
		// use cmd->argc (number or args including command cd) to switch between cases
		if (cmd->argc >= 3) // too many args
			PrintPError("The command cd takes one argument.");
		else if (cmd->argc == 1) // no arguments given, chdir to HOME directory
			{
				if (chdir(getenv("HOME")) < 0)
					PrintPError("Could not change directory.");
			}
		else
			if (*cmd->argv[1] == '/') // absolute path
				{
					if (chdir(cmd->argv[1]) < 0)
						PrintPError("Could not change directory.");
				}
			else if (*cmd->argv[1] == '.' && cmd->argv[1][1] == '.') // go back directories
			{
				char* tempPtr;
				tempPtr = cmd->argv[1]; // ptr to walk over argument counting how many directories to go back
				while (*tempPtr != '\0') // kind of a weak way to count, since we assume the user is putting periods
				{
					if (*tempPtr == '/') // skip the slashes
						tempPtr++;
					else
					{
						tempPtr += 2;
						if (chdir("..") < 0) //go back one directory
							PrintPError("Could not change directory.");
					}
				}
			}
			else // argument without . or / so chdir to currentdir + it
			{
				char* temp = (char*)malloc(500*sizeof(char));
				strcpy(temp, currentdir);
				strcat(temp, "/");
				strcat(temp, cmd->argv[1]);
				if (chdir(temp) < 0)
					PrintPError("Could not change directory.");
				free(temp);
			}		
	}
	if (strcmp(cmd->argv[0], "jobs") == 0)
	{
		bgjobL* temp = bgjobs;
		while (temp != NULL)
		{
			if (temp->status) // running
			{
				char* commands = (char*)malloc(500*sizeof(char));
				strcpy(commands, temp->commands);
				if (commands[strlen(commands) - 1] != '&')
				  strcat(commands, " &");
				printf("[%d]   Running                  %s\n", temp->index, commands);
				fflush(stdout);
				free(commands);
			}
			else
			{
				//char* commands = (char*)malloc(500*sizeof(char));
				//strcpy(commands, temp->commands);
				printf("[%d]   Stopped                  %s\n", temp->index, temp->commands);
				fflush(stdout);
				//free(commands);
			}
			temp = temp->next;
		}
	}
	if (strcmp(cmd->argv[0], "bg") == 0)
	{
		if (cmd->argc > 2) // too many args
		{
			PrintPError("bg takes one or no arguments");
			return;
		}

		//sigset_t chldsigset; // Initialize and set sigset for procmask
		//sigemptyset(&chldsigset);
		//sigaddset(&chldsigset, SIGCHLD);
		//sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs

		if (bgjobs != NULL)
		{
			bgjobL* temp;
			if (cmd->argc == 1) // default
				temp = getmostrecentjob();
			else if (findjobindex(atoi(cmd->argv[1])))
				temp = findjobindex( atoi(cmd->argv[1]) );
			else
			{
				PrintPError("Index outside of job bounds");
				return;
			}
			

			pid_t pid = temp->pid;
			kill(-pid, SIGCONT); // Send SIGCONT to the job and all processes
			temp->status = _RUNNING; // Set status to running
			
			
			//sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); //unmask
		}	
	}
	if (strcmp(cmd->argv[0], "fg") == 0)
	{
		if (cmd->argc > 2) // too many args
		{
			PrintPError("fg takes one or no arguments");
			return;
		}

		//sigset_t chldsigset; // Initialize and set sigset for procmask
		//sigemptyset(&chldsigset);
		//sigaddset(&chldsigset, SIGCHLD);
		//sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs

		if (bgjobs != NULL)
		{
			bgjobL* temp;
			if (cmd->argc == 1) // default
				temp = getmostrecentjob();
			else if (findjobindex(atoi(cmd->argv[1])))
				temp = findjobindex( atoi(cmd->argv[1]) );
			else
			{
				PrintPError("Index outside of job bounds");
				return;
			}
			
			fgpid = temp->pid; // set fg to pid of job
			strcpy(fgcommands, temp->commands); // copy commands to fgcommands
			fgcommands[strlen(fgcommands) - 1] = 0;
			
			if (temp->status == _STOPPED) // if stopped, SIGCONT it to get it running again
				kill(-fgpid, SIGCONT);

			// remove from job list
			if ( !removejob(temp, _JOBLIST, 1) )
				PrintPError("Not a job");

			//sigprocmask(SIG_UNBLOCK, &chldsigset, NULL); //unmask
			fgstatus = _RUNNING;
			// Now wait on it with a busy loop
			while (fgstatus)
			{
				sleep(1);
			}
		}	
	}
	if (strcmp(cmd->argv[0], "alias") == 0){
		aliasL* temp=aliaslist;
		aliasL* previousalias=aliaslist;
		if(cmd->argc==1)/*	show all the alias	*/
		{
			if (temp == NULL) // start of list
			{
				;
			}
			else // something at start of list
			{
				while (TRUE)
				{
					if(temp!=NULL){
						int i;
						for( i = 0; temp->aliascmdline[i] != 0; ++i)
						{
							if(i==0)printf("alias ");
							putchar(temp->aliascmdline[i]);
							if(temp->aliascmdline[i]=='=')putchar('\'');
							if(temp->aliascmdline[i+1]==0)puts("\'");
						}
						//printf("alias %s\n",temp->aliascmdline);
					}
					if (temp->next == NULL)
					{
						break;
					}
					temp = temp->next;
				}
			}
			
		}
		else{
			aliasL* newalias = malloc(sizeof(aliasL)); // malloc memory for new alias
			if (newalias == NULL){
				PrintPError("Error in allocating memory for alias");
				return;
			}

			// Initialize new alias
			newalias->aliascmdline = (char*)malloc(strlen(cmd->argv[1]+1));
			if (newalias->aliascmdline == NULL){
				PrintPError("Error in allocating memory for alias");
				return;
			}
			strcpy(newalias->aliascmdline, cmd->argv[1]);
			newalias->next = NULL;

			if (temp == NULL) // start of list
			{
				aliaslist=newalias;
			}
			else // something at start of list
			{
				while (TRUE)
				{
					if(strcmp(cmd->argv[1],temp->aliascmdline)<=0)//we find the small one, so insert it
					{
						if( previousalias!=aliaslist)previousalias->next=newalias;
						newalias->next=temp;
						if( previousalias==aliaslist)aliaslist=newalias;
						break;
						
					}
					else if (temp->next == NULL)
					{
						temp->next = newalias;
						break;
					}

					previousalias = temp;
					temp = temp->next;
				}
			}
		}
		
	}
	if (strcmp(cmd->argv[0], "unalias") == 0){
		aliasL* temp=aliaslist;
		aliasL* previousalias=aliaslist;
		if(cmd->argc==1)// do nothing
		{
			;
		}
		else
		{
			while (TRUE)
			{
				if( ( temp != NULL ) && (strncmp(cmd->argv[1],temp->aliascmdline,strlen(cmd->argv[1]))==0) )// we find the alias, so unalias it
				{
					previousalias->next = temp->next;
					if(temp==aliaslist)aliaslist=temp->next;
					free(temp->aliascmdline);
					free(temp);
					break;
				}
				if ( ( temp == NULL ) || (temp->next == NULL) )
				{
					printf("%s: unalias: %s: not found\n",SHELLNAME,cmd->argv[1]);
					//PrintPError(cmd->argv[1]);
					break;
				}
				previousalias = temp;
				temp = temp->next;
			}
		}
	}
} /* RunBuiltInCmd */
Esempio n. 21
0
/*
 * Exec
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *   bool fg: whether to fg
 *
 * returns: none
 *
 * Executes a command.
 */
void
Exec(commandT* cmd, bool fg)
{
	// Fork and execute the command using filedir as command and cmd->argv as arguments
	int pid;
	sigset_t chldsigset; // Initialize and set sigset for procmask
	sigemptyset(&chldsigset);
	sigaddset(&chldsigset, SIGCHLD);
	sigprocmask(SIG_BLOCK, &chldsigset, NULL); // mask SIGCHLDs

	char* commands = (char*)malloc(500*sizeof(char));
	int i = 0;
	while (cmd->argv[i] != 0) // traverse commands and copy into one new jobcommands string
	{
	  int j = 0; int insertquotes = 0;
	  while (cmd->argv[i][j] != 0)
	  {
	    if (cmd->argv[i][j] == ' ') // if there are spaces in a single command
	      insertquotes = 1;
	    j++;
	  }
	  if (i == 0)
		  strcpy(commands, cmd->argv[i]);
	  else
		{
		 	strcat(commands, " ");
			if (insertquotes)
			  strcat(commands, "\"");
			strcat(commands, cmd->argv[i]);
			if (insertquotes)
			  strcat(commands, "\"");
		}
		i++;
	}

	pid = fork();
	if (pid >= 0) // fork succeeds
	{
		if (pid == 0) // child process
		{
			setpgid(0,0);
			// Unblock SIGCHLD first
			sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);			
			// Child will execv the command
			if (execv(filedir, cmd->argv) < 0)
				PrintPError("Error in executing the command");
			exit(0);
		}
		else // parent wait if fg set
		{
			if (fg) {
				fgpid = pid; //set global fgpid to current pid
				strcpy(fgcommands, commands);
				fgstatus = _RUNNING; // start fgstatus to _RUNNING

				// Unblock SIGCHLD before busy loop
				sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);

				while (fgstatus)
				{
					sleep(1);
				}
			}
			else // bg
			{
				char* ampersand = " &";
				strcat(commands, ampersand);
					
				int jobnumber = addjob(pid, _RUNNING, commands, _JOBLIST);
				if (jobnumber == 0)
					PrintPError("Error in adding job");
			
				// Unblock SIGCHLD after adding to job list
				sigprocmask(SIG_UNBLOCK, &chldsigset, NULL);
			}
		}
	}
	else // fork errors
	{
		PrintPError("Error in fork");
	}
	free(commands);	
} /* Exec */
Esempio n. 22
0
File: tsh.c Progetto: esun9064/tsh
static void sig(int signo)
{

  if (signo == SIGINT)
  {
    if (fgpid)
    {
      kill(-fgpid, SIGINT); //send sigint to foreground job
      //printf("\n");
    }
  }
  if (signo == SIGCHLD)
  {
    int status;
    pid_t chldpid;
    chldpid = waitpid(-1, &status, WUNTRACED | WNOHANG);   ///wait on child

    if (chldpid == fgpid)     //sigchld send from foreground process
    {
      fgstatus = STOPPED;
    }
    else if (WIFEXITED(status) || WIFSIGNALED(status)) //sigchld send from bg
    {
      if (FindJobPid(chldpid) == NULL)    //not in bgjobl
        return;
      //get id, print message if bg job terminated with error
      int id = FindIdPid(chldpid);

      if (WIFSIGNALED(status))      //terminated with error
      {
        printf("[%d] terminated with status %d   PID: %d\n", id, WTERMSIG(status), chldpid);
        //fflush(stdout);
      }
      //remove finished bg job from list, put in done jobs
      if (!RemoveJob(FindJobPid(chldpid), BGJOBL, 0))
        PrintPError("SIGCHLD from child failed");
    }
  }
  if (signo == SIGTSTP)   //sigstp signal encountered, add foreground job to bgjobs ll
  {
    if (fgpid != 0)
    {
      int id;
      if (GetMostRecentJob() == NULL)
        id = 1;
      else
      {
        bgjobL *temp;
        temp = GetMostRecentJob();  //get most recent bg job
        id = FindIdPid(temp->pid);  //use its pid to find id, increment to get id of new bg job
        id++;
      }
      printf("[%d]   Stopped                 %s\n", id, fgcommands);
      fflush(stdout);

      int i = AddJob(fgpid, STOPPED, fgcommands, BGJOBL); //add stopped job to bgjobl
      kill(-fgpid, SIGTSTP);
      if (i == 0)
      {
        PrintPError("Error adding job");
      }
    }
  }

}
Esempio n. 23
0
/*
 * ResolveExternalCmd
 *
 * arguments:
 *   commandT *cmd: the command to be run
 *
 * returns: bool: whether the given command exists
 *
 * Determines whether the command to be run actually exists.
 */
static bool
ResolveExternalCmd(commandT* cmd, char* path)
{
  //printf("Command: %s\n", cmd->name);
  //Check to see if in home directory:
  if(*(cmd->argv[0])=='.'){
    
    char* cwd = getCurrentWorkingDir();
    //char* cwd;
    //getCurrentWorkingDir(cwd);
    sprintf(path,"%s/%s",cwd,cmd->name);
    free(cwd);
    return TRUE;

  }

  char** memLocs = getPath();
 
  char dest[500];
  int i=0;
  struct stat buf;


 /*If already absolute path*/
 if(stat(cmd->name,&buf)==0){
   
   /*Set path = to entered absolute path*/
   strcpy(path,cmd->name);
   freePath(memLocs);
   return TRUE;

  }

  while(memLocs[i]!=NULL){
    //Concatanate Paths with cmd->name:
    int size = (snprintf( dest, 499,"%s/%s",memLocs[i],cmd->name)+1)*sizeof(char);
    char* exeName =  (char*)malloc(size);
    sprintf(exeName,"%s/%s",memLocs[i],cmd->name);
    //printf("%s/%s\n", memLocs[i], cmd->name); 
    //Check to see if exists and executable:
    if(stat(exeName,&buf)==0){
      if(S_ISREG(buf.st_mode) && buf.st_mode & 0111){
         
         strncpy(path,exeName,size);
         
         freePath(memLocs);
         free(exeName);
         return TRUE;
      }
       
      char* error = malloc(PATHSIZE * sizeof(char*));
      strcpy(error, "line 1: "); //since script reading is not in the functionality, it will be an error on line 1
      strcat(error, cmd->argv[0]);
      PrintPError(error);
      free(error);

      freePath(memLocs);
      free(exeName);
      return FALSE;
    } 
    
    i++;
    free(exeName);
  }
  
  char* error = malloc(PATHSIZE * sizeof(char*));
  strcpy(error, "line 1: "); //since script reading is not in the functionality, it will be an error on line 1
  strcat(error, cmd->argv[0]);
  PrintPError(error);
  free(error);

  freePath(memLocs);
  return FALSE;
} /* ResolveExternalCmd */