Пример #1
0
int main() 
{
	init_dsh();
	DEBUG("Successfully initialized\n");

	while(1) {
    job_t *j = NULL;
    if(!(j = readcmdline(promptmsg(getpid())))) {
			if (feof(stdin)) { /* End of file (ctrl-d) */
        fflush(stdout);
        printf("\n");
        exit(EXIT_SUCCESS);
      }
			continue; /* NOOP; user entered return or spaces with return */
    }

        /* Only for debugging purposes to show parser output; turn off in the
         * final code */
    // if(PRINT_INFO) print_job(j);

        /* Your code goes here */
        /* You need to loop through jobs list since a command line can contain ;*/
        /* Check for built-in commands */
        /* If not built-in */
            /* If job j runs in foreground */
            /* spawn_job(j,true) */
            /* else */
            /* spawn_job(j,false) */

    while (j != NULL)
    {
      // if EOF builtincmd of quit
      //active jobs is last job?

      // if not a command at all ?
      bool is_built_in_cmd = builtin_cmd(j, (j->first_process)->argc, (j->first_process)->argv);
      if(!is_built_in_cmd) 
      {

        if(j->bg == true)
        {
          spawn_job(j, false);
        }
        else
        {
          spawn_job(j, true);
        }

        if(active_jobs_head == NULL) 
        {
        active_jobs_head = j;
        
        }

        else 
        {
        job_t *lastJob = find_last_job(active_jobs_head);
        lastJob->next = j;
        j->next = NULL;

        }
      }

      j = j->next;
    }
  }
}
Пример #2
0
Файл: dsh.c Проект: bsb20/dsh
bool readcmdline(char *msg) {
	
    print_colored_prompt(stdout, msg);

	char *cmdline = (char *)calloc(MAX_LEN_CMDLINE, sizeof(char));
	if(!cmdline)
		return invokefree(NULL, "malloc: no space");
	fgets(cmdline, MAX_LEN_CMDLINE, stdin);

	/* sequence is true only when the command line contains ; */
	bool sequence = false;
	/* seq_pos is used for storing the command line before ; */
	int seq_pos = 0;

	int cmdline_pos = 0; /*iterator for command line; */

	while(1) {
		job_t *current_job = find_last_job();
		int cmd_pos = 0; /* iterator for a command */
		int iofile_seek = 0; /*iofile_seek for file */
		bool valid_input = true; /* check for valid input */
		bool end_of_input = false; /* check for end of input */

		/* cmdline is NOOP, i.e., just return with spaces*/
		while (isspace(cmdline[cmdline_pos])){++cmdline_pos;} /* ignore any spaces */
		if(cmdline[cmdline_pos] == '\n' || cmdline[cmdline_pos] == '\0' || feof(stdin))
			return false;
		
		if (cmdline[cmdline_pos] == '#') //no commands, just a comment
			return false;

                /* Check for invalid special symbols (characters) */
                if(cmdline[cmdline_pos] == ';' || cmdline[cmdline_pos] == '&'
                        || cmdline[cmdline_pos] == '<' || cmdline[cmdline_pos] == '>' || cmdline[cmdline_pos] == '|')
                        return false;

		char *cmd = (char *)calloc(MAX_LEN_CMDLINE, sizeof(char));
		if(!cmd)
			return invokefree(NULL,"malloc: no space");

		job_t *newjob = (job_t *)malloc(sizeof(job_t));
		if(!newjob)
			return invokefree(NULL,"malloc: no space");

		if(!first_job)
			first_job = current_job = newjob;
		else {
			current_job->next = newjob;
			current_job = current_job->next;
		}

		if(!init_job(current_job))
			return invokefree(current_job,"init_job: malloc failed");

		process_t *current_process = find_last_process(current_job);

		while(cmdline[cmdline_pos] != '\n' && cmdline[cmdline_pos] != '\0') {

			switch (cmdline[cmdline_pos]) {
								
			    case '<': /* input redirection */
				current_job->ifile = (char *) calloc(MAX_LEN_FILENAME, sizeof(char));
				if(!current_job->ifile)
					return invokefree(current_job,"malloc: no space");
				++cmdline_pos;
				while (isspace(cmdline[cmdline_pos])){++cmdline_pos;} /* ignore any spaces */
				iofile_seek = 0;
				while(cmdline[cmdline_pos] != '\0' && !isspace(cmdline[cmdline_pos])){
					if(MAX_LEN_FILENAME == iofile_seek)
						return invokefree(current_job,"input redirection: file length exceeded");
					current_job->ifile[iofile_seek++] = cmdline[cmdline_pos++];
				}
				current_job->ifile[iofile_seek] = '\0';
				current_job->mystdin = INPUT_FD;
				while(isspace(cmdline[cmdline_pos])) {
					if(cmdline[cmdline_pos] == '\n')
						break;
					++cmdline_pos;
				}
				valid_input = false;
				break;
			
			    case '>': /* output redirection */
				current_job->ofile = (char *) calloc(MAX_LEN_FILENAME, sizeof(char));
				if(!current_job->ofile)
					return invokefree(current_job,"malloc: no space");
				++cmdline_pos;
				while (isspace(cmdline[cmdline_pos])){++cmdline_pos;} /* ignore any spaces */
				iofile_seek = 0;
				while(cmdline[cmdline_pos] != '\0' && !isspace(cmdline[cmdline_pos])){
					if(MAX_LEN_FILENAME == iofile_seek) 
						return invokefree(current_job,"input redirection: file length exceeded");
					current_job->ofile[iofile_seek++] = cmdline[cmdline_pos++];
				}
				current_job->ofile[iofile_seek] = '\0';
				current_job->mystdout = OUTPUT_FD;
				while(isspace(cmdline[cmdline_pos])) {
					if(cmdline[cmdline_pos] == '\n')
						break;
					++cmdline_pos;
				}
				valid_input = false;
				break;

			   case '|': /* pipeline */
				cmd[cmd_pos] = '\0';
				process_t *newprocess = (process_t *)malloc(sizeof(process_t));
				if(!newprocess)
					return invokefree(current_job,"malloc: no space");
				if(!init_process(newprocess))
					return invokefree(current_job,"init_process: failed");
				if(!current_job->first_process)
					current_process = current_job->first_process = newprocess;
				else {
					current_process->next = newprocess;
					current_process = current_process->next;
				}
				if(!readprocessinfo(current_process, cmd))
					return invokefree(current_job,"parse cmd: error");
				++cmdline_pos;
				cmd_pos = 0; /*Reinitialze for new cmd */
				valid_input = true;	
				break;

			   case '&': /* background job */
				current_job->bg = true;
				while (isspace(cmdline[cmdline_pos])){++cmdline_pos;} /* ignore any spaces */
				if(cmdline[cmdline_pos+1] != '\n' && cmdline[cmdline_pos+1] != '\0')
					fprintf(stderr, "reading bg: extra input ignored");
				end_of_input = true;
				break;

			   case ';': /* sequence of jobs*/
				sequence = true;
				strncpy(current_job->commandinfo,cmdline+seq_pos,cmdline_pos-seq_pos);
				seq_pos = cmdline_pos + 1;
				break;	
                
			   case '#': /* comment */
				end_of_input = true;
				break;

			   default:
				if(!valid_input)
					return invokefree(current_job,"reading cmdline: could not fathom input");
				if(cmd_pos == MAX_LEN_CMDLINE-1)
					return invokefree(current_job,"reading cmdline: length exceeds the max limit");
				cmd[cmd_pos++] = cmdline[cmdline_pos++];
				break;
			}
			if(end_of_input || sequence)
				break;
		}
		cmd[cmd_pos] = '\0';
		process_t *newprocess = (process_t *)malloc(sizeof(process_t));
		if(!newprocess)
			return invokefree(current_job,"malloc: no space");
		if(!init_process(newprocess))
			return invokefree(current_job,"init_process: failed");

		if(!current_job->first_process)
			current_process = current_job->first_process = newprocess;
		else {
			current_process->next = newprocess;
			current_process = current_process->next;
		}
		if(!readprocessinfo(current_process, cmd))
			return invokefree(current_job,"read process info: error");
		if(!sequence) {
			strncpy(current_job->commandinfo,cmdline+seq_pos,cmdline_pos-seq_pos);
			break;
		}
		sequence = false;
		++cmdline_pos;
	}
	return true;
}
Пример #3
0
/* 
 * builtin_cmd - If the user has typed a built-in command then execute
 * it immediately.  
 */
bool builtin_cmd(job_t *last_job, int argc, char **argv) 
{

	    /* check whether the cmd is a built in command
        */

  if (!strcmp("quit", argv[0])) {
    /* Your code here */
    exit(EXIT_SUCCESS);
  }
  else if (!strcmp("jobs", argv[0])) {
    /* Your code here */
    job_t* currentJob = active_jobs_head;
    job_t* deletedJob = NULL;

    while(currentJob != NULL) {
      // print active jobs and then change notified to 0

      //if((currentJob->first_process)->completed == true && currentJob->notified == false) {

      //need to check if every process has completed for a job to be complete, not just the first process
      if (job_is_completed(currentJob) == true)
      {
        printf("%d (Completed): %s\n", currentJob->pgid, currentJob->commandinfo);
        deletedJob = currentJob;

         //currentJob->notified = true;
      }
      //otherwise it is stopped
      else if (job_is_stopped(currentJob) == true)
      {
        printf("%d (Stopped): %s\n", currentJob->pgid, currentJob->commandinfo);
      }

      else
      {
        printf("%d (Running): %s\n", currentJob->pgid, currentJob->commandinfo);
      }

      currentJob = currentJob->next;

      // delete job after it is completed, don't need to save notified 
     
      if (deletedJob != NULL) 
      {
        if (deletedJob == active_jobs_head)
        {
          active_jobs_head = deletedJob->next;
          free_job(deletedJob); //TBD warning about this?
        }
        else
        {
          delete_job(deletedJob, active_jobs_head);
        }
        deletedJob = NULL;
      }
    }
    return true;
  }

  else if (!strcmp("cd", argv[0])) {
    int chdir_return = chdir(argv[1]);
    if(chdir_return == -1) {
      printf("cd: %s: No such file or directory\n", argv[1]);
    }
    return true;
  }
  else if (!strcmp("bg", argv[0])) {
    /* Your code here */
    job_t* currentJob = active_jobs_head;
    process_t* p2;

    if(argv[1] == NULL) 
    {
      // continue most recent stopped job

      //use find_last_job
      currentJob = find_last_job(active_jobs_head);

      continue_job(currentJob);
      seize_tty(currentJob->pgid);


      p2 = currentJob->first_process;

      while(p2 != NULL)
      {
        p2->stopped = false;
        
        struct sigaction action;
        action.sa_sigaction = sighandler;

        sigfillset(&action.sa_mask);
        action.sa_flags = SA_SIGINFO;
        sigaction(SIGCHLD, &action, NULL);

        p2 = p2->next;
      }
      seize_tty(getpid());
    }

    else 
    {
      pid_t job_number = atoi(argv[1]);

      
      while(currentJob != NULL) {
        // Need to eventually iterate through all processes?
        
        if((job_is_stopped(currentJob)) && currentJob->pgid == job_number) {
          //seize_tty(currentJob->pgid);
          continue_job(currentJob); 
          seize_tty(currentJob->pgid);

          p2 = currentJob->first_process;
          while (p2 != NULL)
          {
            p2->stopped = false; 

            struct sigaction action;
            action.sa_sigaction = sighandler;

            sigfillset(&action.sa_mask);
            action.sa_flags = SA_SIGINFO;
            sigaction(SIGCHLD, &action, NULL);
            p2 = p2->next;
          }

          seize_tty(getpid());
          break;
        }
        else if (currentJob->pgid == job_number) {
          printf("%s\n", "This process wasn't stopped`");
        }
        else {
          printf("%s\n", "This job number is not the requested one");
        }
        currentJob = currentJob->next;
      }
    }
    return true;
  }


  else if (!strcmp("fg", argv[0])) {
    /* Your code here */
    job_t* currentJob = active_jobs_head;
    process_t* p2;

    if(argv[1] == NULL) {
      // continue most recent stopped job

      //use find_last_job
      currentJob = find_last_job(active_jobs_head);
      continue_job(currentJob);
      seize_tty(currentJob->pgid);


      p2 = currentJob->first_process;

      while(p2 != NULL)
      {
        waiting(p2);
        p2 = p2->next;
      }
      seize_tty(getpid());
    }
    else {
      pid_t job_number = atoi(argv[1]);

      
      while(currentJob != NULL) {
        
        
        if((job_is_stopped(currentJob)) && currentJob->pgid == job_number) {
          //seize_tty(currentJob->pgid);
          continue_job(currentJob); 
          seize_tty(currentJob->pgid);

          p2 = currentJob->first_process;
          while (p2 != NULL)
          {
            waiting(p2);
            p2 = p2->next;
          }
          seize_tty(getpid());
          break;
        }
        else if (currentJob->pgid == job_number) {
          printf("%s\n", "This process wasn't stopped`");
        }
        else {
          printf("%s\n", "This job number is not the requested one");
        }
        currentJob = currentJob->next;
      }
    }
    return true;
  }
  /* not a builtin command */
  return false;
}