示例#1
0
/**
* Running the shell, cool stuff happens here
*/
void runShell(char ** argv) {

  //loop
  char *String = malloc(200);
  printf("Dat Bash $");

  //run shell
  while (scanf(" %199[^\n]s", String)) {
    if (strcmp(String, "quit") == 0) {
      break;
    }

    int h;
    int g;


    char ** pipedCommands = parse(String, '|');
    int pipes =0;
    for (int i =0; i < strlen(String); i++) {
      if(String[i] == '|') {
        pipes++;
      }
    }
    // printf("pipes = %i\n", pipes);

    char **st = malloc((sizeof(char *)) * (pipes +1));
    char ***parameters = malloc(sizeof(char *) * (pipes +1));



    for(int i= 0; pipedCommands[i] != NULL; i++) {
      h =0;
      g=0;

      while (pipedCommands[i][g] != '|' && pipedCommands[i][g] != 0) {
        g++;
      }

      char ** commands = malloc(g+1);

      //check command for parameter
      while (pipedCommands[i][h] != ' ' && pipedCommands[i][h] != 0) {
        h++;
      }
      commands[i] = malloc(h + 1);
      for (int l = 0; l < h; ++l) {
        commands[i][l] = pipedCommands[i][l];
      }
      commands[i][h] = 0;

      //find the longest path variable
      int lv = 0;
      int envVariables =0;
      for (int j = 0; argv[j] != NULL; j++) {
        if (strlen(argv[j]) > lv) {
          lv = strlen(argv[j]);
          envVariables++;
        }
      }



      st[i] = malloc(strlen(commands[i]) + 2 + lv);

      bool f = false;

      for (int k = 0; argv[k] != NULL; k++) {


        char *a = malloc(strlen(argv[k]) * 10);
        for (int j = 0; j < strlen(argv[k]); j++) {
          a[j] = argv[k][j];
        }
        //find the commands path
        char *s = strcat(a, "/");
        st[i] = strcat(s, commands[i]);

        if (file_exist(st[i])) {
          printf("Found \'%s\'!\n", st[i]);
          f = true;
          break;
        }
      }

      if(!f) {
        printf("\'%s\' was not found.\n", st[i]);
      }

      //format the command's path
      parameters[i] = parse(pipedCommands[i], ' ');
      int count = 0;
      for (int k = 0; parameters[i][k]; k++) {
        count++;
      }

    }

    //check if the files_exist
    if (files_exist(st, pipes)) {
      int i;
      pid_t result;

      //create pipes
      int in, fd [2];
      in =0;

      //begin executing commands
      result = fork();
      if (result == 0) {

        //is a pipe needed? and how many
        for (i = 0; i < pipes; i++) {
          pipe(fd);

          //create more branches for children
          if ((result=fork()) ==0) {

            //child close input pipe
            if ((in != 0)) {
              dup2(in, 0);
              close(in);
            }

            //parents close write pipe
            if(fd[1] != 1) {
              dup2(fd[1], 1);
              close(fd[1]);
            }

            //execute piped commands
            execv(st[i], parameters[i]);
          }else {
            wait(&result);
          }

          //close write pipe
          close(fd [1]);

          //direct output to input for next child
          in = fd [0];
        }
        //set stdin for final command
        if (in != 0) {
          dup2(in, 0);
        }
        //close pipe
        close(fd[0]);

        //execute final command
        execv(st[i], parameters[i]);
      } else {
        wait(&result);
      }
    }

    printf("Dat Bash $");
  }

}
示例#2
0
/*	Test the "semantics" (with respect to what the outputs should be, 
	given certain input) of the test cases in ../test/*.				 

	This testing has the preconditions of having a text output file in 
	test/files/testX/execution/output (for X = test0, test1, ...) and a 
	executable binary in test/files/testX/execution/bin (for X = test0, 
	test1, ...).													     */
void test_semantics_of_test_cases() {

	std::cout << std::endl << std::endl << "Checking semantics of every test case provided:" << std::endl;

	/*	Test case index. */
	unsigned int t_index = 0;
	/* (input, output) pair index. */
	unsigned int f_index = 0;
	const std::string path_temp = ("../test/files/test");
	
	/*	Input file. */
	std::string input_path;
	
	/*	Output file of execution. */
	std::string output_path;

	/*	The expected output file. */
	std::string exp_output_path;

	while(exists(path_temp + std::to_string(t_index) + std::string("/execution/bin"))) {
		/*	The binary file to be checked on exists. */
		
		f_index = 0;
		std::string binary = path_temp
					+ std::to_string(t_index)
					+ std::string("/execution/bin");

		while(files_exist(path_temp, t_index, f_index)) {
			/*	There is a new (input, output) pair to be checked.			 */

			input_path = path_temp 
					+ std::to_string(t_index) 
					+ std::string("/input") 
					+ std::to_string(f_index);
			output_path = path_temp
					+ std::to_string(t_index)
					+ std::string("/execution/output");
			exp_output_path = path_temp 
					+ std::to_string(t_index) 
					+ std::string("/output") 
					+ std::to_string(f_index);

			std::string execution = binary
					+ (std::string(" < ") + input_path)
					+ (std::string(" > ") + output_path);
			std::system(execution.c_str());
			

			/*	------------------------------------------------------------ */
			/*	These instructions check that there was no difference between
				the output that resulted from execution, and the expected 
				output. 													 */

			// First, build diff command.
			std::string diff = std::string("diff ")
					+ output_path
					+ std::string(" ")
					+ exp_output_path
					+ std::string(" > extra.diff");
			// Execute diff command.
			std::system(diff.c_str());
			// Open file that contains results of diff execution.
			std::fstream extra;
			extra.open("extra.diff", std::fstream::in);
			assert(!extra.fail());
			// Check that the end of the file is at position 0 
			// (i.e., length is 0).
			extra.seekg(0, extra.end);
			if ((int)extra.tellg() != 0) {
				std::cout << "Differences have been found between ";
				std::cout << output_path << " and " << exp_output_path;
				std::cout << ":" << std::endl;
				std::system("cat extra.diff");
				exit(1);
			}

			/*	------------------------------------------------------------ */

			++f_index;
		}
	
		++t_index;
	}
	
	if (exists(std::string("extra.diff")))
		std::system("rm extra.diff");

	std::cout << "\tSemantics of the test cases has been proven correct." << std::endl;
}