Esempio n. 1
0
char* read_into_buffer(int (*get_next_byte) (void *), void *get_next_byte_argument) {
    size_t n, buf_size;
    char next_byte;
    char *buf;

    buf_size = 1024;
    n = 0;
    
    buf = (char *) checked_malloc(sizeof(char)*buf_size);
    
    while ((next_byte = get_next_byte(get_next_byte_argument)) != EOF) {
        
        if (next_byte == '#') {
            next_byte = get_next_byte(get_next_byte_argument);
            while (next_byte != '\n' && next_byte != EOF)
                next_byte = get_next_byte(get_next_byte_argument);
        }
        if (next_byte != EOF) {
            buf[n] = next_byte;
            n++;
            if (n == buf_size)
                buf = checked_grow_alloc(buf, &buf_size);
        }
    }
    
    if (n < buf_size - 1) {
        buf[n] = '\0';
    } else {
        buf = (char *) checked_grow_alloc(buf, &buf_size);
        buf[n] = '\0';
    }

    return buf;
}
void process_command(command_t c, char** arg, size_t* size, size_t* mem)
{
    char** w;
    switch (c->type){
        case SEQUENCE_COMMAND:
            process_command(c->u.command[0], arg, size, mem);
            process_command(c->u.command[1], arg, size, mem);
            break;
        case SIMPLE_COMMAND:
            if (c->input != NULL)
            {
                if (not_enough_mem (arg, size, sizeof (char*), *mem))
                { arg = checked_grow_alloc (arg, mem); }
                arg[*size] = c->input; (*size)++;
            }
            else if( c->output != NULL)
            {
                if (not_enough_mem (arg, size, sizeof (char*), *mem))
                { arg = checked_grow_alloc (arg, mem); }
                arg[*size] = c->output; (*size)++;
            }

            w=&(c->u.word[1]);
            while(*++w)
            {
                if (not_enough_mem (arg, size, sizeof (char*), *mem))
                { arg = checked_grow_alloc (arg, mem); }
                arg[*size] = *w; (*size)++;

            }
            break;
        case SUBSHELL_COMMAND:
            if (c->input != NULL)
            {
                if (not_enough_mem (arg, size, sizeof (char*), *mem))
                { arg = checked_grow_alloc (arg, mem); }
                arg[*size] = c->input; (*size)++;
            }
            else if (c->output != NULL)
            {
                if (not_enough_mem (arg, size, sizeof (char*), *mem))
                { arg = checked_grow_alloc (arg, mem); }
                arg[*size] = c->output; (*size)++;

            }
            process_command (c->u.subshell_command, arg, size, mem);
            break;
        default: 
            process_command(c->u.command[0], arg, size, mem);
            process_command(c->u.command[1], arg, size, mem);
            break;   
    }
    return;
}
Esempio n. 3
0
//gets all characters/bytes from the script being run
char* pullBytes(int (*get_next_byte) (void*), void *get_next_byte_argument)
{
  size_t line_size = SIZE_COM_ALLOC;
  char *line = (char *) checked_malloc(sizeof(char *) * line_size);
  int i = (*get_next_byte)(get_next_byte_argument);
  
  if ( i == EOF || i < 0 )
    return NULL;
    
  size_t position = 0;
  while( true )
  {
    if ( DEBUG != 0 )
      printf("Reading char = %c\n", (char)i);
    if ( position == line_size )
    {
      line_size *= 2;
      line = (char *) checked_grow_alloc((void *) line, &line_size);
    }
    if ( i < 0 || ((char) i) == '\n' )
    {
      line[position] = '\0';
      return line;
    }
    line[position] = ((char) i);
    position++;
    i = (*get_next_byte)(get_next_byte_argument);
  } 
  if ( DEBUG == 1 )
      printf("pullBytes: Finished reading input\n");
}
Esempio n. 4
0
//Create_buffer simply stores the file into a buffer
char* create_buffer(int(*get_next_byte) (void *), void *get_next_byte_argument)
{
	size_t iter = 0;
	size_t buffer_size = 1024;
	char *buffer = (char *)checked_malloc(buffer_size);
	char current_byte;

	//Iterates through entire file
	while ((current_byte = get_next_byte(get_next_byte_argument)) != EOF)
	{
		//Skips over characters included in a comment
		if (current_byte == '#')
		{
			while ((current_byte = get_next_byte(get_next_byte_argument)) != '\n')
			{
				if (current_byte == EOF)
					break;
				//fprintf(stderr, "%d", current_byte);
				//Continue iterating until the end of the comment is reached.
			}
			continue;
		}

		buffer[iter++] = current_byte;

		if (iter == buffer_size)
			buffer = (char *)checked_grow_alloc(buffer, &buffer_size);
	}
	buffer[iter] = '\0';

	fprintf(stderr, "%s", buffer);
	return buffer;
}
Esempio n. 5
0
void push_command_stack(struct command *command, size_t *size, struct CStack *cstack) {
    if (command != NULL) {
        if (*size <= (cstack->last_item) * sizeof(command_t))
            cstack->command_stack = (command_t *) checked_grow_alloc(cstack->command_stack, size);
        (cstack->last_item)++;
        cstack->command_stack[cstack->last_item] = command;
    }
}
Esempio n. 6
0
command_t retrieve_simple_command(char* char_buffer, int* index)
{
	
	/* code to retrieve simple command 
	should pass its char buffer into make_simple_command to create the actual struct
	*/

	/*temporary initial size of buffer, will resize if needed */
	size_t buffer_size = (size_t) (sizeof(char) * 16);

	/*char buffer for array */
	char* buffer;
	
	buffer = (char*) checked_malloc(buffer_size); 

	int position = 0;
	
	/*will be the char of the head of the stream we are looking at to retrieve the simple command */ 
	char head = char_buffer[*index];

	while (head != EOF && head != '\n' && head != ';')
	{	
			/* we have a valid simple word character that we need to attach to the buffer */
			if (check_for_simple(head) == 1 || head == ' ')
			{
				if (((position+1) * sizeof(char)) == buffer_size)
					{
						buffer = (char*) checked_grow_alloc(buffer, &buffer_size);
					}
					
			
						buffer[position] = head;
						
						position++;
						*index = *index + 1;
						head = char_buffer[*index];
						
			}
			else
			{
			buffer[position] = '\0';
				/*free the buffer since we are done using it */
				*index = *index - 1;
				/*we are done retrieving all the simple command characters so we can create the simple command */			
				return make_simple_command(buffer);
				
			}
	}	
	
	
	buffer[position] = '\0';

	*index = *index - 1;
	
	command_t temp = make_simple_command(buffer);

	return temp;
}
Esempio n. 7
0
command_stream_t make_command_stream (int (*get_next_byte) (void *), void *get_next_byte_arg)
{
  size_t count = 0;
  size_t buffer_size = 1000;
  char* buffer = checked_malloc(buffer_size);
  //create a buffer of charactors to store the readin chars
  // create buffer of input with comments stripped out
  char ch;
  do
  {
    ch = get_next_byte(get_next_byte_arg);

    if (ch == '#') // for comments: ignore everything until '\n' or EOF
    {
      ch = get_next_byte(get_next_byte_arg);
      while(ch != EOF && ch!='\n')
        ch = get_next_byte(get_next_byte_arg);
    }
    //skip all the words until \n
    if (ch!= -1)
    {
      // load into buffer
      buffer[count] = ch;
      count++;

      // expand buffer if necessary
      //if (count == INT_MAX)
      //{
      //  error(1, 0, "Line -1: Input size over INT_MAX.");
      //}
      if (count == buffer_size)
      {
        buffer_size = buffer_size * 2;
        buffer = checked_grow_alloc (buffer, &buffer_size);
      }
    }
  } while(ch != -1);
  token_stream_t return_point = convert_buffer_to_token_stream(buffer,count);
  //build command_tree
  //nuild the first command_tree
  //command_stream_t command_stream_first = init_command_stream ();
  command_t new_command_t = make_command_tree (return_point);
  add_command_to_stream(new_command_t );
  //build the rest command_tree
  while (return_point->next != NULL)
  {
    //make return_point point to next token stream
    token_stream_t temp = return_point->next;
    //free(return_point);
    return_point = temp;
    new_command_t = make_command_tree (return_point);
    add_command_to_stream(new_command_t);
  }
  return command_stream_head;
}
Esempio n. 8
0
/*code to create a simple command struct */
command_t make_simple_command(char *simple_string)
{

	/*malloc a new command struct */
	command_t simplecommand = (command_t)checked_malloc(sizeof(struct command));

	int position = 0;

	/*split string into words by using strtok */
	char *split_string = strtok(simple_string, " ");
	
	/*set its appropriate variables */
	simplecommand->type = SIMPLE_COMMAND;

	simplecommand->status = 0;

	simplecommand->input = NULL;

	simplecommand->output = NULL;
	
	simplecommand->has_parent = false;

	/* temporary size of words array, 8 bytes to store 4 words */
	size_t newsize = (size_t) (8 * sizeof(char*));

	simplecommand->u.word = (char **)checked_malloc(newsize);
	while(split_string != NULL)
	{
	
	if ((position * sizeof(char*)) == newsize)
	{simplecommand->u.word = (char **)checked_grow_alloc(simplecommand->u.word, &newsize);}
		
	/*set the word variable in the union of the command struct to be the simple command word */
	

	simplecommand->u.word[position] = (char *)checked_malloc(strlen(split_string) + 1);
	
	strcpy(simplecommand->u.word[position], split_string);

	position++;

	/*get the next word in the splitted string */
	split_string = strtok(NULL, " ");

	}
	
	simplecommand->u.word[position] = '\0';
	
	return simplecommand;

}
Esempio n. 9
0
void
push_stack (stack *s, const void *src)
{
    void *dst;
    if (s->len == s->max_len) {
        size_t temp = s->max_len * s->elemsize;
        s->elements = checked_grow_alloc(s->elements, &temp);
        s->max_len = temp / s->elemsize;
    }
    
    dst = (char *)s->elements + s->len * s->elemsize;
    memcpy(dst, src, s->elemsize);
    s->len++;
}
int add_dep_to_graph(dependency_graph_t g, dependency_node_t n, int arr)
{
    if(arr == 0)
    {
        if (g->no_dep_mem<(sizeof(dependency_node_t)* (g->no_dep_size+1))) {
            g->no_dep = checked_grow_alloc(g->no_dep, &(g->no_dep_mem));
        }
        g->no_dep[g->no_dep_size] = n;
        g->no_dep_size++;
    }
    else if (arr == 1)
    {
        if(g->dep_mem<(sizeof(dependency_node_t)* (g->dep_size +1)))
        {
            g->dep = checked_grow_alloc(g->dep, &(g->dep_mem));
        }
        g->dep[g->dep_size] = n;
        g->dep_size++;
        
    }
    else
        return -1;
    return 0;
}
Esempio n. 11
0
bool
add_dependency (command_t c, command_t dep)
{
  // We don't allow null commands or dependencies to be passed in
  if (c == NULL || dep == NULL)
    return false;

  // The two extra spaces allow us to have a NULL pointer at the end
  if (c->dependencies == NULL)
    {
      c->dep_alloc_size = 2;
      c->dependencies = checked_malloc (c->dep_alloc_size * sizeof (command_t));
    }
  else if (c->dep_size + 1 >= c->dep_alloc_size)
    c->dependencies = checked_grow_alloc (c->dependencies, &(c->dep_alloc_size));

  c->dependencies[c->dep_size++] = dep;
  c->dependencies[c->dep_size] = NULL; // This should be the case already, but let's be safe.
  
  return true;
}
Esempio n. 12
0
// Adds a command to the list of processes, ranked by parallelizability
void
add_command_t (command_t cmd, command_array **cmd_arr,  
          size_t *arr_size, size_t *arr_capacity)
{
  command_array cmd_info;

  cmd_info.command_tree = cmd;

  // Make the File Tree
  file_tree head = 0;
  get_files (cmd_info.command_tree, &head);
  cmd_info.files = head;

  // Check Size of the array, allocate more memory if needed
  if (*arr_capacity <= *arr_size)
    {
      size_t new_capacity = (*arr_capacity) * (sizeof (command_array));
      *cmd_arr = checked_grow_alloc (*cmd_arr, &new_capacity);
      *arr_capacity = new_capacity / (sizeof (command_array));
    }

  // Initialize new command_array element's command tree
  if (*arr_size != 0)
    {
      cmd_info.ranking = find_ranking (&cmd_info, cmd_arr, *arr_size);
      place_command_by_ranking (&cmd_info, cmd_arr, *arr_size);
    }
  else // The first command is always independent
    {
      cmd_info.ranking = 0;
      (*cmd_arr)[*arr_size] = cmd_info;
    }

  // Change Array Size
  (*arr_size)++;
}
Esempio n. 13
0
word get_next_word(char* buffer, int* it, int bufSize, int* lineNum) {
  word w;
  // deal with END
  if (*it == bufSize) {
    w.type = END;
    return w;
  }
  
  // remove beginning whitespace
  while (buffer[*it] == ' ' || buffer[*it] == '\t') {
    (*it)++;
    if (*it == bufSize) {
      w.type = END;
      return w;
    }
  }
  
  // deal with single-char tokens, ; | ( ) < > #
  // don't need to update string component of the word bc we don't use it
  char c = buffer[*it];
  switch (c) {
    case ';':
      w.type = SEMICOLON;
      w.string = ";";
      (*it) = (*it) + 1;
      return w;
    case '|':
      w.type = PIPE;
      w.string = "|";
      (*it) = (*it) + 1;
      return w;
    case '(':
      w.type = LPARENS;
      w.string = "(";
      (*it) = (*it) + 1;
      return w;
    case ')':
      w.type = RPARENS;
      w.string = ")";
      (*it) = (*it) + 1;
      return w;
    case '<':
      w.type = INPUT;
      w.string = "<";
      (*it) = (*it) + 1;
      return w;
    case '>':
      w.type = OUTPUT;
      w.string = ">";
      (*it) = (*it) + 1;
      return w;

    case '\n':
      w.type = NEWLINE;
      w.string = "\n";
      (*lineNum) = (*lineNum) + 1;
      (*it) = (*it) + 1;
      return w;
      
    case '#':
      w.type = COMMENT;
      w.string = "#";
      while (*it < bufSize && buffer[*it] != '\n')
        (*it) = (*it) + 1;
      if (*it != bufSize) {
        (*it) = (*it) + 1;  // move past new line, point to start of next word
        (*lineNum) = (*lineNum) + 1;
      }
      return w;
      
    default:
      break;
  }
  
  // deal with words
  int wordLen = 64;
  w.string = (char*)checked_malloc(sizeof(char)*wordLen);
  
  // create string
  int stringIndex = 0;
  while (buffer[*it] != ' ' && buffer[*it] != '\t' && buffer[*it] != '\n' && 
        buffer[*it] != ';' && buffer[*it] != '|' && buffer[*it] != '(' && 
        buffer[*it] != ')' && buffer[*it] != '<' && buffer[*it] != '>' && 
        *it != bufSize) 
  {
    if (stringIndex == wordLen)
    {
      wordLen = wordLen*2;
      size_t size_size = sizeof(char)*wordLen;
      w.string = (char*)checked_grow_alloc((void*)w.string, &(size_size));
    }
    if (!(isalpha(buffer[*it]) || isdigit(buffer[*it]) ||
          buffer[*it]=='!' || buffer[*it]=='%' || buffer[*it]=='+' ||
          buffer[*it]==',' || buffer[*it]=='-' || buffer[*it]=='.' ||
          buffer[*it]=='/' || buffer[*it]==':' || buffer[*it]=='@' ||
          buffer[*it]=='^' || buffer[*it]=='_'
        ))
      bad_error(lineNum, __LINE__);
    w.string[stringIndex] = buffer[*it];
    (*it) = (*it) + 1;
    stringIndex++;
  }
  w.string[stringIndex] = '\0';
  
  // assign special words
  if (strcmp(w.string, "if") == 0) {
    w.type = IF;
    w.string = "IF";
    return w;
  }
  else if (strcmp(w.string, "then") == 0) {
    w.type = THEN;
    w.string = "THEN";
    return w;
  }
  else if (strcmp(w.string, "else") == 0) {
    w.type = ELSE;
    w.string = "ELSE";
    return w;
  }
  else if (strcmp(w.string, "fi") == 0) {
    w.type = FI;
    w.string = "FI";
    return w;
  }
  else if (strcmp(w.string, "while") == 0) {
    w.type = WHILE;
    w.string = "WHILE";
    return w;
  }
  else if (strcmp(w.string, "until") == 0) {
    w.type = UNTIL;
    w.string = "UNTIL";
    return w;
  }
  else if (strcmp(w.string, "do") == 0) {
    w.type = DO;
    w.string = "DO";
    return w;
  }
  else if (strcmp(w.string, "done") == 0) {
    w.type = DONE;
    w.string = "DONE";
    return w;
  }
  else {
    w.type = SIMPLE;
    return w;
  }
}
Esempio n. 14
0
command_t
make_simple_command(char *buffer)
{
  if(!strlen(buffer))
    syntax_error();
  command_t command = checked_malloc(sizeof(struct command));
  command->type = SIMPLE_COMMAND; command->status = -1;
  command->input = NULL; command->output = NULL;
  command->u.word = checked_malloc(8*sizeof(char*)); size_t word_size = 8;
  size_t input_size = 8;size_t output_size = 8;      
  size_t cur_word_size; size_t index = 0; bool in_word = false;
  bool in_input = false; bool in_output = false;
  bool input = false; bool output = false; int i;
  for(i = 0; buffer[i]; i++)
  {
    if(buffer[i] == '<')
    {
      if(i == 0 || input || output 
        || in_input || in_output)
        syntax_error();
      command->input = checked_malloc(8*sizeof(char));
      in_input = true;
    }
    else if(buffer[i] == '>')
    {
      if(i == 0 || output || in_output)
        syntax_error();
      command->output = checked_malloc(8*sizeof(char)); 
      in_input = false;
      in_output = true;
    }
    else if(isalnum(buffer[i]) || strchr("!%+,-./:@^_", buffer[i]))
    {
      if(in_input)
      {
        input = true;
        char* string = command->input;
        if(strlen(string) >= input_size)
          checked_grow_alloc(string, &input_size);
        string[strlen(string)] = buffer[i];
      }
      else if(in_output)
      {
        output = true;
        char* string = command->output;
        if(strlen(string) >= output_size)
          checked_grow_alloc(string, &output_size);
        string[strlen(string)] = buffer[i];
      }
      else if(!in_word)
      {
        if((input || output) && !in_input && !in_output)
          syntax_error();
        if(index >= word_size)
          checked_grow_alloc(command->u.word, &word_size);
        command->u.word[index] = checked_malloc(8*sizeof(char));
        cur_word_size = 8;
        command->u.word[index][0] = buffer[i];
        in_word = true;
      }
      else if(in_word)
      {
        char *string = command->u.word[index];
        if(strlen(string) >= cur_word_size)
          checked_grow_alloc(string, &cur_word_size);
        string[strlen(string)] = buffer[i];
      }
    }
    else if(strchr("\t ", buffer[i]))
    {
      if(in_word)
      {
        in_word = false;
        index++;
      }
      else if(input && in_input)
        in_input = false;
      else if(output && in_output)
        in_output = false; 
    }
    else if(buffer[i] == EOF)
    {
      if(index >= word_size)
        checked_grow_alloc(command->u.word, &word_size);
      return command;
    }
    else
      syntax_error();
  }
  memset((void *) buffer, '\0', 1024);
  if(index >= word_size)
        checked_grow_alloc(command->u.word, &word_size);
  return command;
}
Esempio n. 15
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
         void *get_next_byte_argument)
{
  
  //*****************************************
  //         CREATE & ALLOCATE BUFFER
  //*****************************************
  
  
  int current_size = 1024;
  char* buffer = (char*)checked_malloc(sizeof(char)*current_size);
  int byte_count = 0;
  for(;;) {
    int c = get_next_byte(get_next_byte_argument);

    if (byte_count == current_size) {
      current_size = current_size*2;
      size_t size_size = sizeof(char)*current_size;
      buffer = (char*)checked_grow_alloc((void*)buffer, &(size_size));
    }
    if (c != EOF && byte_count < current_size) {
      buffer[byte_count] = c;
      byte_count++;
    }
    else
      break;
  }
   
  //*****************************************
  //   MAKE COMMAND STREAM OF COMMAND NODES
  //*****************************************

  int currentPos = 0;
  int lineNum = 1;

  // initialize command stream
  command_stream_t command_stream = checked_malloc(sizeof(struct command_stream));
  
  // initialize first node
  command_node_t firstCommandNode = checked_malloc(sizeof(struct command_node));
  command_stream->current_node = firstCommandNode;
  command_node_t currentCommandNode = command_stream->current_node;
  
  // initialize first command
  command_t firstCommand = checked_malloc(sizeof(struct command));
  firstCommandNode->command = firstCommand;
  command_t currentCommand = currentCommandNode->command;

  while (get_command(buffer, &currentPos, byte_count, currentCommand, &lineNum) == 1) {
    // create new node
    
    command_node_t newCommandNode = checked_malloc(sizeof(struct command_node));
    newCommandNode->prev = currentCommandNode;
    currentCommandNode->next = newCommandNode;
    currentCommandNode = currentCommandNode->next;

    // create new command for that node
    command_t newCommand = checked_malloc(sizeof(struct command));
    newCommandNode->command = newCommand;
    currentCommand = currentCommandNode->command;
  }
  
  if (currentCommandNode->prev != NULL) // couldn't add first command
    currentCommandNode->prev->next = NULL;
  else
    command_stream->current_node = NULL;

  return command_stream;
}
Esempio n. 16
0
token_stream_t convert_buffer_to_token_stream(char* buffer, size_t size)
{
//in this function convert buffer to the token stream, which is a linked list
	token_t head_token = create_token_with_type(HEAD, NULL, 0);//which created the dummy token 
  	token_t curr_token = head_token;
  	token_t prev_token = NULL;

  	token_stream_t head_stream = checked_malloc(sizeof(token_stream_t));
  	token_stream_t curr_stream = head_stream;
  	curr_stream->head = head_token;
  	curr_stream->tail = head_token;//now the head and tail both points to the head_token

  	int line = 1;
  	size_t index = 0;
  	char c = *buffer;
  	while(index<size)
	  {  	printf("%c\n",c);
  		if(isword(c) )//if c is word
  		{
  			size_t word_length = 5 ;
  			size_t word_position = 0;
  			char *word = (char*)checked_malloc(sizeof(word_length));
  			while(isword(c))
  			{
  				word[word_position] = c;//assign the c to corresponding position
  				if(word_position == word_length)//if reaches the length
  				{
  					word_length*=2;
  					word = checked_grow_alloc(word,&word_length);//resize the word length
  				}
  			word_position++;index++;buffer++;c = *buffer;//update the char and index
			printf("%c\n",c);
  			}
  			token_t now = create_token_with_type(WORD,word,line);
  			curr_token ->next = now;
  			prev_token = curr_token;//assign the previous token to now
  			curr_token = curr_token->next;
  			curr_token->prev = prev_token;
  			prev_token->next = curr_token;
  		}
  		else if(c == '\n')//if c is the new line
  		{
  			line++;
  			if(curr_token->t_type ==LEFT_DERCTION||curr_token->t_type ==RIGHT_DERCTION)
  				//LEFT direction and right direction cannot be followed by new line
  				{
  					error(2, 0, "Line %d: Newline cannot follow redirects.", line);
        			return NULL;
        		}
        	//if the current token type is word or subshell which indicated a new command
        	if(curr_token->t_type==WORD||curr_token->t_type==SUBSHELL)
        		{//create a new token stream
        			curr_stream->next = checked_malloc(sizeof(token_stream));
          			curr_stream = curr_stream->next;
          			curr_stream->head = create_token_with_type(HEAD, NULL, -1);
          			curr_token = curr_stream->head;
      			}
      		//else just treat is as white space
      		index++;buffer++;c = *buffer;
  		}
  		else if(c == ' ' || c =='\t')
  		{
  			index++;buffer++;c = *buffer;
  			//treated it as white space
  		}
  		else if(c == '<')//left direction
  		{
  			curr_token->next = create_token_with_type(LEFT_DERCTION,NULL,line);
			prev_token = curr_token;//assign the previous token to now
  			curr_token = curr_token->next;
  			curr_token->prev = prev_token;
  			prev_token->next = curr_token;
      		buffer++; index++; c = *buffer;
    	}
    	else if (c == '>') // RIGHT REDIRECT
    	{
      		curr_token->next = create_token_with_type(RIGHT_DERCTION, NULL, line);
      		prev_token = curr_token;//assign the previous token to now
  			curr_token = curr_token->next;
  			curr_token->prev = prev_token;
  			prev_token->next = curr_token;
      		buffer++; index++; c = *buffer;
    	}
    	else if (c == ';') // SEQUENCE command
    	{
      		curr_token->next = create_token_with_type(SEMICOLON, NULL, line);
      		prev_token = curr_token;//assign the previous token to now
  			curr_token = curr_token->next;
  			curr_token->prev = prev_token;
  			prev_token->next = curr_token;
      		buffer++; index++; c = *buffer;
    	}
    	else if (c == '&') // and
    	{
	  buffer++;index++;c=*buffer;
	  //if(c!='&')
	  //	{
	  //		error(2, 0, "Line %d: Syntax error. & must be followed by &", line);
	  //		return NULL;
	  //	}
    		 if(c=='&')
    		{
      			curr_token->next = create_token_with_type(AND, NULL, line);
      			prev_token = curr_token;//assign the previous token to now
  				curr_token = curr_token->next;
  				curr_token->prev = prev_token;
  				prev_token->next = curr_token;
      			buffer++; index++; c = *buffer;
      		}
		 else
		   {
		     error(2,0,"Line %d: Syntax error, && must be in pair",line);
		     return NULL;
		     }
    	}
    	else if (c == '|') // OR or PIPELINE
    	{
	  index++;buffer++;c=*buffer;
    		if(c=='|')
    		{
    			curr_token->next = create_token_with_type(OR, NULL, line);
      			prev_token = curr_token;//assign the previous token to now
  				curr_token = curr_token->next;
  				curr_token->prev = prev_token;
  				prev_token->next = curr_token;
				buffer++; index++; c = *buffer;
    		}
    		else
    		{
      			curr_token->next = create_token_with_type(PIPELINE, NULL, line);
      			prev_token = curr_token;//assign the previous token to now
  				curr_token = curr_token->next;
  				curr_token->prev = prev_token;
  				prev_token->next = curr_token;
				//buffer++; index++; c = *buffer;
      		}
      	/*	else
    		{
    			error(2, 0, "Line %d: Syntax error. | only can be followed by | or  ", line);
        		return NULL;
    		}*/
    	}
    	if (c == '(') // SUBSHELL
    	{
      		int subshell_line = line;
      		int nested = 1;

      		size_t count = 0;
      		size_t subshell_size = 64;
      		char* subshell = checked_malloc(subshell_size);

      		// grab contents until subshell is closed
      		while (nested > 0)
      		{
        		buffer++; index++; c = *buffer;
        		//to examine the next char
        		if (index == size)
        			{
          				error(2, 0, "Line %d: Syntax error. EOF reached before subshell was closed.", subshell_line);
          				return NULL;
        			}

        		if (c == '\n')
        		{
          			// consume all following whitespace
          			while (buffer[1] == ' ' || buffer[1] == '\t' || buffer[1] == '\n')
          			{
            			if (buffer[1] == '\n')
              			line++;

            		buffer++;
            		index++;
          			}

          			// pass semicolon
          			c = ';';
          			line++;
        		}
        		else if (c == '(') // count for nested subshells
          			nested++;
        		else if (c == ')') // close subshell
        		{
          			nested--;

          		if (nested == 0) // break if outermost subshell is closed
          		{
            		buffer++; index++; c = *buffer; // consume last close parens
            		break;
          		}
        		}

        // load into subshell buffer
        subshell[count] = c;
        count++;

        // expand subshell buffer if necessary
        if (count == subshell_size)
        {
          subshell_size = subshell_size * 2;
          subshell = checked_grow_alloc (subshell, &subshell_size);
        }
      }

      // create subshell token
      curr_token->next = create_token_with_type(SUBSHELL, subshell, subshell_line);
      curr_token = curr_token->next;
    }
    else if (c == ')') // CLOSE PARENS
    {
      error(2, 0, "Line %d: Syntax error. Close parens found without matching open parens.", line);
      return NULL;
    }

  	}
  	return head_stream;
}
Esempio n. 17
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;
	} 
}
Esempio n. 18
0
/*
 * Use parsedFile to create a set of command structs 
 * for each proper command in order. 
 * Returns the number of commands found.
 */
int createCommandTree(char* parsedFile, int size, command_t* commands)
{

  //Checking for Errors
  if(parsedFile == NULL)
  {
    error(1, 0, "Unexpected Null parsedFile");
    return 0;
  }
  if(commands == NULL)
  {
    error(1, 0, "Unexpected Null commands");
    return 0;
  }

  //Command Count - First command is close parentheses
  int numCommands = 1;

  //variables used to traverse through words in simple command
  int wordCount = -1;
  size_t wordCapacity = 0;
  int isOutput = 0;
  int isInput = 0;

  //Iterate over parsed file to create commands
  int i = 0;
  command_t temp;
  for(i=0; i < size; i++)
  {
    temp = (command_t)checked_malloc(sizeof(struct command));
    temp->status = -1;
    temp->input = NULL;
    temp->output = NULL;
    temp->u.command[0] = NULL;
    temp->u.command[1] = NULL;
    temp->u.word = NULL;
    temp->u.subshell_command = NULL;

    char c = parsedFile[i];
    if( c == '&')
    {
      temp->type = AND_COMMAND;
      commands[numCommands] = temp;
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
      //skip next &
      i++;
    }
    else if(c == '|')
    {
      if(parsedFile[i+1] == '|')
      {
        temp->type = OR_COMMAND;
        //skip next |
        i++;
      }
      else
      {
        temp->type = PIPE_COMMAND;
      }
      commands[numCommands] = temp;
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
    }
    else if(c == ';')
    {
      temp->type = SEQUENCE_COMMAND;
      commands[numCommands] = temp;
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
    }
    else if(c == '(')
    {
      temp->type = SUBSHELL_COMMAND;
      commands[numCommands] = temp;
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
    }
    else if(c == ')')
    {
      free(temp);
      //Point to empty command stored at the front of the array
      commands[numCommands] = commands[0]; 
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
    }
    else if (c == ' ')
    {
      free(temp);
      if(isOutput || isInput)
      {
        isOutput = 0;
        isInput = 0;
        parsedFile[i] = 0;
      }
      else if(wordCount > -1)
      {
        parsedFile[i] = 0;
        wordCount++;
        if((i+1)<size)
        {
          if( parsedFile[i+1] != '&' && parsedFile[i+1] != '|' && parsedFile[i+1] != ';' &&
              parsedFile[i+1] != '(' && parsedFile[i+1] != ')' && parsedFile[i+1] != '>' &&
              parsedFile[i+1] != '<' && !isspace(parsedFile[i+1]))
          {
            if(wordCount >= (int)(wordCapacity-1))
            {
              size_t wordCapNew = wordCapacity*sizeof(char*);
              commands[numCommands-1]->u.word = (char**)checked_grow_alloc(commands[numCommands-1]->u.word, &wordCapNew);
              wordCapacity = wordCapNew/sizeof(char*);
            }
            commands[numCommands-1]->u.word[wordCount] = &(parsedFile[i+1]);
            commands[numCommands-1]->u.word[wordCount+1] = NULL;
          }
        }
      }
    }
    else if (c == '\n' || c == EOF)
    {
      free(temp);
      commands[numCommands] = NULL;
      numCommands++;
      wordCount = -1;
      wordCapacity = 0;
      isOutput = 0;
      isInput = 0;
    }
    else
    {
      if(c == '>')
      {
        free(temp);
        isOutput = 1;
        i++;
        while(i < size && isspace(parsedFile[i]))
        {
          i++;
        }
        if(commands[numCommands-1] == commands[0])
        {
          int lastCommand;
          for(lastCommand = numCommands-2; lastCommand>0; lastCommand--){
            if(commands[lastCommand]->type == SUBSHELL_COMMAND){
              commands[lastCommand]->output = &parsedFile[i]; 
            }
          }
        }
        else
        {
          commands[numCommands-1]->output = &parsedFile[i]; 
        }
      }
      else if(c == '<')
      {
        free(temp);
        isInput = 1;
        i++;
        while(i < size && isspace(parsedFile[i]))
        {
          i++;
        }
        if(commands[numCommands-1] == commands[0])
        {
          int lastCommand;
          for(lastCommand = numCommands-2; lastCommand>0; lastCommand--){
            if(commands[lastCommand]->type == SUBSHELL_COMMAND){
              commands[lastCommand]->input = &parsedFile[i]; 
            }
          }
        }
        else
        {
          commands[numCommands-1]->input = &parsedFile[i]; 
        }
      }
      else
      {
        if(wordCount == -1 && !isOutput && !isInput)
        {
          //initialize word
          temp->type = SIMPLE_COMMAND;
          temp->u.word = (char**)checked_malloc(sizeof(char*)*2);
          temp->u.word[0] = &(parsedFile[i]);
          temp->u.word[1] = NULL;
          commands[numCommands] = temp;
          numCommands++;
          wordCount = 0;
          wordCapacity = 2;
        }
        else
        {
          free(temp);
        }
      }
    }
  }
  if(commands[numCommands-1] != NULL){
      commands[numCommands] = NULL;
      numCommands++;
  }
  return numCommands;
}
Esempio n. 19
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
		     void *get_next_byte_argument)
{
  size_t size = 1000;
  char *buf = (char*) checked_malloc(size); 
  size_t i = 0;
  char c = get_next_byte(get_next_byte_argument);
  while(c != EOF)
  { 
     if(i >= size)
	checked_grow_alloc(buf, &size);
     buf[i]=c;
     c = get_next_byte(get_next_byte_argument);
     i += sizeof(char);
  }
  
  buf[i] = '\0';
  char* err_buf = checked_malloc(size);
  strcpy(err_buf, buf);
  //printf("%s\n", buf);
  // char delimiters  = 'a';
  char* token = strtok(buf, "\n"); 
  size = 1000;
  i = 0;
  // printf("here\n");
  command_stream_t result = checked_malloc(sizeof(command_stream_t));
  result->my_commands = checked_malloc(size);
  result->size = 0;
  result->next_pos = 0;

  while(token != NULL)
  {
    
     //printf("%s\n", token);
     if(analyze_token(token))
     {	
        //printf("%s\n", token);
  	result->my_commands[result->size] = process_buffer(token);
	//printf("Finished: %s\n", token);
	if(result->my_commands[result->size] == NULL)
	{}
	else if(result->my_commands[result->size]->status <= -2)
	{
	   // printf("BUF: %s\n", err_buf);
	   output_error(err_buf, token,
			result->my_commands[result->size]->status);
	}
	else
	{
	// print_command(result->my_commands[command_count]);
           result->size++;
        }
        token = strtok(NULL, "\n"); 
     //   printf("%s\n", token);
     }
     else
     {
       // printf("%s\n", token);
	char *temp = strtok(NULL, "\n");
	//printf("NEXT TOKEN: %s\n", temp);
	if(temp!=NULL)
	{
		strcat(token,temp);
        	printf("%s\n", token);
	}
	else
	   output_error(err_buf, token,0);
     }
  }


/*ONE COMMAND TESTING PURPOSES ONLY
  command_t e1 =  process_buffer(set_of_tokens[0]);
  if(e1==NULL)
  {
	printf("NULL command, comment");
	return result;
  }
  // printf("Word 1: %s %d\n", e1->u.word[2], strlen(e1->u.word[0]));
  print_command(e1);
  // while(e1->u.word[index] != NULL)
  result->my_commands[0] = e1;
*/
  return result;

}
dependency_graph_t build_graph (command_stream_t s)
{
    dependency_graph_t ret_d;
    ret_d = NULL;
    size_t num;
    num = 0;
    size_t iter = 0;
    command_t comm;
    ret_d =checked_malloc(sizeof(struct dependency_graph));
    init_graph(ret_d);
    
    char**args;
    size_t a_size;
    size_t a_mem;
    a_mem = (sizeof(char*));
    args=checked_malloc(a_mem);
    int size= countNodes(s->item);
    
    char** read;
    size_t r_mem;
    size_t r_size;
    
    char** write;
    size_t w_mem;
    size_t w_size;
    
    size_t position=0;
    size_t innerpos = 0;
    
    for(num = 0; num < size;num++)
    {
        comm = s->cArray[num]; //each command in the array
        dependency_node_t n;
        n = checked_malloc (sizeof (struct dependency_node));
        init_node(n, comm); //make a node to add to the graph
        while(iter < ret_d->no_dep_size || iter < ret_d->dep_size)
        {
            //if (debugmode) { printf ("I AM THERE!"); }
            r_size = 0;
            r_mem = (sizeof(char*));
            read = checked_malloc(r_mem);
            w_mem = (sizeof(char*) * 3);
            w_size = 0;
            write = checked_malloc(w_mem);
            a_size = 0;
            size_t aMem = sizeof (char*);
            args = checked_malloc(aMem);
            //find all the arguments passed on the command line
            process_command(comm, args, &a_size, &aMem);
            process_command(comm, read, &r_size, &r_mem);
            process_command(comm, write, &w_size, &w_mem);
            //set all the node properties
            n->read = read;
            n->read_size = r_size;
            n->read_mem = r_mem;
            n->write = write;
            n->write_size = w_size;
            n->write_mem = w_mem;
            n->args = args;
            //printf("iter: %zu\n", iter);
            //error(1,0,"kid");
            //if(comm->input!= NULL)
            //	printf("%s\n", comm->input);
            //printf ("1");
            
            //if there is a value in the output array and there is a node in the executable array
            //of the graph, then add a dependency to the current node and then push it to the dependancy graph
            if(write != NULL && iter < ret_d->no_dep_size){//printf("O\n");
                while(position < w_size){
                    while(innerpos < ret_d->no_dep[iter]->read_size){
                        if(strcmp(ret_d->no_dep[iter]->read[innerpos], write[position])==0)
                        {
                            if (mem_need_grow (n->b4, &n->b4_size, sizeof(dependency_node_t) , n->b4_mem))
                            { n->b4 = checked_grow_alloc (n->b4, &(n->b4_mem)); }
                            
                            n->b4[n->b4_size] = ret_d->no_dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
         
            
            //if there is a value in the output array and there is a node in the dependancy array
            //of the graph, then add a dependency to the current node and then push it to the dependancy graph, because all commands
            //are parsed sequentially, if a dependancy occurs in the dependancy graph, then it must be added to the
            //dependancy graph
            if(write != NULL && iter < ret_d->dep_size){//printf("O\n");
                while(write[position]!=NULL){//printf("O2\n");
                    while(ret_d->dep[iter]->read[innerpos]!=NULL){
                        if(strcmp(ret_d->dep[iter]->read[innerpos], write[position])==0)
                        {
                            n->b4[n->b4_size] = ret_d->dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
            //printf ("3");
            
            //if there is a input depencdancy and there is a matching value in the dependancy graph
            //push the dependancy for this node
            if(read != NULL && iter < ret_d->dep_size){
                while(read[position]!=NULL){
                    while(ret_d->dep[iter]->write[innerpos]!=NULL){
                        if(strcmp(ret_d->dep[iter]->write[innerpos], read[position])==0)
                        {
                            n->b4[n->b4_size] = ret_d->dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
            //printf ("4");
            
            //same thing as above, but check the executable array for a dependancy
            if(read != NULL && iter < ret_d->no_dep_size){
                while(read[position]!=NULL){
                    while(ret_d->no_dep[iter]->write[innerpos]!=NULL){
                        if(strcmp(ret_d->no_dep[iter]->write[innerpos], read[position])==0)
                        {
                            n->b4[n->b4_size] = ret_d->no_dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
            //printf ("5");
            
            //this should do the same for the arguments parsed as command line and not strict
            //I/O redirection. This function checks the dependancy array of the graph
            if(args != NULL && iter < ret_d->dep_size){
                while(args[position]!=NULL){
                    while(ret_d->dep[iter]->write[innerpos]!=NULL){
                        if(strcmp(ret_d->dep[iter]->write[innerpos], args[position])==0)
                        {
                            n->b4[n->b4_size] = ret_d->dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
            //printf ("6");
            
            //same as above, but it checks the executable array for the graph
            if(args != NULL && iter < ret_d->no_dep_size){
                while(args[position]!=NULL){
                    while(ret_d->no_dep[iter]->write[innerpos]!=NULL){
                        if(strcmp(ret_d->no_dep[iter]->write[innerpos], args[position])==0)
                        {
                            n->b4[n->b4_size] = ret_d->no_dep[iter];
                            n->b4_size +=1;
                        }
                        innerpos+=1;
                    }
                    position +=1;
                }
            }
            //printf ("6.5");
            /*if(comm->input != NULL && iter < ret_d->depSize){
             if(ret_d->dep[iter]->c->output == comm->input)
             {
             n->before[n->bef_size] = ret_d->dep[iter];
             n->bef_size+=1;
             //ret_d->dep[iter]->after[ret_d->dep[iter]->aft_size] = n;
             //ret_d->dep[iter]->aft_size++;
             }
             }*/
            //reset all the values that you used before in the loop 
            position = 0;
            innerpos = 0;
            iter +=1;
        }
        //printf ("7");
        //if at any point the bef_size of the current node has been altered so it is greater than 0, add this
        //node to the dependancy array for the graph
        if(n->b4_size > 0){//if (debugmode) printf("befsize = %zu\n", n->bef_size);
            add_dep_to_graph(ret_d, n, 1);}
        //if the node has no dependancies, then push it to the executable array of the dependancy graph
        else{// if (debugmode) printf("befsize = %zu\n", n->bef_size);
            add_dep_to_graph(ret_d, n, 0);}
        //reset iter for the next command that needs to be added
        iter = 0;
        
        //TODO:
        // Determine which nodes already seen depend on this one.
        // Look through the independent nodes.
        // If a match is found, add this node as a dependency
        // And move it to the node with dependencies list
        // Look through the nodes with dependencies.
        // If a match is found, add this node as a dependency
        //printf ("9");
        
    }
    
    return ret_d;
}
Esempio n. 21
0
/* FIXME: Define the type 'struct command_stream' here. This should
complete the incomplete type declaration in command.h. */
command_stream_t make_command_stream(int(*get_next_byte) (void *),
	void *get_next_byte_argument)
{
	/* FIXME: Replace this with your implementation. You may need to
	add auxiliary functions and otherwise modify the source code.
	You can also use external functions defined in the GNU C Library. */
	if (DEBUG) printf("291 Begin make_command_stream\n");
	initStream();
	size_t sizeofBuffer = 1024;
	char* buffer = (char*)checked_malloc(sizeofBuffer);
	char curr;
	size_t filled = 0;
	while ((curr = get_next_byte(get_next_byte_argument)) != EOF) {
		buffer[filled] = curr;
		filled++;
		if (filled == sizeofBuffer) {
			sizeofBuffer *= 2;
			buffer = (char*)checked_grow_alloc(buffer, &sizeofBuffer);
		}
	}
	//***For the parser:
	//Word
	int bufferWordSize = 10;
	int currWord = 0;
	//char ** wordElement;
	char** wordElement = checked_malloc(sizeof(char*));
	wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
	int usedWord = 0;
	//Input
	int bufferInputSize = 10;
	char* inputElement = (char*)checked_malloc(bufferInputSize);
	int usedInput = 0;
	//Output
	int bufferOutputSize = 10;
	char* outputElement = (char*)checked_malloc(bufferOutputSize);
	int usedOutput = 0;
	//***Initialize operator and command stacks
	initStacks();
	if (DEBUG) printf("333 Buffer created, initStacks()\n");
	
	int i = 0;
	while (i < (int)filled)
	{
		if (DEBUG) printf("on buffer %d\n", i);
		//***When you want to add a character*************************//
		int op = -1;
		int openCount = 0;
		int closedCount = 0;

		if (buffer[i] == '`')
			error(1, 0, "Line %d: %c", __LINE__, buffer[i]);

		if (buffer[i] == '(')
		{
			openCount = 1;
			closedCount = 0;
			int x = i;
			while (x < (int) filled)
			{
				x++;
				if (buffer[x] == '(')
					openCount++;
				if (buffer[x] == ')')
					closedCount++;
				if (closedCount == openCount)
					break;
			}
			if (closedCount != openCount)
				error(1, 0, "Line %d: Expected ')' for end of subshell", __LINE__);
		}
		if(buffer[i] == ')')
		{
			if(openCount == 0)
				error(1, 0, "Line %d: Expected '(' before ')'", __LINE__);
		}

		if(buffer[i] = '(') 
		{
			op = numberOfOper(&buffer[i]);
			processOperator(op);
		}

		//Case of ' '
		while (buffer[i] == ' ' && usedWord == 0)
			i++;

		if (buffer[i] == ' ' && usedWord != 0)
		{
			if (usedWord >= bufferWordSize)
			{
				bufferWordSize += 10;
				wordElement[currWord] = (char*)checked_realloc(wordElement[currWord], bufferWordSize);
			}
			//i++;
			wordElement[currWord][usedWord] = '\0';
			while (buffer[i + 1] == ' ')
				i++;
			usedWord = 0;
			bufferWordSize = 10;
			currWord++;
			wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
			//wordElement[currWord][usedWord] = buffer[i];
			//usedWord++;
		}
		//Case of carrots
		//WHAT IF a<b>c>d<a....?! You're making a simple command out of a<b>c which then
		// must also be the word of >d<a
		//Case of '<' first
		else
			if (buffer[i] == '<')
			{
				int k = i;
				while (buffer[k-1] == ' ')
				{
					k--;
					if(buffer[k-1] == '\n')
						error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
				}
				if (wordElement[0][0] == '\0')
					error(1, 0, "Line %d: No command given to '<'", __LINE__);
				i++;
				while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
				{
					if (i == filled)
					{
						if (DEBUG) printf("378 Complete command, free buffer bc EOF\n");
						currWord++;
						wordElement[currWord] = '\0';
						if (usedInput == 0)
							inputElement = NULL;
						if (usedOutput == 0)
							outputElement = NULL;
						makeSimpleCommand(wordElement, inputElement, outputElement);
						completeCommand();
						//free(buffer);
						return headStream;
					}
					if (buffer[i] == ' ')
						i++;
					else
					{
						if (usedInput >= bufferInputSize)
						{
							bufferInputSize += 10;
							inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
						}
						inputElement[usedInput] = buffer[i];
						usedInput++;
						i++;
					}
				}
				if (usedInput >= bufferInputSize)
				{
					bufferInputSize += 10;
					inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
				}
				if (usedInput == 0)
					error(1, 0, "Line %d: No input after '<'", __LINE__);
				inputElement[usedInput] = '\0';
				usedInput++;
				if (buffer[i] == '>')
				{
					i++;
					while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
					{
						if (i == filled)
						{
							if (DEBUG) printf("413 Complete command, free buffer at EOF\n");
							currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							makeSimpleCommand(wordElement, inputElement, outputElement);
							completeCommand();
							//free(buffer);
							return headStream;
						}
						if (buffer[i] == ' ')
							i++;
						else
						{
							if (usedOutput >= bufferOutputSize)
							{
								bufferOutputSize += 10;
								outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
							}
							outputElement[usedOutput] = buffer[i];
							usedOutput++;
							i++;
						}
					}
					if (usedOutput >= bufferOutputSize)
					{
						bufferOutputSize += 10;
						outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
					}
					if (usedOutput == 0)
						error(1, 0, "Line %d: No input after '<'", __LINE__);
					outputElement[usedOutput] = '\0';
					usedOutput++;
					//i--; //Check logic
				}
				i--;
			}
		/////CHECK FOR EXTRA i++!!!!!
		//Case of '>' first
			else
				if (buffer[i] == '>')
				{
					int k = i;
					while (buffer[k-1] == ' ')
					{
						k--;
						if(buffer[k-1] == '\n')
							error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
					}
					if (wordElement[0][0] == '\0')
					error(1, 0, "Line %d: No command given to '<'", __LINE__);
					i++;
					while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
					{
						if (i == filled)
						{
							if (DEBUG) printf("471 Complete Command, free buffer at EOF");
							currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							makeSimpleCommand(wordElement, inputElement, outputElement);
							completeCommand();
							//free(buffer);
							return headStream;
						}
						if (buffer[i] == ' ')
							i++;
						else
						{
							if (usedOutput >= bufferOutputSize)
							{
								bufferOutputSize += 10;
								outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
							}
							outputElement[usedOutput] = buffer[i];
							usedOutput++;
							i++;
						}
					}
					if (usedOutput >= bufferOutputSize)
					{
						bufferOutputSize += 10;
						outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
					}
					if (usedOutput == 0)
						error(1, 0, "Line %d: No input after '<'", __LINE__);
					outputElement[usedOutput] = '\0';
					usedOutput++;
					if (buffer[i] == '<')
					{
						i++;
						while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
						{
							if (i == filled)
							{
								if (DEBUG) printf("505 Complete Command, free buffer at EOF");
								currWord++;
								wordElement[currWord] = '\0';
								if (usedInput == 0)
									inputElement = NULL;
								if (usedOutput == 0)
									outputElement = NULL;
								makeSimpleCommand(wordElement, inputElement, outputElement);
								completeCommand();
								//free(buffer);
								return headStream;
							}
							if (buffer[i] == ' ')
								i++;
							else
							{
								if (usedInput >= bufferInputSize)
								{
									bufferInputSize += 10;
									inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
								}
								inputElement[usedInput] = buffer[i];
								usedInput++;
								i++;
							}
						}
						if (usedInput >= bufferInputSize)
						{
							bufferInputSize += 10;
							inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
						}
						if (usedInput == 0)
							error(1, 0, "Line %d: No input after '<'", __LINE__);
						inputElement[usedInput] = '\0';
						usedInput++;
					}
					wordElement[currWord + 1] = '\0';
					/*if (usedInput == 0)
					inputElement = NULL;
					if (usedOutput == 0)
					outputElement = NULL;
					if(DEBUG) printf("makeSimpleCommand %s\n", wordElement[0]);
					makeSimpleCommand(wordElement, inputElement, outputElement);
					bufferWordSize = 10;
					currWord = 0;
					usedWord = 0;
					usedInput = 0;
					usedOutput = 0;
					wordElement = (char**)checked_malloc(sizeof(char*));
					wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
					inputElement = (char*)checked_malloc(bufferInputSize);
					outputElement = (char*)checked_malloc(bufferOutputSize);*/
					i--;
				}
		//Operators
		//After every operator is encountered, use makeSimpleCommand to push the command on the stack
		//Case of '|'
				else
					if (buffer[i] == '|')
					{
						int k = i;
						while (buffer[k-1] == ' ')
						{
							k--;
							if(buffer[k-1] == '\n')
								error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
						}
						
						if (buffer[i+1] == '|' && operatorStack == NULL)
							error(1, 0, "Line %d: Missing pipe for '||'", __LINE__);
						if (wordElement[0][0] == '\0')
							error(1, 0, "Line %d: Nothing for '|'", __LINE__);
						//if (commandStack == NULL)
						//	error(1, 0, "Line %d: Nothing to run '|' on");
						if (buffer[i + 1] == '|' && buffer[i+2] == '|')
							error(1, 0, "Line %d: Invalid Command, too many '|'", i);
						op = numberOfOper(&buffer[i]);
						//error(1, 0, "Line %d: Nothing to pipe", __LINE__);
						if (buffer[i-1] != ' ')
							currWord++;
						wordElement[currWord] = '\0';
						if (usedInput == 0)
							inputElement = NULL;
						if (usedOutput == 0)
							outputElement = NULL;
						if (DEBUG) printf(" 566 makeSimpleCommand %s\n", wordElement[0]);
						makeSimpleCommand(wordElement, inputElement, outputElement);
						bufferWordSize = 10;
						currWord = 0;
						usedWord = 0;
						usedInput = 0;
						usedOutput = 0;
						wordElement = (char**)checked_malloc(sizeof(char*));
						wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
						inputElement = (char*)checked_malloc(bufferInputSize);
						outputElement = (char*)checked_malloc(bufferOutputSize);
						if (DEBUG) printf("577 Process operator %d\n", op);
						processOperator(op);
						if (op == 3) 
							i++;
						if (buffer[i + 1] == ' ')
							i++;
						//i++;
					}
		//Case of '&'
					else
						if (buffer[i] == '&')
						{
							int k = i;
							while (buffer[k-1] == ' ')
							{
								k--;
								if(buffer[k-1] == '\n')
									error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
							}
							//if (buffer[i] == '&' && operatorStack == NULL)
							//	error(1, 0, "Line %d: Missing pipe for '&&'", __LINE__);
							if (wordElement[0][0] == '\0')
								error(1, 0, "Line %d: Nothing for '|'", __LINE__);
							if (buffer[i + 1] == '&' && buffer[i+2] == '&')
								error(1, 0, "Line %d: Invalid Command, too many '&'", i);
							op = numberOfOper(&buffer[i]);
							if (buffer[i-1] != ' ')
								currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							if (DEBUG) printf("592 makeSimpleCommand %s\n", wordElement[0]);
							makeSimpleCommand(wordElement, inputElement, outputElement);
							bufferWordSize = 10;
							usedWord = 0;
							currWord = 0;
							usedInput = 0;
							usedOutput = 0;
							wordElement = (char**)checked_malloc(sizeof(char*));
							wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
							inputElement = (char*)checked_malloc(bufferInputSize);
							outputElement = (char*)checked_malloc(bufferOutputSize);
							processOperator(op);
							i++;
							if (buffer[i + 1] == ' ')
								i++;
						}
		//Case of ';'
						else
							if (buffer[i] == ';')
							{
													int k = i;
						while (buffer[k-1] == ' ')
						{
							k--;
							if(buffer[k-1] == '\n')
								error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
						}
								if(wordElement[0][0] == '\0')
									error(1, 0, "Line %d: Nothing before sequence", i);
								op = numberOfOper(&buffer[i]);
								currWord++;
								wordElement[currWord] = '\0';
								if (usedInput == 0)
									inputElement = NULL;
								if (usedOutput == 0)
									outputElement = NULL;
								if (DEBUG) printf("617 makeSimpleCommand %s\n", wordElement[0]);
								if ((currWord = 0) || (currWord == 1))
									error(1, 0, "Line %d: Nothing to run ';' on", i);
								makeSimpleCommand(wordElement, inputElement, outputElement);
								bufferWordSize = 10;
								usedWord = 0;
								currWord = 0;
								usedInput = 0;
								usedOutput = 0;
								wordElement = (char**)checked_malloc(sizeof(char*));
								wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
								inputElement = (char*)checked_malloc(bufferInputSize);
								outputElement = (char*)checked_malloc(bufferOutputSize);
								processOperator(op);
								//i++;
							}
		//Case of '\n'
							else
								if (buffer[i] == '\n' && i != 0)
								{
									/*int scChecker = i;
									while (buffer[i + 1] == ' ')
									{
										scChecker++;
										if (buffer[scChecker + 1] == ';')
											error(1, 0, "Line %d: Newline followed by ';'");
									}*/
									if (buffer[i+1] == ';')
										error(1, 0, "Line %d: Newline followed by ';'", i);
									if ((i + 1) == (int)filled)
									{
										currWord++;
										wordElement[currWord] = '\0';
										if (usedInput == 0)
											inputElement = NULL;
										if (usedOutput == 0)
											outputElement = NULL;
										if (DEBUG) printf("654 makeSimpleCommand %s\n", wordElement[0]);
										makeSimpleCommand(wordElement, inputElement, outputElement);
										bufferWordSize = 10;
										currWord = 0;
										usedWord = 0;
										usedInput = 0;
										usedOutput = 0;
										wordElement = (char**)checked_malloc(sizeof(char*));
										wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
										inputElement = (char*)checked_malloc(bufferInputSize);
										outputElement = (char*)checked_malloc(bufferOutputSize);
										completeCommand();
										free(buffer);
										return headStream;
									}
									char lastC;
									int back = 1;
									while (buffer[i - back] == ' ' && i - back >= 0)
									{
										//lastC = buffer[i - back];
										back++;
									}
									lastC = buffer[i - back];
									if (buffer[i + 1] == '\n')
									{
										while (buffer[i + 1] == '\n')
											i++;
										if (lastC != '|' && lastC != '&')
										{
											currWord++;
											wordElement[currWord] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											if (DEBUG) printf("654 makeSimpleCommand %s\n", wordElement[0]);
											makeSimpleCommand(wordElement, inputElement, outputElement);
											bufferWordSize = 10;
											currWord = 0;
											usedWord = 0;
											usedInput = 0;
											usedOutput = 0;
											wordElement = (char**)checked_malloc(sizeof(char*));
											wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
											inputElement = (char*)checked_malloc(bufferInputSize);
											outputElement = (char*)checked_malloc(bufferOutputSize);
											completeCommand();
										}
									}
									else
									{
										if (lastC == '|' || lastC == '&' || lastC == '<' || lastC || '>')
										{
											while (buffer[i + 1] == '\n')
												i++;//////SPIT ERROR?
										}
										else
										{
											char swap = ';';
											op = numberOfOper(&swap);
											wordElement[currWord + 1] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											if (DEBUG) printf(" 679 makeSimpleCommand %s\n", wordElement[0]);
											makeSimpleCommand(wordElement, inputElement, outputElement);
											bufferWordSize = 10;
											currWord = 0;
											usedWord = 0;
											usedInput = 0;
											usedOutput = 0;
											wordElement = (char**)checked_malloc(sizeof(char*));
											wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
											inputElement = (char*)checked_malloc(bufferInputSize);
											outputElement = (char*)checked_malloc(bufferOutputSize);
											processOperator(op);
										}
									}
								}
		//Case of # (comment)
								else
									if (buffer[i] == '#')
									{
										if (DEBUG) printf("698 Got a comment!\n");
										while (buffer[i] != '\n')
											i++;
									}
									//Else
									else
									{
										if (buffer[i] == '\'')
										{
											if (buffer[i + 1] == 'E' && buffer[i + 2] == 'O' && buffer[i + 3] == 'F')
												break;
										}
										//if (buffer[i] != ' ')
										wordElement[currWord][usedWord] = buffer[i];
										usedWord++;
										if (i + 1 == filled)
										{
											currWord++;
											wordElement[currWord] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											makeSimpleCommand(wordElement, inputElement, outputElement);
											completeCommand();
										}
									}
		i++;
	}
	free(buffer);
	return headStream;
}
Esempio n. 22
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);
}
Esempio n. 23
0
///////////////////////////////////////////////////////////////////
//Creates the stream of tokens for use in stack processing later.//
///////////////////////////////////////////////////////////////////
struct token_node_list* create_token_stream(char* input, int num_of_chars){
    
    //Create the token node list
    struct token_node_list* new_token_list= malloc(sizeof(struct token_node_list));
    struct token_node_list* head_of_list = new_token_list;
    //Make dummy token in order to avoid NULL token_type pointer
    struct token_node* dummy_head = add_token(new_token_list, NULL,DUMMY_HEAD);
    new_token_list->head = dummy_head;


    
    char char_to_sort = *input;

    int nested_breaker = 0;
    
    int char_num_counter = 0;
    while(char_num_counter < num_of_chars){
        if(char_to_sort == '\000'){
            return head_of_list;
        }
        //Check to see if word
        if(isWord(char_to_sort)){
            //If so, store the word in its own token
            size_t size = 8;

            char* w = checked_malloc(size);
            size_t word_index = 0;
    
            do{
                w[word_index] = char_to_sort;
                word_index++;
                
                if(word_index == size){
                    size = size*2;
                    w = checked_grow_alloc(w, &size);
                }
                char_num_counter++;     //increment index
                input++;                //increment stream pointer
                char_to_sort = *input;
                
            }while(isWord(char_to_sort) && char_num_counter < num_of_chars);
            new_token_list->cur_node = add_token(new_token_list, w, WORD);
            
        }
        
        //Handle useless white space
        else if(char_to_sort == ' ' || char_to_sort == '\t'){
            char_num_counter++;     //increment index
            input++;                //increment stream pointer
            char_to_sort = *input;
        }
        
        //Check for subshell
        else if( char_to_sort == '('){
            //TODO
            int num_pairs = 1;
            int open_pars = 1;
            int close_pars = 0;
            int parens_valid = 0;
            
            int index = 0;
            int buf_size = 10;      //random low num for most purposes
            
            char *ss_buf = malloc(buf_size* sizeof(char));
            if(ss_buf == NULL)
                fprintf(stderr, "\n Error allocating memory for subshell parse.\n");
            
            while(num_pairs>0){
                char_num_counter++;     //increment index
                input++;                //increment stream pointer
                char_to_sort = *input;
                if(char_num_counter == num_of_chars){ //gone through all chars
                    fprintf(stderr, "\nAll characters used.\n");
                    return NULL;
                }
                else if(char_to_sort == '('){
                    open_pars++;
                    num_pairs++;
                }
                else if(char_to_sort == ')'){
                    //Decrease the number of pairs.
                    close_pars++;
                    num_pairs--;
                    parens_valid = open_pars-close_pars;
		    if(num_pairs == 0 && parens_valid == 0){
		      char_num_counter++;
		      input++;
		      char_to_sort = *input;
		      break; 
		    }
                }
                else if(char_to_sort == '\n'){
                    if(input[1] == '\000'){
                        error(6, 0, "input[1] is null, so nothing after the newline.");
                    }
                    while(input[1] != ' ' || input[1] != '\t' || input[1] != '\n'){                        //Eliminate useless characters
                        input++;
                        char_to_sort++;
                    }
                    //Spec says to substitute semicolon for \n
                    char_to_sort = ';';
                }
                ss_buf[index] = char_to_sort;
                index++;
                
                if(index == buf_size){
                    buf_size+=2;
                    ss_buf = realloc(ss_buf, buf_size*sizeof(char));
                    if(ss_buf == NULL){
                        fprintf(stderr, "\n Error reallocating memory for subshell buffer.\n");
                        return NULL;
                    }
                }
                if( num_pairs == 0 && parens_valid == 0)
                    break;
                else if(num_pairs == 0 && parens_valid != 0){
                    error(2, 0, "\n Mismatched parentheses.\n");
                    return NULL;
                }
               }
                new_token_list->cur_node = add_token(new_token_list, ss_buf, SUBSHELL);
            
        }
        //Check for OR and PIPE
        else if(char_to_sort == '|'){
            char_num_counter++;
            input++; //increment pointer
            char_to_sort = *input;
            //Check to see if the next character is also a pipe, this is an OR
            if(char_to_sort == '|'){
                //Add a token node for OR
                new_token_list->cur_node = add_token(new_token_list, NULL, OR);
                
                char_num_counter++;
                input++;                    //increment pointer
                char_to_sort = *input;         //peek at the next character

            }else
                new_token_list->cur_node = add_token(new_token_list, NULL, PIPE);

        }
        
        //Check for & and AND, code is same as OR case
        else if(char_to_sort == '&'){
            char_num_counter++;
            input++;                    //increment pointer
            char_to_sort = *input;         //peek at the next character
            
            if(char_to_sort == '&'){       //This is an and
                new_token_list->cur_node = add_token(new_token_list, NULL, AND);
                
                char_num_counter++;
                input++;                    //increment pointer
                char_to_sort = *input;         //peek at the next character
            }else if(char_to_sort != '&'){
                error(2,0, "\n Single and...error.\n");
                return NULL;
            }
        }
        
        //Check for left redirect
        else if(char_to_sort == '<'){
            new_token_list->cur_node = add_token(new_token_list, NULL, LEFT_REDIRECT);
            
            char_num_counter++;
            input++;                    //increment pointer
            char_to_sort = *input;         //peek at the next character
        }
        //Check for right redirect
        else if(char_to_sort == '>'){
            new_token_list->cur_node = add_token(new_token_list, NULL, RIGHT_REDIRECT);

            //hurwitz
            char_num_counter++;
            input++;                       //increment pointer
            char_to_sort = *input;         //peek at the next character
        }
        
        //Handle newline
        else if(char_to_sort == '\n'){
            if(*input++ == '\000'){
                return head_of_list;
                break;
            }else
                *input--;
                
            switch(new_token_list->cur_node->token_type){
                case LEFT_REDIRECT:
                case RIGHT_REDIRECT:
                    error(2, 0, "\n Error in syntax. Redirect before newline.\n");
                    return NULL;
                    break;
                case WORD:
                case SUBSHELL:
                    if(new_token_list->cur_node->token_type != DUMMY_HEAD){
                        new_token_list->next = malloc(sizeof(struct token_node_list));
                        
                        if(new_token_list->next == NULL){
                            fprintf(stderr, "\nError allocating memory for new tree in create_token_stream.\n");
                            return NULL;
                        }
                        
                        
                        new_token_list = new_token_list->next;
                        if(new_token_list == NULL)
                            fprintf(stderr, "\n new_token_list is NULL in handling newline\n");

                        new_token_list->head = add_token(new_token_list, NULL, DUMMY_HEAD );
                        new_token_list->cur_node = new_token_list->head;
		

		
                    }
                    break;
                default:
                    break;
            }/*
	    if(char_to_sort == ';'){
	        new_token_list->cur_node = add_token(new_token_list, NULL, SEMICOLON);
	    }*/
            char_num_counter++;
            input++;                    //increment pointer
            char_to_sort = *input;         //peek at the next character
        }
        //Check for semicolon
	
        else if(char_to_sort == ';'){
            new_token_list->cur_node = add_token(new_token_list, NULL, SEMICOLON);
            
            char_num_counter++;     //increment index
            input++;                //increment stream pointer
            char_to_sort = *input;
            
	    }
        else{
            error(4, 0,"\nCharacter is not a word or a special token.\n");
            return NULL;    //no character matches
	    }
    }
    //Return pointer to the top of the token_stream
    return head_of_list;
}
Esempio n. 24
0
command_stream_t
make_command_stream(int
(*get_next_byte)(void *), void *get_next_byte_argument)
{
  // read all the input
  size_t bufferSize = 1024;
  size_t read = 0;
  int val;
  char* buffer = (char*) checked_malloc(bufferSize);

  while ((val = get_next_byte(get_next_byte_argument)) != EOF)
  {
    buffer[read++] = val;
    if (read == bufferSize)
    {
      buffer = (char*) checked_grow_alloc(buffer, &bufferSize);
    }
  }
  if (read == bufferSize)
  {
    buffer = (char*) checked_grow_alloc(buffer, &bufferSize);
  }
  buffer[read] = 0;

  // lex the input
  token* tokens;
  size_t num_tokens = 0;
  lexer(buffer, &tokens, &num_tokens);
  //test_arvore_vec(tokens, num_tokens);
  //exit(0);

  // put all the tokens into a vector
  arvore_vec* v;
  init_arvore_vec(&v, num_tokens);
  size_t i = 0;
  for (; i < num_tokens; i++)
  {
    arvore a;
    a.type = TOKEN_AT;
    a.u.tok = tokens + i;
    append_arvore_vec(v, a);
  }

  // parse tokens into AST
  command_t top_cmd = parse(v);
  //print_command(top_cmd);

  // break top level sequence commands down
  arvore_vec* stack;
  init_arvore_vec(&stack, 10);
  arvore x;
  x.type = COMMAND_AT;
  x.u.cmd = top_cmd;
  append_arvore_vec(stack, x);

  arvore_vec* list;
  init_arvore_vec(&list, 10);

  while (stack->size > 0)
  {
    arvore pop = get_arvore_vec(stack, stack->size - 1);
    command_t cmd = pop.u.cmd;
    stack->size--;
    if (cmd->type == SEQUENCE_COMMAND)
    {
      arvore a;
      a.type = COMMAND_AT;
      a.u.cmd = cmd->u.command[0];
      arvore b;
      b.type = COMMAND_AT;
      b.u.cmd = cmd->u.command[1];
      append_arvore_vec(stack, b);
      append_arvore_vec(stack, a);
    }
    else
    {
      append_arvore_vec(list, pop);
    }
  }

  // create command stream
  command_stream_t cst = (command_stream_t) checked_malloc(
      sizeof(struct command_stream));
  cst->commands = (command_t*) checked_malloc(sizeof(command_t) * list->size);
  for (i = 0; i < list->size; i++)
    cst->commands[i] = get_arvore_vec(list, i).u.cmd;
  cst->size = list->size;
  cst->iterator = 0;

  return cst;

  // debug
  /*char* type_names[11] =
   { "word", ";", "|", "&&", "||", "(", ")", "<", ">", "NL", "?" };

   for (i = 0; i < num_tokens; i++)
   {
   token t = tokens[i];
   if (t.type != NEWLINE_TOKEN)
   printf("%s\t%s\n", type_names[t.type], t.text);
   else
   printf("%s\n", type_names[t.type]);
   }*/
}
Esempio n. 25
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
		     void *get_next_byte_argument)
{

  /* FIXME: Replace this with your implementation.  You may need to
     add auxiliary functions and otherwise modify the source code.
     You can also use external functions defined in the GNU C Library.  */
	
	/* create a previous byte character to see what the previous character was */
	/*char previous_byte = get_next_byte(get_next_byte_argument); */

	/* create a current_byte char to look at the current byte */
	char current_byte; 

	/* create a temporary array to hold all the commands that we will even put together into a tree */
	command_t temp_command = NULL;

	/*char buffer array to take in all the characters from the file in the beginning*/
	char* char_buffer;

	/*index for what element in the character buffer we are currently looking at */
	int buf_index = 0;

	/*malloc initialize size of char buffer to 16, change size of character to indicate that */
	char_buffer = (char *)checked_malloc(256 * sizeof(char));
	size_t size = (size_t) 256 * sizeof(char);
	
	/*for changing subshell commands*/
	int* start_index = (int*) checked_malloc(sizeof(int*));

	/*to create array of commands */
	size_t array_size = (sizeof(command_t) * 1024);
	command_t* temp_array = (command_t*) checked_malloc(array_size);
	int temp_idx = 0;
	int num_cmds = 0;
	
	/*create primary array of commands*/
	command_stream_t output = (command_stream_t) checked_malloc(sizeof(struct command_stream));
	output->command_array = (command_t*) checked_malloc((size_t) sizeof(command_t) * 8);
	output->index = 0;
	output->size = 0;
	
	current_byte = get_next_byte(get_next_byte_argument);
	
	int placeholder;
	
	
	while (current_byte != EOF)
	{
		
		/*realloc memory */
		if (buf_index * sizeof(char) == size)
			{char_buffer = (char *) checked_grow_alloc(char_buffer, &size);}
		char_buffer[buf_index] = current_byte;
		buf_index++ ;
		current_byte = get_next_byte(get_next_byte_argument);
		
	}
	
	char_buffer[buf_index] = current_byte;
	
	/* set buf_index back to 0 once we are done reading */
	buf_index = 0;
	
	/* keep track of line for return error */
	int line_num = 1;

	/* create variable to check if we are in a subshell or not */
	int open_bracket = 0;

	
	char current_buffer = char_buffer[buf_index];
	
	/* checked the bytes in the command buffer we have just created one by one to create commands */	
	while (current_buffer != EOF)
	{
		/* check correct use of paranthesis */
		
		/* store what we are currently looking at in the buffer into a char*/
		

		/* ignore white spaces, tabs, and comment symbol */
		while((current_buffer == ' ') || (current_buffer == '\t') || (current_buffer == '#'))
		{
			/* if comment, ignore until newline */
			if(current_buffer == '#')
					{
						if (buf_index >0)
						{
							if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
							{
								error(1, 0, "invalid character before #");
							}
						}
					while(current_buffer != '\n')
 					{buf_index++;
					current_buffer = char_buffer[buf_index];}
					}
			else
				{buf_index++;
				current_buffer = char_buffer[buf_index];}
		}
	
		if (check_for_simple(current_buffer) == 1)
		{
			/* put code to retrieve following simple command, and put it into a simple command struct */
			temp_command = retrieve_simple_command(char_buffer, &buf_index);

		}
		else if (check_for_special_token(current_buffer) == 1)
		{
			/* check to see which special token the character currently is and put the command into the proper special command struct" */
			if(current_buffer == '&')
			{
			
			if (temp_idx > 0)
			{
				if(temp_array[temp_idx-1]->type != SIMPLE_COMMAND &&
					temp_array[temp_idx-1]->type != RIGHT_PAREN)
				{ error(1,0, "Two consecutive special commands in line: %i",line_num);	}
			}
				buf_index++;
				current_buffer = char_buffer[buf_index];
				/* check if AND_COMMAND is valid */
				if(current_buffer == '&')
				{
				placeholder = buf_index;
				buf_index++;
					current_buffer = char_buffer[buf_index];
					 
				while(current_buffer == ' ' || current_buffer == '\n' || current_buffer == '\t' || current_buffer == '#')
				{
					/* if comment, ignore until newline */
					if(current_buffer == '#')
					{
					
					if (buf_index >0)
						{
							if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
							{
								error(1, 0, "invalid character before #");
							}
						}
					while(current_buffer != '\n')
 					{buf_index++;
					current_buffer = char_buffer[buf_index];}
					}
					buf_index++;
					current_buffer = char_buffer[buf_index];
				}
				if(current_buffer == '(' || check_for_simple(current_buffer) == 1)
				{
					
				temp_command = make_special_command(AND_COMMAND);
				buf_index = placeholder;
				current_buffer = char_buffer[buf_index];
				
				}
				else
				{ error(1,0, "Invalid token after '&' in line: %i",line_num);	}		
				}
				/*also check if next command in array of commands is a simple command or a LEFT PAREN */
				
				
							
	/* add and command to array of commands */
					
			}
			else if(current_buffer == '|')
			{
			
			if (temp_idx > 0)
			{
			if(temp_array[temp_idx-1]->type != SIMPLE_COMMAND &&
					temp_array[temp_idx-1]->type != RIGHT_PAREN)
				{ error(1,0, "Two consecutive special commands in line: %i",line_num);	}
			}
				/* check if OR_COMMAND or PIPE_COMMAND is valid */
				buf_index++;
				current_buffer = char_buffer[buf_index];
				if(current_buffer == '|')
				{
					placeholder = buf_index;
					buf_index++;
					current_buffer = char_buffer[buf_index];
							while(current_buffer == ' ' || current_buffer == '\n' || current_buffer == '\t' || current_buffer == '#')
							{
							
							
								/* if comment, ignore until newline */
									if(current_buffer == '#')
									{
									if (buf_index >0)
									{
										if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
										{
											error(1, 0, "invalid character before #");
										}
									}
									while(current_buffer != '\n')
									{buf_index++;
									current_buffer = char_buffer[buf_index];}
									}
							buf_index++;
							current_buffer = char_buffer[buf_index];
							}
								if(current_buffer == '(' || check_for_simple(current_buffer) == 1)
								{
								temp_command = make_special_command(OR_COMMAND);
								buf_index = placeholder;
								current_buffer = char_buffer[buf_index];
								}
								else
								{
									error(1, 0, "invalid token after '||'");
								}
					buf_index = placeholder;
					current_buffer = char_buffer[buf_index];
					
					
				}
				else if(current_buffer == ' ' || current_buffer == '\n' || 
				current_buffer == '\t' || current_buffer == '(' || check_for_simple(current_buffer) == 1)
					{
					placeholder = buf_index-1;
					while(current_buffer == ' ' || current_buffer == '\n' || current_buffer == '\t' || current_buffer == '#')
							{
								/* if comment, ignore until newline */
									if(current_buffer == '#')
									{
									if (buf_index >0)
									{
										if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
										{
											error(1, 0, "invalid character before #");
										}
									}
									
									while(current_buffer != '\n')
									{buf_index++;
									current_buffer = char_buffer[buf_index];}
									}
							buf_index++;
							current_buffer = char_buffer[buf_index];
							}
					if(current_buffer == '(' || check_for_simple(current_buffer) == 1)
								{	
								temp_command = make_special_command(PIPE_COMMAND);
								buf_index = placeholder;
								current_buffer = char_buffer[buf_index];
								}
								else
								{
									error(1, 0, "invalid token after '||'");
								}		
					buf_index = placeholder;
					current_buffer = char_buffer[buf_index];
					}
			}
			else if(current_buffer == '(')
			{
				open_bracket++;
				placeholder = buf_index;
				buf_index++;
				current_buffer = char_buffer[buf_index];
				while (current_buffer == ' ' || current_buffer == '\n' || current_buffer == '\t' || current_buffer == '#')
				{
				/* if comment, ignore until newline */
									if(current_buffer == '#')
									{
										if (buf_index >0)
										{
											if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
											{
												error(1, 0, "invalid character before #");
											}
										}
									while(current_buffer != '\n')
									{buf_index++;
									current_buffer = char_buffer[buf_index];}
									}
					buf_index++;
					current_buffer = char_buffer[buf_index];
				}
				
				if(check_for_simple(current_buffer) == 1)
					{ temp_command = make_special_command(LEFT_PAREN); }
				else
					{ error(1,0, "Invalid token after '(' in line: %i",line_num);	}
				buf_index = placeholder;
				current_buffer = char_buffer[buf_index];
				
			}
			else if(current_buffer == ')')
			{
				
				open_bracket--;
				if(open_bracket < 0)
				{ error(1,0, "')' cannot precede '(' in line: %i",line_num);	}
				temp_command = make_special_command(RIGHT_PAREN);
			}
			else if(current_buffer == '<')
			{
				if (temp_idx >= 2)
				{
					if (temp_array[temp_idx -2]->type == GREATER_THAN)
					{error(1,0, "Invalid token after '<' in line: %i",line_num);}
				}
				placeholder = buf_index;
				buf_index++;
				current_buffer = char_buffer[buf_index];
				while(current_buffer == ' ' || current_buffer == '\t')
				{
				buf_index++;
				current_buffer = char_buffer[buf_index];
				}
				if (check_for_simple(current_buffer))
				{
					temp_command = make_special_command(LESS_THAN);
					buf_index = placeholder;
					current_buffer = char_buffer[buf_index];
				}
				else
				{ error(1,0, "Invalid token after '<' in line: %i",line_num);}	
			}
			else if(current_buffer == '>')
			{
				placeholder = buf_index;
				buf_index++;
				current_buffer = char_buffer[buf_index];
				while(current_buffer == ' ' || current_buffer == '\t')
				{
				buf_index++;
				current_buffer = char_buffer[buf_index];
				}
				if (check_for_simple(current_buffer))
				{
					temp_command = make_special_command(GREATER_THAN);
					buf_index = placeholder;
					current_buffer = char_buffer[buf_index];
				}
				else
				{ error(1,0, "Invalid token after '>' in line: %i",line_num);	}
			}
			else if(current_buffer == ';' && open_bracket > 0 && temp_idx != 0)
			{
					placeholder = buf_index;
					buf_index++;
					current_buffer = char_buffer[buf_index];
					while (current_buffer == ' ' || current_buffer== '\n' || 
						current_buffer == '\t' || current_buffer == '#')
					{
						if (current_buffer == '#')
						{
						if (buf_index >0)
										{
											if (char_buffer[buf_index-1] != ' ' && char_buffer[buf_index-1] != '\n')
											{
												error(1, 0, "invalid character before #");
											}
										}
						
						while(current_buffer != '\n')
									{buf_index++;
									current_buffer = char_buffer[buf_index];}
									}
						buf_index++;
						current_buffer = char_buffer[buf_index];
					}
					if( check_for_simple(current_buffer) == 1)
					{
						temp_command = make_special_command(SEQUENCE_COMMAND);
						buf_index = placeholder;
						current_buffer = char_buffer[buf_index];
					}
					else if (current_buffer == '(')
					{
						temp_command = make_special_command(SEQUENCE_COMMAND);
						buf_index = placeholder;
						current_buffer = char_buffer[buf_index];
					}
					else if (current_buffer == ')')
					{
						buf_index = placeholder;
						current_buffer = char_buffer[buf_index];
					}
					else
					{ error(1,0, "Invalid token after ';' in line: %i",line_num);	}
			}
			else if(current_buffer == ';'  && temp_idx == 0)
			{error(1,0, "Invalid token in line: %i",line_num);}
			
		}
		else if (current_buffer == '#')
			{
				if(buf_index >0)
				{
					if (char_buffer[buf_index-1] != ' ')
					{error(1,0, "Invalid token in line: %i",line_num);}
				}	
				
				while(current_buffer != '\n')
 					{buf_index++;
					current_buffer = char_buffer[buf_index];}
			}
		else if (current_buffer != '\n' && current_buffer != EOF)
		{error(1,0, "Invalid token in line: %i",line_num);}
		
		/*check if we are at a newline and we are not in a subshell command */
		if(((current_buffer == '\n') || (current_buffer == ';')) && (temp_idx != 0))
		{
			if (open_bracket == 0)
			{
				if (temp_array[temp_idx-1]->type == SIMPLE_COMMAND||
				temp_array[temp_idx-1]->type == RIGHT_PAREN)
				{				
				output->command_array[output->size] = make_tree(temp_array, num_cmds, start_index, 0);
				output->size++;
				
				*start_index = 0;
				
				free(temp_array);
					
				array_size = (size_t) (sizeof(command_t) * 1024);
				temp_array = (command_t*) checked_malloc(array_size);
				temp_idx = 0;
				num_cmds = 0;
				}		
			
			}
			else if (open_bracket>0)
			{
				if (current_buffer == '\n')
				{
					if (temp_idx > 0)
					{
						if (temp_array[temp_idx-1]->type == SIMPLE_COMMAND)
						{	
							placeholder = buf_index;
							buf_index++;
							current_buffer = char_buffer[buf_index];
							while (current_buffer == ' ' || current_buffer == '\n')
							{
								buf_index++;
								current_buffer = char_buffer[buf_index];
							}
							if (current_buffer == '(' || check_for_simple(current_buffer))
							{
							temp_command = make_special_command(SEQUENCE_COMMAND);
							/*check if we need to resize */
							if ((temp_idx * sizeof(command_t)) == array_size)
							temp_array = (command_t*) checked_grow_alloc(temp_array, &array_size);
			
							temp_array[temp_idx] = temp_command;
							temp_idx++;
							num_cmds++;
							}
							buf_index = placeholder;
							current_buffer = char_buffer[buf_index];
							
						}
					
					}
					/* else do nothing */
				}
				else if (current_buffer == ';')
				{
					if (temp_idx > 0)
					{
						if (temp_command->type == SEQUENCE_COMMAND)
						{
							if (temp_array[temp_idx-1]->type == SIMPLE_COMMAND)
							{
								/*check if we need to resize */
								if ((temp_idx * sizeof(command_t)) == array_size)
								temp_array = (command_t*) checked_grow_alloc(temp_array, &array_size);
				
								temp_array[temp_idx] = temp_command;
								temp_idx++;
								num_cmds++;
							}
						}
					}
				}
			}
		}
			
		/*add command to temporary command array */
		if (current_buffer != '\n' && current_buffer != ';' && current_buffer != EOF)
			{		
				if(temp_idx == 0)
				{
					if(temp_command->type != SIMPLE_COMMAND && temp_command->type != LEFT_PAREN)
					{ error(1,0, "The first command must be a simple command or open parenthesis in line: %i",line_num-1);	}
				}
				
				/*check if we need to resize */
				if ((temp_idx * sizeof(command_t)) == array_size)
				temp_array = (command_t*) checked_grow_alloc(temp_array, &array_size);
				
				temp_array[temp_idx] = temp_command;
				temp_idx++;
				num_cmds++;
			}
		
		buf_index++;
		current_buffer = char_buffer[buf_index];
	
		if((current_buffer == EOF) && (temp_idx != 0))
		{
				if (open_bracket > 0)
				{ error(1,0, "Unclosed parenthesis in line: %i",line_num-1);}
				if (temp_idx > 0)
				{
					if (temp_array[temp_idx-1]->type != SIMPLE_COMMAND && temp_array[temp_idx-1]->type != RIGHT_PAREN)
					{	
					error(1, 0, "last command is not a simple command or right paren");
					}
				}
				output->command_array[output->size] = make_tree(temp_array, num_cmds, start_index, 0);
				output->size++;
				
				*start_index = 0;
				
				free(temp_array);	
		}
	
	}

	
	/* previous byte becomes current byte */
	/*previous_byte = current_byte;*/

	return output;
}
Esempio n. 26
0
char*
get_executable_path (char* bin_name)
{
  if(bin_name == NULL)
    return NULL;

  // Check if this is a valid absolute price
  if (file_exists (bin_name))
    return bin_name;

  // First, find the current working directory
  char *cwd = getcwd (NULL, 0);

  // Does it exist relative to the current directory?
  char *path = checked_malloc (sizeof(char) * (strlen(cwd) + strlen(bin_name) + 1 + 1)); // Add one char for '/' and one for NULL
  strcpy (path, cwd);
  strcat (path, "/");
  strcat (path, bin_name);

  if (file_exists (path))
    return path;

  // If not, let's try the system PATH variable and see if we have any matches there
  char *syspath = getenv ("PATH");

  // "The application shall ensure that it does not modify the string pointed to by the getenv() function."
  // By definition of getenv, we copy the string and modify the copy with strtok
  char *syspath_copy = checked_malloc(sizeof (char) * (strlen (syspath) + 1 + 1)); // Add one char for '/' and one for NULL
  strcpy (syspath_copy, syspath);

  // Split the path
  char **path_elements = NULL;
  char *p = strtok (syspath_copy, ":");
  int path_items = 0, i;

  while (p)
  {
    path_elements = checked_realloc (path_elements, sizeof (char*) * (path_items + 2));
    path_elements[path_items] = p;

    path_items++;

    p = strtok (NULL, ":");
  }

  path_elements[path_items] = NULL; // Make sure the last item is null for later looping

  // Now, let's iterate over each item in the path and see if it's a fit
  for (i = 0; path_elements[i] != NULL; i++)
  {
    size_t len = sizeof(char) * (strlen(bin_name) + strlen(path_elements[i]) + 1);
    path = checked_grow_alloc (path, &len);
    strcpy (path, path_elements[i]);
    strcat (path, "/");
    strcat (path, bin_name);

    if (file_exists (path))
    {
      free (path_elements);
      free (syspath_copy);
      return path;
    }
  }

  free (path_elements);
  free (syspath_copy);
  free (path);
  return NULL; // If we got this far, there's an error.
}
Esempio n. 27
0
void input_dependencies (cmd_stream_t stream)
{
  const int INC = sizeof(int);
  size_t size = INC;
  size_t id_size = size;
  
  stream->curr = stream->tail;
  cmd_node_t current = stream->curr;
  cmd_node_t ptr;
  // Loop through each complete command in stream
  // Starts at tail of stream and goes backwards
  
  while (current != NULL)
  {
    size = INC;
    int* ids = checked_malloc(size*sizeof(int));
    int id_index = 0;
    ids[0] = 0; 
    ptr = stream->head;

    // Check each file dependency 
    if (current->depends != NULL)
    {
      current->depends->curr = current->depends->head;
      file_node_t ptr0 = current->depends->curr;
      
      // Go through each file in current command
      while (ptr0 != NULL)
      {
        //printf("Going through each file in current command\n");
        ptr = stream->head;
        // Go through each previous command
        while (ptr != current)
        {
          // Go through each file in this previous command 
          if (ptr->depends != NULL)
          {
            ptr->depends->curr = ptr->depends->head;
            while (ptr->depends->curr != NULL)
            {
              // Found dependent file
              if (strcmp(ptr0->name, ptr->depends->curr->name) == 0 &&
                  (ptr->depends->curr->type == 'w' || ptr0->type == 'w'))
              {
                int j = 0;
                while (j < id_index)
                {
                  if (ids[j] == ptr->id)
                    break;
                  ++j;
                }
                // If command id was not already in list, add it
                if (j == id_index)
                {
                  ids = checked_grow_alloc(ids, &size);
                  ids[id_index] = ptr->id;
                  ++id_index;
                  int y;
                }
              }
              ptr->depends->curr = ptr->depends->curr->next;
            }
          }
          ptr = ptr->next;
        }
        ptr0 = ptr0->next;
      }
    }
    current->depend_id = ids;
    // End int array with signal bit (0 can never be an id)
    ids[id_index] = 0;

    current = current->prev;
  }

  stream->curr = stream->head;
}
Esempio n. 28
0
token_stream_t
char_stream_to_token_stream (char_stream_t cst)
{
	// Initialize the new token_stream, allocating memory and setting variables
	token_stream_t stream = checked_malloc(sizeof(struct token_stream));
	stream->head = NULL;
	stream->tail = NULL;
	
	// Prev_token will keep track of the previous token for syntax purposes
	// Initializing prev_token here
	token_t prev_token = checked_malloc(sizeof(struct token));
	prev_token->type = NEWLINE; 		// Makes it easy for the first real line
	prev_token->string = NULL;
	
	// Start the character stream
	char_stream_init(cst);

	char ch;
	bool in_andorpipe_command = false;
	int paren_count = 0;
	int line_num = 1; 				// For error reporting
	
	// Loop through all the characters, tokenizing them and checking syntax
	while ((ch = char_stream_current(cst)) != EOF)
	{
		if (ch == '#') 			// COMMENT
		{
			if(cst->last != '\0' && cst->last != '\n' &&
			   cst->last != '\t' && cst->last != ' ')
			{
				error(1,0,"Comment Error");
			}
			while (ch != '\n') 	// until you find a new line...
			{
				ch = char_stream_read(cst); // iterate through characters
			}
		}
		else if (ch == '\n') 		// NEWLINE
		{
			line_num++;
			switch (prev_token->type) 					// check if it's valid syntax
			{
				case IN:
				case OUT:
					error (1, 0, "%d: Invalid newline after previous token\n",line_num);
					break;
				case AND:
				case OR:
				case PIPE:
				case NEWLINE:
					ch = char_stream_read(cst);				// keep going...
					break;
				default:
				{
					// Create the new token and add it to the token stream
					token_t new_token = checked_malloc(sizeof(struct token));
					new_token->type = NEWLINE;
					new_token->string = NULL;
					token_stream_add(stream, new_token);
					
					// set the prev_token for syntax-checking
					prev_token->type = NEWLINE;
					prev_token->string = NULL;
					ch = char_stream_read(cst);
				}
			}
		}
		else if (isspace(ch))			// BLANK SPACE (not \n)
		{
			ch = char_stream_read(cst);
		}
		else if (ch == ')')		// CLOSED PAREN
		{
			switch (prev_token->type)
			{
				case AND:
				case OR:
				case PIPE:
				case IN:
				case OUT:
				case OPEN_PAREN:
					error (1, 0, "%d: Invalid ')' after previous token\n", line_num);
					break;
				default:
				{
					// Create the new token and add it to the token stream
					token_t new_token = checked_malloc(sizeof(struct token));
					new_token->type = CLOSE_PAREN;
					new_token->string = NULL;
					token_stream_add(stream, new_token);
					
					// set the prev_token for syntax-checking
					prev_token->type = CLOSE_PAREN;
					prev_token->string = NULL;
					ch = char_stream_read(cst);
					
					paren_count--;
				}
			}
		}
		else if (ch == '(')		// OPEN PAREN
		{
			switch (prev_token->type)
			{
				case WORD:
				case IN:
				case OUT:
				case CLOSE_PAREN:
					error (1, 0, "%d: Invalid '(' after previous token\n", line_num);
					break;
				default:
				{
					// Create the new token and add it to the token stream
					token_t new_token = checked_malloc(sizeof(struct token));
					new_token->type = OPEN_PAREN;
					new_token->string = NULL;
					token_stream_add(stream, new_token);
					
					// set the prev_token for syntax-checking
					prev_token->type = OPEN_PAREN;
					prev_token->string = NULL;
					ch = char_stream_read(cst);
					
					paren_count++;
					in_andorpipe_command = false;
					// printf("%i: in_andorpipe_command set to FALSE\n", line_num);
				}
			}
		}
		else if (ch == '&')			// AND
		{
			ch = char_stream_read(cst); 					// Check to see if & or &&
			if (ch == '&')
			{
				switch (prev_token->type)
				{
					case WORD:
					case CLOSE_PAREN:
					{
						// Create the new token and add it to the token stream
						token_t new_token = checked_malloc(sizeof(struct token));
						new_token->type = AND;
						new_token->string = NULL;
						token_stream_add(stream, new_token);
					
						// set the prev_token for syntax-checking
						prev_token->type = AND;
						prev_token->string = NULL;
						ch = char_stream_read(cst);
						
						in_andorpipe_command = true;
						// printf("%i: in_andorpipe_command set to TRUE\n", line_num);
						
						break;
					}
					default:
						error (1, 0, "%d: Invalid '&&' after previous token\n", line_num);
				}
			}
			else
			{
				error (1, 0, "%d: Invalid token: & must be followed by &\n", line_num);
			}
		}
		else if (ch == '|')
		{
			ch = char_stream_read(cst);
        	switch (prev_token->type)
            {
            	case WORD:
            	case CLOSE_PAREN:
            		if (ch == '|')
                	{
                		// Create the new token and add it to the token stream
                  		token_t new_token = checked_malloc (sizeof (struct token));
                  		new_token->type = OR;
                  		new_token->string = NULL;
                  		token_stream_add(stream, new_token);
                  		
                  		// set the prev_token for syntax-checking
						prev_token->type = OR;
                  		prev_token->string = NULL;
                  		ch = char_stream_read(cst);
						
						in_andorpipe_command = true;
						// printf("%i: in_andorpipe_command set to TRUE\n", line_num);
						
                	}
             		else
                	{
                		// Create the new token and add it to the token stream
                  		token_t new_token = checked_malloc (sizeof(struct token));
                  		new_token->type = PIPE;
                  		new_token->string = NULL;
                  		
                  		// set the prev_token for syntax-checking
                  		token_stream_add(stream, new_token);
                  		prev_token->type = PIPE;
                  		prev_token->string = NULL;
						
						in_andorpipe_command = true;
						// printf("%i: in_andorpipe_command set to TRUE\n", line_num);
                	}
              		break;
				default:
            	error (1, 0, "%d: Invalid '|' or '||' after previous token\n", line_num);
            }
		}
		else if (ch == ';')
		{
			switch (prev_token->type)
			{
				case WORD:
				case CLOSE_PAREN:
				{
					// Create the new token and add it to the token stream
              		token_t new_token = checked_malloc (sizeof (struct token));
            		new_token->type = SEQ;
             		new_token->string = NULL;
             		token_stream_add(stream, new_token);
                 		
             		// set the prev_token for syntax-checking
					prev_token->type = SEQ;
             		prev_token->string = NULL;
            		ch = char_stream_read(cst);
             		break;
				}
				default:
					error (1, 0, "%d: Invalid ';' after previous token\n", line_num);                  		
			}
		}
		else if (ch == '<')
		{
			switch (prev_token->type)
			{
				case WORD:
				case CLOSE_PAREN:
				{
					// Create the new token and add it to the token stream
              		token_t new_token = checked_malloc (sizeof (struct token));
            		new_token->type = IN;
             		new_token->string = NULL;
             		token_stream_add(stream, new_token);
                 		
             		// set the prev_token for syntax-checking
					prev_token->type = IN;
             		prev_token->string = NULL;
            		ch = char_stream_read(cst);
             		break;
				}
				default:
					error (1, 0, "%d: Invalid '<' after previous token\n", line_num);
			}
		}
		else if (ch == '>')
		{
			switch (prev_token->type)
			{
				case WORD:
				case CLOSE_PAREN:
				{
					// Create the new token and add it to the token stream
              		token_t new_token = checked_malloc (sizeof (struct token));
            		new_token->type = OUT;
             		new_token->string = NULL;
             		token_stream_add(stream, new_token);
                 		
             		// set the prev_token for syntax-checking
					prev_token->type = OUT;
             		prev_token->string = NULL;
            		ch = char_stream_read(cst);
             		break;
             	}
             	default:
             		error (1, 0, "%d: Invalid '>' after previous token\n", line_num);
			}
		}
		else
		{
			if (prev_token->type == CLOSE_PAREN)
            	error (1, 0, "%d: Invalid string after ')'\n", line_num);
            if (!is_regular_char(ch))
			{
            	error (1, 0, "%d: Invalid character '%c'\n", line_num, ch);
            }
            size_t count = 0;
            size_t max = 8;
            
            token_t new_token = checked_malloc(sizeof(struct token));
            new_token->type = WORD;
            new_token->string = checked_malloc(max * sizeof(char));
            
            while (is_regular_char(char_stream_current(cst)))
            {
            	if (count + 1 >= max)
            		checked_grow_alloc(new_token->string, &max);
            	new_token->string[count++] = char_stream_current(cst);
            	ch = char_stream_read(cst);
            }
            
            new_token->string[count] = '\0'; // end the string
            token_stream_add(stream, new_token);
            prev_token->type = WORD;
            prev_token->string = NULL;
			
			in_andorpipe_command = false;
			// printf("%i: in_andorpipe_command set to FALSE\n", line_num);
		}
		
	}
	if (in_andorpipe_command)
		error (1, 0, "EOF: Reached end of file without correct number of commands (and, or, pipe)\n");
	if (paren_count)
		error (1, 0, "EOF: Incorrect number of parentheses\n");
	//print_tokens(stream);
	return stream;
}
Esempio n. 29
0
void redirect_commands(command_t symb, command_t command_input, command_t command_output)
{	
	size_t input_size= 32 * sizeof(char);
	int index = 0;
	command_input->input = (char *) checked_malloc(32 * sizeof(char));
	command_input->input[0] = '\0';
	
	size_t output_size= 32 * sizeof(char);
	command_output->output = (char *) checked_malloc(32 * sizeof(char));
	command_output->output[0] = '\0';
	
	char* nothing = (char*) checked_malloc(sizeof(char*));
	nothing[0] = '\0';
	
	if (symb-> type == GREATER_THAN)
	{
		/*if (command_output->output != NULL)
		{ error(1,0, "Invalid token for output in line: 0 ");} */
	
			if (command_input->u.word[index] != NULL)
			{
			if (sizeof(command_input->u.word[index]) >= output_size)
				{command_output->output = (char*) checked_grow_alloc(command_output->output, &output_size);}
			strcat(command_output->output, command_input->u.word[index]);
			index++;
			}

	}
	
	index = 0;
	
	if (symb-> type == LESS_THAN)
	{
		/*if (command_input->input != NULL)
		{ error(1,0, "Invalid token for input in line: 0");} */
	
			if (command_output->u.word[index] != NULL)
			{

			if (sizeof(command_output->u.word[index]) >= input_size)
				{command_input->input = (char*) checked_grow_alloc(command_input->input, &input_size);}
			
			strcat(command_input->input, command_output->u.word[index]);
			index++;
			
			}

	}
	
	
	
	
		if (symb->type == LESS_THAN)
	{
		symb->has_parent = 1;
		command_output->has_parent = 1;
	}
	
	if (symb->type == GREATER_THAN)
	{
		symb->has_parent = 1;
		command_input->has_parent = 1;
	}
		
}
Esempio n. 30
0
/*
 * Fill parseFile with valid character array input
 * Remove all white space and comments
 * Return the size of the array
 */
int parseFile(int (*get_next_byte) (void *), void *get_next_byte_argument, char* parsedFile)
{
  int size = 0;
  size_t capacity = 256;

  //Allocate space in parsedFile
  if(!parsedFile)
  {
    error(1, 0, "Unexpected Null parsedFile");
    return 0;
  }

  //to hold next character
  char c;
  //For parantheses correctness
  int parenCount = 0;

  //Used to remove comments
  int isComment = 0;

  //Used to check for valid redirection
  int findSingleWord = 0;
  int singleWordStarted = 0;
  int foundLessThan = 0;
  int foundSingleWord = 0;

  while( (c = get_next_byte(get_next_byte_argument)) && c != 0 && !feof(get_next_byte_argument))
  {
    //printf("DEBUG: parseFile: checking %c\n", c);
    // If the beginning of a comment is reached
    // set the comment flag to one and continue 
    // through the loop
    if(c == '#')
    {
      isComment = 1;
      continue;
    }

    // If comment flag is set and the current character is not
    // a new line, then skip character and continue loop
    // Otherwise, if it is a new line, unset the comment flag
    if(isComment && c != '\n'){
      continue;
    }else if(isComment){
      isComment = 0;
    }

    // If character is a new line, check if it is an 
    // extra or arbitrary new line. If it is, then
    // remove it. Otherwise, if its any other arbitrary
    // white space, also remove it. If not a white space,
    // then check grammar.
    if(c == '\n')
    {
      int parsePointer = size-1;
      if(size == 0 || parsedFile[parsePointer] == '\n')
      {
        continue;
      }
      if(parsedFile[parsePointer] == ' ')
      {
        if(parsePointer-1 >= 0){
          if(parsedFile[parsePointer-1] == '&' || parsedFile[parsePointer-1] == '|' || parsedFile[parsePointer-1] == ';' )
          {
            continue;
          }
        }
        parsedFile[parsePointer] = '\n';
        continue;
      }
      if(parsedFile[parsePointer] == '&' || parsedFile[parsePointer] == '|' || parsedFile[parsePointer] == ';'){
        continue;
      }
    }
    else if(isspace(c))
    {
      if(c != ' ')
      {
        c = ' ';
      }
      if(size == 0 || parsedFile[size-1] == ' ' || parsedFile[size-1] == '\n')
      {
        continue;
      }
    }
    else
    {
      if(!isProperGrammar(parsedFile, size, &parenCount, c))
      {
        error (1, 0, "Improper Syntax in File: bad grammar");
      }
    }

    // If an I/O flag has been set to find
    // single file name, then check for valid
    // file name. Otherwise check if current character is
    // I/O character 
    if(findSingleWord)
    {
      if(foundSingleWord)
      {
        if( c == '|' || c== '&' || c == ';' || c == '(' || 
                 c == '\n')
        {
          findSingleWord = 0;
          foundSingleWord = 0;
          singleWordStarted = 0;
          foundLessThan = 0;
        }
        else if(c == '>' && foundLessThan)
        {
          foundLessThan = 0;
          findSingleWord = 1;
          foundSingleWord = 0;
          singleWordStarted = 0;
        }
        else if(isspace(c))
        {
          //do nothing
        }
        else
        {
          error (1, 0, "Improper Syntax in File: Improper Redirect");
          return 0;
        }
      }
      else if(singleWordStarted)
      {
        if( c== '(' || c== '<')
        {
          error (1, 0, "Improper Syntax in File: Improper Redirect");
          return 0;
        }
        else if( c == '|' || c== '&' || c == ';' || c == '\n')
        {
          findSingleWord = 0;
          foundSingleWord = 0;
          singleWordStarted = 0;
          foundLessThan = 0;
        }
        else if(isspace(c))
        {
          foundSingleWord = 1;
        }
        else if( c == '>' && foundLessThan )
        {
          findSingleWord = 1;
          singleWordStarted = 0;
          foundLessThan = 0;
          foundSingleWord = 0;
        }
        else if(c == '>')
        {
          error (1, 0, "Improper Syntax in File: Improper Redirect");
          return 0;
        }
      }
      else if( c == '|' || c== '&' || c == ';' || c == '(' || 
              c == '>' || c == '<' || c == '\n')
      {
        error (1, 0, "Improper Syntax in File: Improper Redirect");
        return 0;
      }
      else if(isspace(c))
      {
        //do nothing
      }
      else
      {
        singleWordStarted = 1;
      }
    }
    else if(c == '<')
    {
      findSingleWord = 1;
      foundLessThan = 1;
      foundSingleWord = 0;
      singleWordStarted = 0;
    }
    else if(c == '>')
    {
      findSingleWord = 1;
      foundLessThan = 0;
      foundSingleWord = 0;
      singleWordStarted = 0;
    }

    if(!(size < (signed int)capacity))
    {
      parsedFile = (char*)checked_grow_alloc((void*)parsedFile, &capacity);
    }

    // Remove any extra white space before 
    // New lines and close parentheses
    if(c == '>' || c == '\n')
    {
      int parsePointer = size-1;
      while(parsePointer >= 0)
      {
        if(isspace(parsedFile[parsePointer]))
        {
          size--;
        }
        else
        {
          break;
        }
        parsePointer--;
      }
    }

    // Add space before any special characters
    if(size > 0)
    {
      if(c == ')' || c == ';' || c == '(' || c == '\n' || c == '>' || c == '<' )
      {
        if(parsedFile[size-1] != ' ')
        {
          parsedFile[size] = ' ';
          size++;
        }
      }
      else if( c == '&' || c == '|')
      {
        if(parsedFile[size-1] != ' ' && parsedFile[size-1] != c)
        {
          parsedFile[size] = ' ';
          size++;
        }
      }
      if(!(size < (signed int)capacity))
      {
        parsedFile = (char*)checked_grow_alloc((void*)parsedFile, &capacity);
      }
    }
    //Add Valid Character to Array
    parsedFile[size] = c;

    //Increment character count
    size++;
  }

  //Check if file ended properly
  if(parsedFile[size-1] != ';' && parsedFile[size-1]!='\n' && !isProperGrammar(parsedFile, size, &parenCount, ';'))
  {
    error (1, 0, "Improper Syntax in File: File terminated incorrectly");
  }

  //add end of file
  if(!(size < (signed int)capacity))
  {
    parsedFile = (char*)checked_grow_alloc((void*)parsedFile, &capacity);
  }

  //Add Null Character to End of Array
  parsedFile[size] = '\0';
  //size++;

  if(parenCount > 0)
  {
    error (1, 0, "Improper Syntax in File: Unclosed Parentheses");
    return 0;
  }

  //printf("%s\n", parsedFile);
  return size;
}