Example #1
0
// Set up's cmd_stream, minus depend_id
cmd_stream_t
initialize_cmds (command_stream_t command_stream)
{
  cmd_stream_t stream = checked_malloc(sizeof(struct cmd_stream));
  command_t command;
  
  int id = 1;
  while ((command = read_command_stream(command_stream)))
  {
    cmd_node_t node = checked_malloc(sizeof(struct cmd_node));
    node->id = id;
    node->started = false;
    node->self = command;
    node->next = NULL;
    node->depends = get_file_depends(command);
    
    if (stream->head == NULL)
    {
      node->prev = NULL;
      stream->head = node;
      stream->curr = node;
    }
    else
    {
      node->prev = stream->curr;
      stream->curr->next = node;
      stream->curr = stream->curr->next;
    }
    ++id;
  }
  stream->tail = stream->curr;
  stream->curr = stream->head;
  return stream;
}
Example #2
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = 1; break;
      case 't': time_travel = 1; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
  {
  return 0;
  //error (1, errno, "%s: cannot open", script_name);
  }
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
void execute_timeTravel(command_stream_t c);

	if(time_travel ==1)
	{ //execute in time travel mode 
	execute_timeTravel(command_stream);
	}
else{ //this means we are not in timetravel mode
  while ((command = read_command_stream (&command_stream)))
    {
      if (print_tree)
	{
	  printf ("# %d\n", command_number++);
	  print_command (command);
	}
      else
	{
	  last_command = command;
	  execute_command (command);
	}
    }
} //close the else statement
  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #3
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = 1; break;
      case 't': time_travel = 1; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);





  command_t last_command = NULL;
  command_t command;
  if (!time_travel){
    while ((command = read_command_stream (command_stream)))
      {
        if (print_tree)
	  {
	    printf ("# %d\n", command_number++);
	    print_command (command);
	  }
        else
	  {
	    last_command = command;
	    execute_command (command, time_travel);
	  }
      }
  }
  else{
    parallel_execute (command_stream);
  }

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #4
0
command_t
execute_parallel_stream (command_stream_t com)
{
  command_node_t dep_head = NULL;

  command_t final_command = NULL;
  command_t command;
  //This function gets the command stream, we are reading the commands, one after the other. 
  for(;;)
  {
  	command = read_command_stream (com);

  	//This means we finished reading the command
  	if(!command)
  	break;
      command_node_t curr_node = NULL;

  	//We got a new command, so create a new command, initialize everything to null and new_node->c to the command read
    command_node_t new_node = checked_malloc(sizeof(struct command_node));
    //Initializae function will initialize everything!
    initialize(new_node,command);
    //Then we simply need to add the dependencies to our list
    add_dependencies(new_node, command);  
    final_command = command;

	//At this point the list has been populated and the dependencies have been added
    command_node_t current_node = dep_head;
    for(;;)
    {
    	//This means there are no dependencie
    	if(current_node == NULL)	
    		break;
      //If ther are dependencies found, we do comparisons and assign the current node accordingly
      helper(current_node, new_node->outputs, current_node->inputs, new_node);
      helper(current_node, current_node->outputs, new_node->inputs, new_node);
      
      curr_node = current_node;
      //Traversing the list
      current_node = current_node->next;
    }

    //This means means we can add to the waiting list
    if( curr_node == NULL)
      dep_head = new_node;
    else
      curr_node->next = new_node;

  }
  //dep head
  // While there's someone on the waiting list
  command_t retcommand = forkingandwaiting(dep_head,final_command);
  return retcommand;

}
Example #5
0
int
main (int argc, char **argv)
{
    int command_number = 1;
    bool print_tree = false;
    char const *profile_name = 0;
    program_name = argv[0];
    
    for (;;)
    switch (getopt (argc, argv, "p:t"))
    {
        case 'p': profile_name = optarg; break;
        case 't': print_tree = true; break;
        default: usage (); break;
        case -1: goto options_exhausted;
    }
    options_exhausted:;
    
    // There must be exactly one file argument.
    if (optind != argc - 1)
    usage ();
    
    script_name = argv[optind];
    FILE *script_stream = fopen (script_name, "r");
    if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
    command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);
    int profiling = -1;
    if (profile_name)
    {
        profiling = prepare_profiling (profile_name);
        if (profiling < 0)
        error (1, errno, "%s: cannot open", profile_name);
    }
    
    command_t last_command = NULL;
    command_t command;
    while ((command = read_command_stream (command_stream)))
    {
        if (print_tree)
        {
            printf ("# %dn", command_number++);
            print_command (command);
        }
        else
        {
            last_command = command;
            execute_command (command, profiling);
        }
    }
    
    return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #6
0
void execute_parallel(command_stream_t commandStream) {
    graphnode_list_t adjList = create_list();
    command_t cmd;
    while ((cmd = read_command_stream (commandStream))) {
        string_list_t readList = create_list(); 
        string_list_t writeList = create_list();
        build_io_lists(cmd, readList, writeList);
        add_to_graph(adjList, cmd, readList, writeList);
    }

    int adjListSize = size(adjList);

    sharedFinished = mmap(NULL, adjListSize * sizeof(bool), 
                    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);

    int i;
    for (i = 0; i < adjListSize; i++) {
        sharedFinished[i] = false;
    }


    unsigned int numStartedProcesses = 0;

    i = 0;
    node_t currNode = adjList->head;
    while (currNode) {
        graphnode_t currGraphNode = currNode->item;
        currGraphNode->aid = i;

        if (numStartedProcesses >= MAX_PROCS) {
            // wait for a spot to open up
            wait(NULL);
        }

        pid_t p = fork();

        if (p == 0) {
            execute_node(currGraphNode);
        }
        else if (p > 0) {
            numStartedProcesses++;
            currNode = currNode->next;
        }
        i++;
    }
    while (true) {
        int status;
        pid_t done = wait(&status);
        if (done == -1 && errno == ECHILD) {
            break;
        }
    }
}
void
execute_graph(int** graph, command_stream_t stream, int N)
{
  int i,j,n = 0, m, np = N;
  while (graph[n]) n++;

  command_t* command_stream = malloc(sizeof(command_t)*n);
  int count = 0, status;
  while(count < n)
      command_stream[count++] = read_command_stream(stream);

  int *executed = malloc(sizeof(int)*n);

  for (i = 0; i<n; i++)
    executed[i] = 0;
  m = n;
  while (m > 0)
    {
      for (i = 0; i < n; i++)
	if (!executed[i])
	  {
	    int dependency = 0;
	    for (j = 0; j < n; j++)
	      if (graph[i][j]) dependency = 1;
	    if (!dependency)
	      {
		if (np == 0) // if the limit of subprocesses is met 
		  {
		    waitpid(WAIT_ANY, &status, WUNTRACED); // wait for any child to return
		    if (errno == EINTR || errno == EINVAL) perror("waitpid");
		    np = 1;
		  } // the check is put right before forking, so that the efficiency is maximized.
		m--; np--;
		executed[i] = 1;
		pid_t pid = fork();
		if (!pid)
		  {/* child process execute the command */
		    execute_command(command_stream[i], 0);
		    for (j = 0; j < n; j++)
		      graph[j][i] = 0;
		    exit(command_status(command_stream[i]));
		  }
	      }
	  }
    }
 
  while (waitpid(WAIT_ANY, &status, WUNTRACED))
     { 
       if (errno == ECHILD) break; 
       if (errno == EINTR || errno == EINVAL) perror("waitpid");
     }
}
Example #8
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  char* measure_file_name = NULL;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pm:t"))
      {
      case 'p': print_tree = true; break;
      case 'm': measure_file_name = optarg; break;
      case 't': time_travel = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  int ret = 0;
  command_t command;
  if (print_tree) {
    while ((command = read_command_stream (command_stream))) {
	  printf ("# %d\n", command_number++);
	  print_command (command, false, 0, 0);
    }
  }
  else if (time_travel) {
    ret = execute_time_travel (command_stream);
  }
  else {
    ret = execute_sequential (command_stream, measure_file_name);
  }

  return ret;
}
Example #9
0
// FIXME: Include a dependency graph argument here
void execute_command_parallel (command_stream_t command_stream) {
  command_t currCommand;
  pid_t child;

  while ((currCommand = read_command_stream(command_stream))) {
    child = fork();
    if (child == 0) { // Child Process
      execute_command(currCommand, 0);
      break;
    } else if (child > 0) { // Parent Process
      continue;
    } else { // error on fork
      error(1, 0, "Cannot create parallel process!");
    }
  }
  return;
}
Example #10
0
command_t
read_command_stream (command_stream_t s)
{
  if(s != NULL && s->read == 0){
    command_t tree;
    tree = s->root;
    s->read++;
    return tree;
  }

  else if(s != NULL && s->next != NULL){
    return read_command_stream(s->next);
  }

  else{
    return NULL;
  }
}
Example #11
0
void
exe_stream (command_stream_t stream, int time_travel, int nThreads)
{
  if (time_travel == 0)
  {
    command_t command;
    while ((command = read_command_stream(stream)))
      execute_command(command);
  }
  else
  {
    cmd_stream_t cmds = initialize_cmds(stream);
    HEAD = cmds->head;
    input_dependencies (cmds);
    
    if (nThreads == -1)
      do_unlimited(cmds);
    else
      do_limited(cmds, nThreads);
  }
}
Example #12
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = 1; break;
      case 't': time_travel = 1; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
  command_node* inner_current;


  if(!print_tree && time_travel) {
    int read_array_len = 0;
    int write_array_len = 0;
    // iterate through command stream to build dependency list, information is stored in command nodes
    while (command_stream->current != NULL) {

      read_array_len = 0;
      write_array_len = 0;
      command_stream->current->read_list = malloc(sizeof(char*) * 32);
      command_stream->current->write_list = malloc(sizeof(char*) * 32);
      command_stream->current->dependencies = malloc(sizeof(struct command_node*)*20);
      command_stream->current->num_dependencies = 0;
      populate_read_list(command_stream->current, command_stream->current->command, &read_array_len, &write_array_len);
      /*
      if(command_stream->current->command->input != NULL)
      {
          command_stream->current->read_list[0] = malloc(sizeof(char) * 100);
          read_array_len++;
          strcpy(command_stream->current->read_list[0], command_stream->current->command->input);
      }
      if(command_stream->current->command->output != NULL)
      {
          command_stream->current->write_list[0] = malloc(sizeof(char) * 100);
          strcpy(command_stream->current->write_list[0], command_stream->current->command->output);
      }
      // index starts at 1 so we don't include the command name
      int iterator = 1;
      while(command_stream->current->command->u.word[iterator]!=NULL)
      {
        command_stream->current->read_list[read_array_len]=malloc(sizeof(char*) * 40);
        if(command_stream->current->command->type == SIMPLE_COMMAND)
              strcpy(command_stream->current->read_list[read_array_len],command_stream->current->command->u.word[iterator]);
        iterator++;
        read_array_len++;
      }
      */
      inner_current = command_stream->head;
      while (inner_current != command_stream->current) {
        if ((dependency_exists(inner_current->read_list, command_stream->current->write_list))  || // "possible RAW data race"
            (dependency_exists(inner_current->write_list, command_stream->current->write_list)) || // "possible WAR data race"
            (dependency_exists(inner_current->write_list, command_stream->current->read_list)))    // "possible WAW data race"
          {
            // add pointer to inner_current in current's dependencies
          //  printf("hi\n");
            command_stream->current->dependencies[command_stream->current->num_dependencies] = inner_current;
         //   printf("Yes\n");
            command_stream->current->num_dependencies++;
          }
        inner_current = inner_current->next;
      }

      /*printf("the readlist is ================\n");
      int haha = 0 ;
      for(haha; haha<read_array_len; haha++)
        printf("%s\n",command_stream->current->read_list[haha]);

      printf("the writelist is ================\n");
      for(haha = 0; haha<write_array_len; haha++)
        printf("%s\n",command_stream->current->write_list[haha]);

      printf("dependency: %d\n", dependency_exists(command_stream->current->read_list, command_stream->current->write_list));*/
      command_stream->current = command_stream->current->next;
    } 
  
    command_stream->current = command_stream->head;

    // loop through
    while (command_stream->current != NULL) {
   //  printf("the command is %s\n",command_stream->current->command->u.word[1]);
   
     // printf("child_pid is %d\n",child_pid );
      //pid_t child_pid = fork();
    //  if(child_pid == 0) //child
      //{
        int ind = 0;
        int ind2 = 0;
        int num_depp = command_stream->current->num_dependencies;
        //check if dependencies have been started
        for(ind; ind<num_depp; ind++)
        {
          if(command_stream->current->dependencies[ind]->pid == -1)
          {
            ind--;
          }
        }
        //check if dependencies are done
        int eStatus;
        for(ind2; ind2< num_depp; ind2++)
        {
            waitpid(command_stream->current->dependencies[ind2]->pid, &eStatus,0);
            command_stream->current->num_dependencies--;
        }

       
    // }
     pid_t child_pid = fork();
     if(child_pid == 0)
     {
       // printf("command_stream is %s\n", command_stream->current->command->u.word[1]);
        execute_command(command_stream->current->command, 1);
        _exit(0);
    }

      else  //parent
     {
        command_stream->current->pid = child_pid;
        
     }
     command_stream->current = command_stream->current->next;  
    }

    command_stream->current = command_stream->head;

    while (command_stream->current != NULL)
        {
        int exit_status = 0;
        waitpid(command_stream->current->pid, &exit_status, 0);
        command_stream->current->command->status=WEXITSTATUS(exit_status);
        command_stream->current = command_stream->current->next;
        }

    last_command = command_stream->tail->command;
  }  //end of no print_tree

  else if (print_tree)
  {
      while ((command = read_command_stream (command_stream))) {
      printf ("# %d\n", command_number++);
      print_command (command);
    } 
  }  // end of print tree

  else {
      while ((command = read_command_stream (command_stream))) {
        last_command = command;
        execute_command(command, time_travel);
      }
  }
/*

  while ((command = read_command_stream (command_stream)))
    {
      if (print_tree)
	{
	  printf ("# %d\n", command_number++);
	  print_command (command);
	}
      else
	{
	  last_command = command;
	  execute_command (command, time_travel);
	}
    }*/

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #13
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = true; break;
      case 't': time_travel = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  fclose(script_stream);

  command_t last_command = NULL;
  command_t command;

  //hold last_command_status
  int last_command_status;

  if(print_tree) {

    while ((command = read_command_stream (command_stream)))
    {
      /*if (print_tree)
      {	*/
  	    printf ("# %d\n", command_number++);
  	    print_command (command);
      //}
      /*else
    	{
    	  last_command = command;
    	  execute_command (command, time_travel);
    	}*/
    }
    
  } else {

    last_command_status = execute_command(command_stream, time_travel);

  }

  free(command_stream->cmds);
  free(command_stream);

  //return print_tree || !last_command ? 0 : command_status (last_command);
  return print_tree || !last_command ? 0 : last_command_status;
}
void execute_time_travel(command_stream_t command_stream)
{
    command_t command;

    // Initialize array for all commands
    List command_list = create_list();

    // For each command in the command stream
    while ((command = read_command_stream(command_stream))) {
        // Initialize a new node for the command
        Node* new_node = create_node(command);

        // Determine all of its dependencies and add it to the node
        // For dependencies need to determine input files and output files
        determine_dependencies(command, new_node);

        // Push the new command node on to the array
        list_insert(&command_list, new_node);
    }

    // While there are still commands in the array
    while (command_list.counter > 0) {
        Node* iter = command_list.begin;

        int i;
        // For each command in the array
        for (i = 0; i < command_list.counter; i++)
        {
            // Check to make sure none of it's input files is equal to any of
            // the output files of the previous commands
            // If it doesn't depend on any of the previous commands then we
            // should create a fork and execute the process
            if (no_dependencies(iter, i) && !iter->executed) {
                iter->executed = true;

                pid_t pid = fork();

                // If we are in the child process
                if (pid == 0) {
                    // Execute the command
                    execute_command(iter->c);

                    // Exit the process
                    _exit(0);
                }
                // If we are the parent set that positions pid to the pid of the
                // process just created
                else if (pid > 0) {
                    iter->pid = pid;
                }else
                    error(1, 0, "Forked process Failed");
            }

            iter = iter->next_node;    
        }

        // Wait for any process to finish
        pid_t finished_pid = waitpid(-1, NULL, 0);

        // Find that process in the array and remove it from the array
        list_remove(&command_list, finished_pid);
    }
}
Example #15
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  char const *profile_name = 0;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "p:t"))
      {
      case 'p': profile_name = optarg; break;
      case 't': print_tree = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);
  int profiling = -1;
  if (profile_name)
    {
      profiling = prepare_profiling (profile_name);
      if (profiling < 0)
	error (1, errno, "%s: cannot open", profile_name);
    }

  command_t last_command = NULL;
  command_t command;

    //timer starts
    struct timespec absolute;
    double start_time, prev_user_CPU, prev_sys_CPU;
    get_timer(&start_time, &prev_user_CPU, &prev_sys_CPU);
  while ((command = read_command_stream (command_stream)))
    {
      if (print_tree)
	{
	  printf ("# %d\n", command_number++);
	  print_command (command);
	}
      else
	{
	  last_command = command;
	  execute_command (command, profiling);
	}
    }
    //timer stops
    clock_gettime(CLOCK_REALTIME, &absolute);
    double absolute_time = absolute.tv_sec + (double)absolute.tv_nsec/1000000000.0;
    double end_time, current_user_CPU, current_sys_CPU;
    get_timer(&end_time, &current_user_CPU, &current_sys_CPU);
    double real_time = end_time - start_time;
    double userCPU = current_user_CPU-prev_user_CPU;
    double sysCPU = current_sys_CPU-prev_sys_CPU;
    
    pid_t pid = getpid();
    char buffer[1024];
    sprintf(buffer, "%f %f %.3f %.3f %d\n", absolute_time, real_time, userCPU, sysCPU, (int)pid);
    write(profiling, buffer, strlen(buffer));
    

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #16
0
void 
time_travel_mode(command_stream_t command_stream) // time travle main function
{
	command_t command;
	int line_num = 1;
	initialize_dependent_array();

	command_list_t head = NULL;

	// add dependencies and stuff
	while ((command = read_command_stream (command_stream)))
	{
		command_list_t new_cmd = checked_malloc(sizeof(struct command_list));
		new_cmd->c = command;
		new_cmd->file_list = NULL;
		new_cmd->num_of_dependent = 0;
		new_cmd->cmd_num = line_num;
		new_cmd->pid = -10; // arbitrary number that not child and parent
		new_cmd-> next = NULL;
		

		// if number of cmd > current array size
		// update it
		if (line_num >= current_size)
		{
			current_size *= 2;
			size_t resize =  current_size * sizeof(int);
			dependent_array = checked_grow_alloc(dependent_array, &resize);
		}

		add_dependencies(command, new_cmd);

/*
#ifdef DEBUG
		if(new_cmd->file_list == NULL)
			printf("NULL\n");
		printf("Command dependencies list: ");
		io_list_t cur = new_cmd->file_list;
		int i = 0;
		while(cur != NULL && i != 10)
		{
			printf("%s ", cur->name);
			cur = cur->next;
			i++;
		}
		printf("\n");
#endif
*/
		// traverse through the graph to add dependencies
		command_list_t last = head;
		command_list_t curr = head;
		
		
		while(curr != NULL)
		{
			analyze_dependencies(new_cmd, curr);
			last = curr;
			curr = curr->next;
		}

		if (last == NULL) // empty list
		{
			// add head
			head = new_cmd;
		}
		else
		{
			last->next = new_cmd;
		}
		line_num++;
	}
/*
	if (head != NULL)
			printf("Head outside is Cmd %d\n", head->cmd_num);
	int i;
	for( i = 0; i < INIT_SIZE; i++)
	{
		int j;
		for (j = 0; j < INIT_SIZE; j++)
		{
			if (dependent_array[i][j] > 0)
			{ 
				printf("Cmd %d requires Cmd %d\n", i, j);
			}
		}
	}
	command_list_t curr = head;
	while(curr != NULL)
	{
		printf("Cmd %d requires %d cmds\n", curr->cmd_num, curr->num_of_dependent);
		curr = curr->next;
	}
*/


	// Execute time travel
	// TODO
	
	//printf("Head is cmd %d\n", head->cmd_num);
	while(head != NULL)
	{
		command_list_t curr = head;
		while(curr != NULL)
		{
			//printf("curr cmd is %d and num of dependency is %d\n", curr->cmd_num, curr->num_of_dependent);
			// If current command/node does not require other cmd to be executed before
			// then execute current cmd
			if(curr->num_of_dependent == 0 && curr->pid < 1)
			{
				pid_t pid = fork();
				if (pid < 0)
        	error(1, 0, "Fork error: %s\n", strerror(errno));
				else if ( pid == 0) // child
        {
        	exec_command_helper(curr->c);
	        _exit(curr->c->status); 
        }
        else if ( pid > 0) // parent then save pid and wait
        {
        	curr->pid = pid;
        }
			}
			curr = curr->next;
		}
	
		int status;
		pid_t curr_pid = waitpid(-1, &status, 0); // parent wait for chid
		
		// Remove node from graph and update look-up table and stuff
		command_list_t prev = NULL;
		command_list_t traverse = head;
		while(traverse != NULL)
		{
			if(traverse->pid == curr_pid) // same pid, this node has finish executing
			{
				//printf("Remove cmd %d\n", traverse->cmd_num);
				// update table
				int i;
				for(i = 0; i < line_num; i++)
				{
					dependent_array[i][traverse->cmd_num] = 0;
				}

				//remove from the list
				if(prev == NULL) // head
				{
					head = traverse->next;
				}
				else
				{
					prev->next = traverse->next;
				}

				// update dependency number on each node
				command_list_t update = head;
				while(update != NULL)
				{
					int sum = 0;
					int j;
					for(j=0; j<line_num; j++)
					{
						sum += dependent_array[update->cmd_num][j];
					}
					//printf("Cmd %d now requires %d cmd\n", update->cmd_num, sum);
					update->num_of_dependent = sum;				
					update = update->next;
				}
				
				//printf("before break\n");
				break;
				//printf("after break\n");
			}
			prev = traverse;
			traverse = traverse->next;
		}
		//printf("Head is cmd %d\n", head->cmd_num);
		//if(head != NULL)
		//	head = head->next;
	} 
}
Example #17
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  int interactive = 0;
  program_name = argv[0];

  depend_node_t depend_table = checked_malloc(sizeof(struct depend_node));
  //Dependency Table

  for (;;)
    switch (getopt (argc, argv, "pti"))
      {
      case 'p': print_tree = 1; break;
      case 't': time_travel = 1; break;
		case 'i': interactive = 1; break;	// Interactive Shell
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (!interactive && optind != argc - 1) 
    usage ();
  if (interactive) {
  	 printf("*******Interactive Shell*******\n");
	 ishell();
	 return 0;
  }

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
  while ((command = read_command_stream (command_stream)))
    {
      if (print_tree)
	{
	  printf ("# %d\n", command_number++);
	  print_command (command);
	}
      else
	{
	  if (last_command !=NULL)
			free(last_command);
	  last_command = command;
	  execute_command (command, time_travel, depend_table);
	}
    }
  // Deallocate the dependency table
  if (time_travel) // time_travel
  {
		depend_node_t temp = depend_table;
		depend_table = depend_table->nxt;
		free(temp);
		while (depend_table != NULL)
		{
			temp = depend_table;
			depend_table = depend_table->nxt;
			free(temp->handle);
			free(temp);
		}
  }
  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #18
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;

  bool output_to_file=false;
  bool error_to_file=false;
  bool all_to_file=false;
  
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "ptvxoehas"))
      {
      case 'p': print_tree = true; break;
      case 't': time_travel = true; break;
      case 'x': x_option=true;break;
      case 'v': v_option=true;break;
      case 'o': output_to_file=true;break;
      case 'e': error_to_file=true;break;
      case 'a': all_to_file=true;break;
      case 's': s_option=true;break;
      case 'h':
	fprintf(stderr,"option p to print command trees without execution.\noption t to exploit parallelism between command trees.\n");
	fprintf(stderr,"option x to print simple commands and their arguments before execution.\noption v to print shell input before execution.\n");
	fprintf(stderr,"option o to save output to output.txt.\noption e to save error to error.txt.\n");
	fprintf(stderr,"option a to save output and error to  output_and_error.txt.\n");
	fprintf(stderr,"option s to slowly go through script, one command tree at a time\n");
	fprintf(stderr,"option x and v not available in combination with option t.\n");
	fprintf(stderr,"options x or v in combination with option s to tell what the next command is before continuing.\n");
	
	return 0;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  if(time_travel)
    {
      if(x_option || v_option || s_option)
	{
	  no_debug_time_travel();
	}
      }
  if(print_tree && s_option)
    {
      error (1, 0, "usage: %s [-pxvtoehas] SCRIPT-FILE, cannot use step_mode and print tree", program_name);
    }

  script_name = argv[optind];


  if(s_option)
    {
      fprintf(stderr,"Step mode enabled. Press d to disable step mode, press a to abort further execution, or press enter to move onto the next command.\n");
    }


  if (all_to_file==false)
    {  
      if(output_to_file==true)
	{
	  
	  int fd=open("output.txt",O_CREAT|O_TRUNC|O_WRONLY,0644);
	  if(fd<0)
	    {
	      fprintf(stderr,"No available file descriptors");
	      return(1);
	    }
	  dup2(fd,1);
	  close(fd);

	}
      if(error_to_file==true)
	{
	  
	  int fd=open("error.txt",O_CREAT|O_TRUNC|O_WRONLY,0644);
	  if(fd<0)
	    {
	      fprintf(stderr,"No available file descriptors");
	      return(1);
	    }
	  dup2(fd,2);
	  close(fd);
	}
    }
  else//all to file is true
    {
      int fd=open("output_and_error.txt",O_CREAT|O_TRUNC|O_WRONLY,0644);
      if(fd<0)
	{
	  fprintf(stderr,"No available file descriptors");
	  return(1);
	}
      dup2(fd,2);
      dup2(fd,1);
      close(fd);


    }

  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
  if(time_travel)
    {
      struct dependency_graph* graph=create_graph(command_stream);
      int final_status=0;
      final_status=execute_graph(graph);
    }
 
  if(print_tree==true || time_travel==false)
    {
      while ((command = read_command_stream (command_stream)))
	{
	  if (print_tree)
	    {
	      printf ("# %d\n", command_number++);
	      print_command (command);
	    }
	  else
	    {
	      last_command = command;
	      
	      execute_command (command, time_travel);
	    }
	}
    }
  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #19
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
	bool time_travel_limit = false;
	int num_of_processes =0;
	program_name = argv[0];
	char c = ' ';

  for (;;)
    switch (getopt (argc, argv, "ptj"))
      {
      case 'p': print_tree = true;c = 'p'; break;
      case 't': time_travel = true; c = 't';break;
			case 'j': time_travel_limit = true;
								num_of_processes = atoi(argv[2]);
								c = 'j';
								break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
	{
		if (argc > 1 && c == 'j' && optind == argc-2)
		{}
		else
		{
    usage ();
		}
	}	
	

  script_name = argv[argc - 1];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
  while ((command = read_command_stream (command_stream)))
    {
      if (print_tree)
			{
				printf ("# %d\n", command_number++);
				print_command (command);
			}
      else
			{
				if (time_travel == false && time_travel_limit == false)
				{
				last_command = command;
				execute_command (command, time_travel);
				}
			}
    }
		if (time_travel == true)
		{execute(command_stream);}
		if (time_travel_limit == true)
		{execute_limit(command_stream, num_of_processes);}

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #20
0
int execute_time_travel(command_stream_t stream)
{
    command_t cmd;
    struct vector *gnodes = make_vector(DEFAULT_STACK_CAPAC);
    struct vector *running_nodes = make_vector(DEFAULT_STACK_CAPAC);

    /* Create all nodes and build input/output list */
    while ((cmd = read_command_stream(stream)) != NULL)
    {
        struct graph_node *node = make_graph_node(cmd);
        build_input_output_list(node, cmd);
        vector_push(gnodes, node);
    }

    /* Calculate dependencies */
    calc_dependencies(gnodes);

    /* Run initial nodes, then continue to run gnodes with zero dependencies until there are none left */
    for (int i = 0; i < gnodes->size; ++i)
    {
        struct graph_node *node = vector_get(gnodes, i);
        if (node->deps == 0)
        {
            dispatch_graph_node(node);
            vector_push(running_nodes, node);
        }
    }
    int last_status = 0;
    while (running_nodes->size > 0)         /* Poll for finished commands in running_nodes */
    {
        for (int i = 0; i < running_nodes->size; ++i)
        {
            struct graph_node *node = vector_get(running_nodes, i);
            int pid = node->pid;
            int wait_result;

            /* Don't block for waitpid(); check the next running process immediately */
            wait_result = waitpid(pid, &last_status, WNOHANG);
            if (wait_result > 0)
            {
                struct vector *depped_by = node->node_deps;
                for (int j = 0; j < depped_by->size; ++j)
                {
                    struct graph_node *dep_node = vector_get(depped_by, j);
                    dep_node->deps--;
                    if (dep_node->deps == 0)
                    {
                        dispatch_graph_node(dep_node);
                        vector_push(running_nodes, dep_node);
                    }
                }
                vector_remove(running_nodes, i);
                --i;
                last_status = WEXITSTATUS(last_status);
            }
            else if (wait_result < 0)
                ERR("Failed to waitpid() for child\n");
        }
    }

    /* Cleanup */
    for (int i = 0; i < gnodes->size; ++i)
        free_graph_node(vector_get(gnodes, i));
    free_vector(gnodes);
    free_vector(running_nodes);

    return last_status;
}
Example #21
0
DependencyGraph
createGraph(command_stream_t stream)
{
	DependencyGraph graph = (DependencyGraph)malloc(sizeof(struct dependency_graph));
	graph->dependencies = NULL;
	graph->no_dependencies = NULL;

	command_t command = read_command_stream(stream);
	for (; command != NULL; command = read_command_stream(stream))
	{
		// create a new GraphNode to hold the new command. 
		GraphNode g_node = (GraphNode)malloc(sizeof(struct graph_node));
		g_node->command = command;
		g_node->size = 10;
		g_node->before = (GraphNode*)malloc(g_node->size*sizeof(GraphNode)); 
		g_node->count = 0;
		g_node->pid = -1;

		// create a new ListNode to hold the new GraphNode and its RL, WL. 
		ListNode l_node = (ListNode)malloc(sizeof(struct list_node));
		l_node->graphnode = g_node;
		l_node->readlist = NULL;
		l_node->writelist = NULL;
		l_node->next = NULL;

		// fill in the readlist and writelist of l_node. 
		processCommand(command, l_node);

		// 2. Figure out the before list for g_node. 
		// TODO implementation
		ListNode iter = graph->dependencies;
		while (iter != NULL)
		{
			if (haveDependency(l_node, iter))
			{
				g_node->before[g_node->count] = l_node->graphnode;
				g_node->count++;
				if (g_node->count >= g_node->size)
				{
					g_node->size *= 2;
					g_node->before = (GraphNode*)realloc(g_node->before, g_node->size*sizeof(GraphNode));
				}
			}
			iter = iter->next;
		}
		iter = graph->no_dependencies;
		while (iter != NULL) {
			if (haveDependency(l_node, iter))
			{
				g_node->before[g_node->count] = l_node->graphnode;
				g_node->count++;
				if (g_node->count >= g_node->size)
				{
					g_node->size *= 2;
					g_node->before = (GraphNode*)realloc(g_node->before, g_node->size*sizeof(struct graph_node));
				}
			}
			iter = iter->next;
			
		}

		// 3. Add l_node to graph accordingly. 
		// TODO implementation depends on part 2. 
		if (g_node->count == 0) {
			iter = graph->no_dependencies;
			if (iter == NULL) {
				graph->no_dependencies = l_node;
			}
			else {
				while (iter->next != NULL) {
					iter = iter->next;
				}
				iter->next = l_node;
			}
		}
		else {
			iter = graph->dependencies;
			if (iter == NULL) {
				graph->dependencies = l_node;
			}
			else {
				while (iter->next != NULL) {
					iter = iter->next;
				}
				iter->next = l_node;
			}

		}
	}
	return graph;
}
Example #22
0
int
main (int argc, char **argv)
{
  total_cmd = 0;
  total_file = 0;
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = true; break;
      case 't': time_travel = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;
  
  if(!time_travel){
    while ((command = read_command_stream (command_stream)))
    {
      if (print_tree){
	    printf ("# %d\n", command_number++);
	    print_command (command);
	  }else{
	    last_command = command;
	    execute_command (command, time_travel);
	  }
    }
  }else{
    
    int i;
    //list for child process id. Each index represent the corresponding complete command
    // -1: executed & one
    //  0: hasn't been executed
    // >0: child executing
    pid_t *cpid_list = (pid_t*) checked_malloc(sizeof(pid_t) * total_cmd);
    for(i=0; i<total_cmd; i++){
      cpid_list[i] = 0;
    }
    bool done = false;
    //while there are still commands waiting to be run
    while(!done){
      cc_node_t temp_cmd = get_root(command_stream);
      int c_count = 0;
      while(temp_cmd){
        pid_t cpid;
          
        //fork and execute commands with no dependency problem and that the command hasn't been run
        if(cpid_list[c_count] ==0 && no_dependency(c_count)){
           cpid = fork();
           //child execute the command
           if(cpid == 0){
            execute_command (temp_cmd->c, time_travel);
            exit(0); //child exit
           }else if(cpid >0){
            //parent add child pid to the global array
            cpid_list[c_count] = cpid;

           }else{
            error(1, 0, "Forking process failed");  
           }
        
        }
        temp_cmd = temp_cmd->next;
        c_count++;
      
      }
      //wait for child
      for(i=0; i<total_cmd; i++){
        //if the child process is runnign the ith command
        if(cpid_list[i] >0){
          int status;
          waitpid(cpid_list[i], &status, 0);
          //update the dependency list (remove the ith row or something)
          update_dependency(i);
          //set the cpid to -1
          cpid_list[i] = -1;
        }
      }
      //if there are no more command
      done =  true;
      for(i=0; i<total_cmd; i++){
        if(cpid_list[i]==0){
          done = false;
        }
      }
    }
    free(cpid_list);
    while ((command = read_command_stream (command_stream))){}
    //deallocate dependcy lists
    int k;
    for(k=0; k<total_cmd; k++){
      free(depend_list[k]);
    }
    free(depend_list);
    free(file_list);
  }

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #23
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
  {
    case 'p': print_tree = true; break;
    case 't': time_travel = true; break;
    default: usage (); break;
    case -1: goto options_exhausted;
  }
  options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
  make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;



  if(time_travel)
  {
    size_t command_buf = 16;
    command_t* command_array = NULL;
    command_array = (command_t*) checked_malloc(command_buf*sizeof(command_t));
    int command_count = 0;
    int i;
    int previous_command = 0;

    for (command_count = 0; (command = read_command_stream (command_stream)); command_count++)
    {
      if (command_count == (int)command_buf)
        command_array = (command_t*) checked_grow_alloc(command_array, &command_buf);
      command_array[command_count] = command;
    }

    bool dependency_matrix[command_count][command_count];
    int j;
    int k;
    bool run_command;
    pid_t pid;
    int fd[command_count][2];
    int retval;
    fd_set set;
    int buf;
    int m;
    int z;
    int read_return;
    
    for (j=0; j < command_count; j++)
      for (k = 0; k < command_count; k++)
        dependency_matrix[j][k] = false;

    //Iterating through all commands
      for (i=0; i < command_count; i++)
      {
      //Iterating through all commands preceding it
        for (previous_command = i-1; previous_command >= 0; previous_command--)
        {
        //Iterating through the output files of the current command
          for (j=0; j < command_array[i]->top_outputs_count; j++)
          {
          //Iterating through the input files of the preceding command
            for (k=0; k < command_array[previous_command]->top_inputs_count; k++)
            {
              if (strcmp(command_array[i]->top_outputs[j], command_array[previous_command]->top_inputs[k]) == 0)
              {
                dependency_matrix[i][previous_command] = true;
                break;
              }
            }
          //Iterating through the output files of the preceding command
            for (k=0; k < command_array[previous_command]->top_outputs_count; k++)
            {
              if (strcmp(command_array[i]->top_outputs[j], command_array[previous_command]->top_outputs[k]) == 0)
              {
                dependency_matrix[i][previous_command] = true;
                break;
              }
            }
          }
        //Iterating through the input files of the current command
          for (j=0; j < command_array[i]->top_inputs_count; j++)
          {
          //Iterating through the input files of the preceding command
            for (k=0; k < command_array[previous_command]->top_inputs_count; k++)
            {
              if (strcmp(command_array[i]->top_inputs[j], command_array[previous_command]->top_inputs[k]) == 0)
              {
                dependency_matrix[i][previous_command] = false;
                break;
              }
            }
          //Iterating through the output files of the preceding command
            for (k=0; k < command_array[previous_command]->top_outputs_count; k++)
            {
              if (strcmp(command_array[i]->top_inputs[j], command_array[previous_command]->top_outputs[k]) == 0)
              {
                dependency_matrix[i][previous_command] = true;
                break;
              }
            }
          }
        }
      }
      for(z=0; z < command_count; z++)
        fd[z][0] = 0;

      bool done = false;
      while(!done)
      {
        for (i=0; i < command_count; i++)
        {
          run_command = true;
          for (k=0; k < command_count; k++)
          {
            if (dependency_matrix[i][k])
            {
              run_command = false;
              break;
            }
          }
          if (run_command)
          {
            dependency_matrix[i][i] = true;
            if (pipe(fd[i]) != 0)
            {
              fprintf(stderr, "Failed to initialize pipe\n");
              exit(1);
            }
        //Child process
            pid = fork();
            if(pid == 0)
            {
              close(fd[i][0]);
              execute_command (command_array[i], false);

              //Setup pipe for writing from child to parent
              m = i;
 //             fprintf(stderr, "write#:%i\n", m);
              write(fd[i][1], &m, sizeof(int));
              close(fd[i][1]);
              exit(command_array[i]->status);
            }
        //Parent Process
            else if (pid > 0)
            {
              close(fd[i][1]);
              continue;
            }
            else
            {
              fprintf(stderr, "Failed to fork\n");
              exit(1);
            }
          }
        }
        
        FD_ZERO(&set);
        for(z=0; z < command_count; z++)
        {
          if(fd[z][0] != 0)
          {
            FD_SET(fd[z][0], &set);
            //fprintf(stderr, "set\n");
          }
        }
        
        retval = select(FD_SETSIZE, &set, NULL, NULL, NULL);
        if(retval == -1)
        {
          fprintf(stderr, "Error monitoring pipes");
          exit(1);
        }

        for(z=0; z < command_count; z++)
        {
          if(fd[z][0] != 0)
          {
            //fprintf(stderr, "fjieowajfoew\n");
            read_return = read(fd[z][0], &buf, sizeof(int));
            if(read_return > 0)
            {
              //fprintf(stderr, "Read: %i\n", buf);
              for(k=0; k < command_count; k++)
                dependency_matrix[k][buf] = false;
            //Set child command dependent to itself to indicate that it has already successfully executed
              dependency_matrix[buf][buf] = true;
            //close(fd[z][0]);
            }
            else if(read_return == -1)
            {
              fprintf(stderr, "Error reading\n");
              exit(1);
            }
          }
        }

        for(z=0; z < command_count; z++)
        {
          if(!dependency_matrix[z][z])
            break;
        }
        if(z == command_count)
          done = true;

 //       FD_ZERO(&set);
 //       FD_SET(fd[0], &set);
        //When this returns, data has been detected from pipe
 //       retval = select(FD_SETSIZE, &set, NULL, NULL, NULL);
//        fprintf(stderr, "Select read:%i\n", retval);
        /*
        while (read(fd[0], &buf, sizeof(int)) > 0)
        {
          fprintf(stderr, "Going through while loop with buf:%i \n", buf);
          for(k=0; k < command_count; k++)
            dependency_matrix[k][buf] = false;
        //Set child command dependent to itself to indicate that it has already successfully executed
          dependency_matrix[buf][buf] = true;
        }
        fprintf(stderr, "z:%i\n", z);
        */
        /*
        int read_return;
        while((read_return = read(fd[0], &buf, sizeof(int))) <= 0)
        {
          if (read_return == -1)
          {
            fprintf(stderr, "Error:%i\n", errno);
            fprintf(stderr, "Error reading\n");
            exit(1);
          }
        }

        fprintf(stderr, "Iteration:%i\nNum_read:%i\n", z, read_return);
        do
        {
          fprintf(stderr, "Bufval:%i\n", buf);
          for(k=0; k < command_count; k++)
            dependency_matrix[k][buf] = false;
          //Set child command dependent to itself to indicate that it has already successfully executed
          dependency_matrix[buf][buf] = true;
        } while(read(fd[0], &buf, sizeof(int)) > 0);
        close(fd[0]);
        */
      }
      for(z=0; z < command_count; z++)
        close(fd[z][0]);

      while((pid = wait(NULL)))
      {
        if(pid == -1 && errno == ECHILD)
          break;
        else if(pid == -1)
        {
          fprintf(stderr, "Error waiting on children");
          exit(1);
        }
      }








/*
    for (i = 0; i < command_count; i++)
    {
      last_command = command_array[i];
      execute_command(command_array[i], false);
    }
*/


  }

  else
  {
    while ((command = read_command_stream (command_stream)))
    {
      if (print_tree)
      {
       printf ("# %d\n", command_number++);
       print_command (command);
     }
     else
     {
       last_command = command;
       execute_command (command, time_travel);
     }
   }
 }

 return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #24
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  int **dependencies;
  int i, j, status, wait_val;
  pid_t* pids;
  bool can_run, finished;
  command_t* commands;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = true; break;
      case 't': time_travel = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  if (time_travel)
  {
    commands = command_stream->commands;
    dependencies = set_dependencies(commands, command_stream->num_commands);
    pids = (pid_t*) checked_malloc(sizeof(pid_t) * command_stream->num_commands);
    for (i = 0; i <command_stream->num_commands; i++)
      pids[i] = -1;
  }

  command_t last_command = NULL;
  command_t command;

  if (print_tree || !time_travel)
  {
    while ((command = read_command_stream (command_stream)))
      {
        if (print_tree)
  	{
  	  printf ("# %d\n", command_number++);
  	  print_command (command);
  	}
        else
  	{
  	  last_command = command;
  	  execute_command (command);
  	}
      }
  }

  else
  {
    for(;;)
    {
      finished = true;
      for (i = 0; i < command_stream->num_commands; i++)
      {
        if (pids[i] == -1)
        {
          can_run = true;
          for (j = 0; dependencies[i][j] != -1; j++)
            if (commands[dependencies[i][j]]->status == -1)
                {
                  can_run = false;
                  break;
                }

          if (can_run)
          {
            pids[i] = fork();
            if (pids[i]== -1)
              error(1, errno, "Error forking process");

            if (pids[i] == 0)
            {
              execute_command(commands[i]);
              exit(commands[i]->status);
            }
          }
        }
      }

      for (i = 0; i < command_stream->num_commands; i++)
      {
        if (pids[i] != -1)
        {
          wait_val = waitpid(pids[i], &status, WNOHANG);

          if (wait_val == 0)
            finished = false;

          else
            commands[i]->status = WEXITSTATUS(status);
        }

        else
          finished = false;
      }
      if (finished)
      {
        last_command = commands[command_stream->num_commands-1];
        break;
      }
    }
  }


  free_stream(command_stream);
  if (time_travel)
  {
    free(pids);
    for (i = 0; i<command_stream->num_commands; i++)
      free(dependencies[i]);
    free(dependencies);
  }
  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #25
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  int limit_process=0;
  int limit=-1;

  int make=1;
  program_name = argv[0];
  int c;
  while ((c = getopt (argc, argv, "ptn:")) != -1) {
    switch (c)
      {
      case 'p': print_tree = 1; break;
      //case 'm': print_tree = 1; make=0; break;
      case 'n': 
        limit_process=1; 
        limit=atoi(optarg);
        if (limit<=0) //process limit must be positive
          usage();
        break;
      case 't': time_travel = 1; break;
      default: printf("opt parsing error:\n"); usage (); break;
      
      }
  }
  //prints for debugging bash command argument parsing
  
  printf("p: %d n: %d t: %d\nlimit: %d\n", print_tree, limit_process, time_travel, limit);
  /*
  int index;
  for (index = optind; index < argc; index++)
    printf ("Non-option argument %s\n", argv[index]);
  */

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream = make_command_stream (get_next_byte, script_stream);
  /* //used for debugging make_command_stream
  if (make)
    command_stream=make_command_stream (get_next_byte, script_stream);
  else {
    command_stream=(command_stream_t) malloc(sizeof command_stream);
    char str[]=SCRIPT;
    memcpy(command_stream->stream,str,strlen(str));
    command_stream->index=0;
  }
  */

  command_t last_command = NULL;
  command_t command;

  command_t* commandArr = (command_t*)checked_malloc(sizeof(command_t));
  int commandArrSize = 0;

  //build the command array
  while ((command = read_command_stream (command_stream)))
  {
    commandArr[commandArrSize] = command;
    commandArrSize++;
    commandArr = (command_t*)checked_realloc(commandArr, sizeof(command_t)*(commandArrSize+1));
  }
  commandArr[commandArrSize] = NULL;

  //print, execute normally or execute time travel
  int i = 0;
  if (print_tree)
  {
    while(commandArr[i])
    {
      printf ("# %d\n", command_number++);
      print_command (commandArr[i]);
      i++;
    }
  }
  else 
  {
    execute_general(commandArr,commandArrSize, last_command, time_travel, limit_process, limit);
  }

  free(command_stream);
  free(commandArr);
  

  return print_tree || !last_command ? 0 : command_status (last_command);
}
Example #26
0
int
main (int argc, char **argv)
{
  int opt;
  int command_number = 1;
  int print_tree = 0;
  int time_travel = 0;
  int limit_processes = false;
  int num_processes = -1;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = 1; break;
      case 't': time_travel = 1; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one or two file argument.

  if (optind != argc - 1 && optind != argc - 2)
    usage ();

  script_name = argv[optind];

  //there are two arguments
  if (optind == argc - 2) {
    limit_processes = true;
    parse_ssize(argv[optind+1], &num_processes);
  }

  if (limit_processes && num_processes > 0) {
    printf("Running with %i processes\n", num_processes);
    update_subprocess_limit(num_processes);
  }
  else if (limit_processes && num_processes == 0) {
    error (1, errno, "Cannot run with 0 processes");
  }
  else {
    printf("Running with unlimited processes\n");
    update_subprocess_limit(-1);
  }

  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  command_t last_command = NULL;
  command_t command;


  //If time travel option is set make dependency graph
  int** graph; 
  if(time_travel)
  {
    execute_command_time_travel(command_stream);
    return 1;
  }
  else
  {
    int processes_needed_count = 0; 
    while ((command = read_command_stream (command_stream)))
      {
	if (print_tree)
	  {
	    printf ("# %d\n", command_number++);
	    print_command (command);
	  }
	else
	  {
	    last_command = command;
	    execute_command (command, time_travel);
	  }
      }
    
    return print_tree || !last_command ? 0 : command_status (last_command);
  }
}