Beispiel #1
0
//释放用户进程资源
//1 页表中对应的物理页
//2 虚拟内存池占物理页框
//3 关闭打开的文件
static void release_prog_resource(struct task_struct* release_thread){
	uint32_t* pgdir_vaddr = release_thread->pgdir;
	uint16_t user_pde_nr = 768,pde_idx = 0;
	uint32_t pde = 0;
	uint32_t* v_pde_ptr = NULL;		//v表示var,和函数pde_ptr区分

	uint16_t user_ptr_nr = 1024,pte_idx = 0;
	uint32_t pte = 0;
	uint32_t* v_pte_ptr = NULL;		//v表示var,和函数pte_ptr区分

	uint32_t* first_pte_vaddr_in_pde = NULL;	//用来记录pde中第0个pte的地址
	uint32_t pg_phy_addr = 0;

	//回收页表中用户空间的页框
	while(pde_idx < user_pde_nr){
		v_pde_ptr = pgdir_vaddr + pde_idx;
		pde = *v_pde_ptr;
		if(pde & 0x00000001){	//如果页目录项p位表示1,表示该页目录项下可能有页表项
			first_pte_vaddr_in_pde = pte_ptr(pde_idx * 0x400000);	//一个页表表示的内存容量是4M,即0x400000
			pte_idx = 0;
			while(pte_idx < user_ptr_nr){
				v_pte_ptr = first_pte_vaddr_in_pde + pte_idx;
				pte = *v_pte_ptr;
				if(pte & 0x00000001){
					//将pte中记录的物理页框直接在相应内存池的位图中清0
					pg_phy_addr = pte & 0xfffff000;
					free_a_phy_page(pg_phy_addr);
				}
				pte_idx++;
			}
			//将pde中记录的物理页框直接在相应内存池中清0
			pg_phy_addr = pde & 0xfffff000;
			free_a_phy_page(pg_phy_addr);
		}
		pde_idx++;
	}

	//回收用户虚拟地址池所占的物理内存
	uint32_t bitmap_pg_cnt = (release_thread->userprog_vaddr.vaddr_bitmap.btmp_bytes_len) / PG_SIZE;
	uint8_t* user_vaddr_pool_bitmap = release_thread->userprog_vaddr.vaddr_bitmap.bits;
	mfree_page(PF_KERNEL,user_vaddr_pool_bitmap,bitmap_pg_cnt);

	//关闭进程打开的文件
	uint8_t local_fd = 3;
	while(local_fd < MAX_FILES_OPEN_PER_PROC){
		if(release_thread->fd_table[local_fd] != -1){
			if(is_pipe(local_fd)){
				uint32_t global_fd = fd_local2global(local_fd);
				if(--file_table[global_fd].fd_pos == 0){
					mfree_page(PF_KERNEL,file_table[global_fd].fd_inode,1);
					file_table[global_fd].fd_inode = NULL;
				}
			}else{
				sys_close(local_fd);
			}
		}
		local_fd++;
	}
}
Beispiel #2
0
// used to skip unusable portions of the snapshot
void OS::read_or_seek(void* ptr, int32 size, FILE* f) {
  if (okToUseCodeFromSnapshot) {
    OS::FRead(ptr, size, f);
  } else if (!is_pipe(f)) {
    // can't just let fseek fail as it alters the state of f
    if (fseek(f, size, SEEK_CUR)) fatal("seek failed");
  } else {
    while (size--) getc(f);
  }
  if (ferror(f)) fatal("read error");
}
Beispiel #3
0
gmx_bool gmx_eof(FILE *fp)
{
    char data[4];
    gmx_bool beof;

    if (is_pipe(fp))
        return feof(fp);
    else {
        if ((beof=fread(data,1,1,fp))==1)
            gmx_fseek(fp,-1,SEEK_CUR);
        return !beof;
    }
}
Beispiel #4
0
//更新inode打开数
static void update_inode_open_cnts(struct task_struct* thread){
	int32_t local_fd = 3,global_fd = 0;
	while(local_fd < MAX_FILES_OPEN_PER_PROC){
		global_fd = thread->fd_table[local_fd];
		ASSERT(global_fd < MAX_FILE_OPEN);
		if(global_fd != -1){
			if(is_pipe(local_fd)){
				file_table[global_fd].fd_pos++;
			}else{
				file_table[global_fd].fd_inode->i_open_cnts++;
			}
		}
		local_fd++;
	}
}
Beispiel #5
0
int		exec_tree(t_tree_op *node)
{
	if (!node)
		return (-1);
	if (node->type == NODE_EXPR)
		return (exec_node(node));
	if (node->type == NODE_OPERATOR && is_pipe(node->data))
		return (piped_node(node));
	if (node->type == NODE_OPERATOR && is_semi_colon(node->data))
	{
		exec_tree(node->left);
		exec_tree(node->right);
	}
	return (0);
}
Beispiel #6
0
int main(int argc, char *argv[])
{
	struct daemon_conf config;
	struct rlimit limit;
	int rc;

	/* Check params and build regexpr */
	setlocale (LC_ALL, "");
	if (check_params(argc, argv))
		return 1;

	/* Raise the rlimits in case we're being started from a shell
	* with restrictions. Not a fatal error.  */
	limit.rlim_cur = RLIM_INFINITY;
	limit.rlim_max = RLIM_INFINITY;
	setrlimit(RLIMIT_FSIZE, &limit);
	setrlimit(RLIMIT_CPU, &limit);
	set_aumessage_mode(MSG_STDERR, DBG_NO);
	(void) umask( umask( 077 ) | 027 );
	very_first_event.sec = 0;
	reset_counters();

	if (user_file == NULL) {
		/* Load config so we know where logs are */
        	if (load_config(&config, TEST_SEARCH))
			fprintf(stderr, 
				"NOTE - using built-in logs: %s\n",
				config.log_file);
	} else {
		config.sender_ctx = NULL;
		config.log_file = NULL;
		config.dispatcher = NULL;
		config.node_name = NULL;
		config.space_left_exe = NULL;
		config.action_mail_acct = NULL;
		config.admin_space_left_exe = NULL;
		config.disk_full_exe = NULL;
		config.disk_error_exe = NULL;
		config.krb5_principal = NULL;
		config.krb5_key_file = NULL;
	}
		
	print_title();
	lol_create(&lo);
	if (user_file)
		rc = process_file(user_file);
	else if (force_logs)
		rc = process_logs(&config);
	else if (is_pipe(0))
		rc = process_stdin();
	else
		rc = process_logs(&config);
	lol_clear(&lo);
	if (rc) {
		free_config(&config); 
		return rc;
	}

	if (!found && report_detail == D_DETAILED && report_type != RPT_TIME) {
		printf("<no events of interest were found>\n\n");
		destroy_counters();
		aulookup_destroy_uid_list();
		aulookup_destroy_gid_list();
		free_config(&config); 
		return 1;
	} else 
		print_wrap_up();
	destroy_counters();
	aulookup_destroy_uid_list();
	aulookup_destroy_gid_list();
	free_config(&config); 
	free(user_file);
	return 0;
}
Beispiel #7
0
int main(int argc, char *argv[])
{
	struct rlimit limit;
	int rc;

	/* Check params and build regexpr */
	setlocale (LC_ALL, "");
	if (check_params(argc, argv))
		return 1;

	/* Raise the rlimits in case we're being started from a shell
	* with restrictions. Not a fatal error.  */
	limit.rlim_cur = RLIM_INFINITY;
	limit.rlim_max = RLIM_INFINITY;
	setrlimit(RLIMIT_FSIZE, &limit);
	setrlimit(RLIMIT_CPU, &limit);
	set_aumessage_mode(MSG_STDERR, DBG_NO);
	(void) umask( umask( 077 ) | 027 );
	very_first_event.sec = 0;
	reset_counters();

	print_title();
	lol_create(&lo);
	if (user_file) {
		struct stat sb;
		if (stat(user_file, &sb) == -1) {
			perror("stat");
			return 1;
		} else {
			switch (sb.st_mode & S_IFMT) {
				case S_IFDIR: 
					userfile_is_dir = 1;
					rc = process_logs();
					break;
				case S_IFREG:
				default:
					rc = process_file(user_file);
					break;
			}
		}
	} else if (force_logs)
		rc = process_logs();
	else if (is_pipe(0))
		rc = process_stdin();
	else
		rc = process_logs();
	lol_clear(&lo);
	if (rc)
		return rc;

	if (!found && report_detail == D_DETAILED && report_type != RPT_TIME) {
		printf("<no events of interest were found>\n\n");
		destroy_counters();
		aulookup_destroy_uid_list();
		aulookup_destroy_gid_list();
		return 1;
	} else 
		print_wrap_up();
	destroy_counters();
	aulookup_destroy_uid_list();
	aulookup_destroy_gid_list();
	free(user_file);
	return 0;
}
Beispiel #8
0
int main()
{
	int i, redirect_bool, pipe_bool, fd_rdr;
	char **cmd;
	char **cmmnd;
	char **pipe_command;
	char buf[512];
	int command_bytes;
	int pipe_fd[2];
        temp_environ = environ;

    while (1) {
        char arg[50], mod[50];

        fprintf(stdout, "\nflop: ");
        fflush(stdout);

        // reset pipe and redirect values
        pipe_bool = 0;
        redirect_bool = 0;

        cmd = (char **)malloc(20*sizeof(char *));
		for (i = 0; i < 20; i++) {
			cmd[i] = (char *) malloc(128);
		}

		if ((command_bytes = read(0, buf, 512)) < 0) {
			fprintf(stdout, "There was an issue reading the command, please try again.\n");
			break;
		}

		buf[command_bytes] = '\0';
		if (parse_cmd(buf, cmd)) {
			if (strcmp("exit", cmd[0]) == 0) {
				fprintf(stdout, "Exiting the floppy disk shell... \n");
				return EXIT_SUCCESS;
			}

            pipe_bool = is_pipe(cmd);
			redirect_bool = is_redirection(cmd);

			if (strcmp("path", cmd[0]) == 0) {
				if (cmd[1])
					strcpy(arg,cmd[1]);
				else
					strcpy(arg, "");
				if (cmd[2])
					strcpy(mod,cmd[2]);
				else strcpy(mod, "");
				if ((strchr(arg,'+') == NULL) && (strchr(arg,'-') == NULL)) {
					path();
					continue;
				} else if (!strcmp("+", arg)) {
					if(strchr(mod,'#') == NULL){
						path_add(mod);
						strcpy(arg,"");
						continue;
					} else {
						fprintf(stdout, "Error invalid argument, please try again! \n");
						continue;
					}
				} else if (!strcmp("-", arg)) {
					if(strchr(mod,'#') == NULL){
						path_sub(mod);
						strcpy(arg,"");
						continue;
					} else{
						fprintf(stdout, "Error invalid argument, please try again! \n");
					}
				} else {
					fprintf(stdout, "Error invalid argument, please try again! \n");
				}
			} else if (!strcmp("cd", cmd[0])) {
				change_dir((const char*)cmd[1]);
				continue;
			}
                        

			if (pipe_bool > 0) {
                                // copy command string to not alter original 
				cmmnd = cmd;
                                // iterate over command to find pipe portion
				while (*cmmnd != NULL) {
					if (!strcmp(*cmmnd, "|")) {
						pipe_command = cmmnd + 1;
						*cmmnd = NULL;
						break;
					}
					cmmnd++;
				}
                                // iterate over command string to find redirection portion
				if (redirect_bool > 0) {
					cmmnd = pipe_command;
					while (*cmmnd != NULL) {
						if (!strcmp(*cmmnd, ">")) {
							if ((fd_rdr = open(*(cmmnd+1), (O_WRONLY | O_CREAT | O_TRUNC), 0644)) < 0)
								fprintf(stdout, "There was an error creating file for redirection\n");
							*cmmnd = NULL;
							break;
						}
						cmmnd++;
					}
				}
				if (*pipe_command == NULL || pipe_command[0][0] == '\0') {
					fprintf(stdout, "There was an error in the pipe command\n");
					fflush(stdout);
					continue;
				}
				if ((pipe(pipe_fd)) != 0)
					fprintf(stdout, "There was an error creating the pipe\n");

				if ((fork()) == 0) {
					close(1);
                                        dup(pipe_fd[1]);
                                        close(pipe_fd[1]);
                                        close(pipe_fd[0]);
                                        // execute command 
					execve(cmd[0], cmd, NULL);
                                        // above command was not found so try path_name environment
                                        char* temp = path_name; 
                                        char *token = strtok(temp,":");
                                        while( token != NULL ) {
                                            char envir_arg_pathname[50];
                                            strcpy(envir_arg_pathname, "PATH=");
                                            strcpy(envir_arg_pathname, token);
                                            char *env_args[] = { envir_arg_pathname, NULL, NULL };
                                            environ = env_args;
                                            
                                            if((execvp(cmd[0], &cmd[0])) == -1) {
                                                token = strtok(NULL, ":");
                                            }
                                            else
                                                break;
                                        }
					fprintf(stdout, "There was an invalid command in string\n");
				}
				if ((fork()) == 0) {
					close(0);
                                        dup(pipe_fd[0]);
                                        close(pipe_fd[0]);
                                        close(pipe_fd[1]);
					if (redirect_bool) {
                                            close(1);
                                            dup(fd_rdr);
                                            close(fd_rdr);
                                        }
                                        
                                        // reset environment
                                        environ = temp_environ;
                                        // execute pipe 
					execvp(pipe_command[0], pipe_command);
                                        // above command was not found so try path_name environment
                                        char* temp = path_name; 
                                        char *token = strtok(temp,":");
                                        while( token != NULL ) {
                                            char envir_arg_pathname[50];
                                            strcpy(envir_arg_pathname, "PATH=");
                                            strcpy(envir_arg_pathname, token);
                                            char *env_args[] = { envir_arg_pathname, NULL, NULL };
                                            environ = env_args;
                                            
                                            if((execvp(cmd[0], &cmd[0])) == -1) {
                                                token = strtok(NULL, ":");
                                            }
                                            else
                                                break;
                                        }
					fprintf(stdout, "There was an error in pipe command\n");
				}
				close(pipe_fd[0]);
                                close(pipe_fd[1]);
				wait(NULL);
                                wait(NULL);
			}
			else {
                            // pipe was not found
				if (redirect_bool > 0) {
                                        // copy command to not alter original string
					cmmnd = cmd;
                                        // find redirect file name and create file for writing.
					while (*cmmnd != NULL) {
						if (!strcmp(*cmmnd, ">")) {
							if ((fd_rdr = open(*(cmmnd+1), (O_WRONLY | O_CREAT | O_TRUNC), 0644)) < 0)
								fprintf(stdout, "There was an issue creating redirect file\n");
							*cmmnd = NULL;
							break;
						}
						cmmnd++;
					}
				}
				if ((fork()) == 0) {
					if (redirect_bool) {
						close(1);
                                                dup(fd_rdr);
                                                close(fd_rdr);
					}
					execve(cmd[0], cmd, NULL);
                                        // above command was not found so try path_name environment
                                        char* temp;
					char* token;
					temp = path_name; 
					token = strtok(path_name,":");
					while(token != NULL){
						char *slash = "/";
						path_name = temp;
						//add command to end of each path to search
						strcat(token,slash);
						strcat(token,cmd[0]);
						printf("token : %s",token);
						execl(token,cmd[0],cmd[1],cmd[2],NULL);
						token = strtok(NULL,":");
					}

					fprintf(stdout, "There was an invalid command in command string.\n");
				}
				if (redirect_bool)
					close(fd_rdr);
				wait(NULL);
			}
		}
        free(cmd);
    }

    return 0;
}
Beispiel #9
0
qp_source_t qp_source_create(const char *filename, int value_type)
{
  struct qp_source *source;
  struct qp_reader rd;
  int r;

  source = make_source(filename, value_type);

  rd.fd = -1;
  rd.rd = 0;
  rd.len = 0;
  rd.past = 0;
  rd.file = NULL;
  rd.buf = NULL;
  rd.filename = (char *) filename;
  qp_rd = &rd;

  if(strcmp(filename,"-") == 0)
  {
    rd.file = stdin;
    rd.fd = STDIN_FILENO;
  }

  if(rd.fd == -1)
    rd.fd = open(filename, O_RDONLY);

  if(rd.fd == -1)
  {
    EWARN("open(\"%s\",O_RDONLY) failed\n", filename);
    QP_EWARN("%sFailed to open file%s %s%s%s\n",
        bred, trm, btur, filename, trm);
    goto fail;
  }

  if(!is_pipe(&rd))
  {
    /* don't buffer read() and lseek() */
    qp_rd = NULL;
  }
  else
  {
    /* this is a pipe */
    DEBUG("Virturalizing a pipe%s%s\n",
        (filename[0] == '-' && filename[1] == '\0')?
        "":" with name ",
        (filename[0] == '-' && filename[1] == '\0')?
        "":filename);
    rd.buf = qp_malloc(BUF_LEN);
  }

  if((r = read_sndfile(source, &rd)))
  {
    if(r == -1)
      goto fail;


    if(rd.past && qp_rd)
    {
      VASSERT(0, "libsndfile read to much data "
          "to see that the file was not a sndfile\n");
      QP_WARN("%sFailed to read file%s %s%s%s:"
          " read wrapper failed\n",
          bred, trm, btur, filename, trm);
      goto fail;
    }

    if(qp_rd)
    {
      /* Start reading the data from the qp_rd read() buffer */
      rd.rd = 0;
      /* no need to add more to the qp_rd read() buffer */
      rd.fd = -1;
    }
    /* The above lseek() should work fine. */
    else if(lseek(rd.fd, 0, SEEK_SET))
    {
      EWARN("lseek(fd=%d, 0, SEEK_SET) failed\n", rd.fd);
      QP_EWARN("%sFailed to read file%s %s%s%s: lseek() failed\n",
          bred, trm, btur, filename, trm);
    }

    if(!rd.file)
    {
      errno = 0;
      rd.file = fdopen(rd.fd, "r");
      ASSERT(fileno(rd.file) == rd.fd);
    }
    if(!rd.file)
    {
      EWARN("fopen(\"%s\",\"r\") failed\n", filename);
      QP_EWARN("%sFailed to open file%s %s%s%s\n",
          bred, trm, btur, filename, trm);
      goto fail;
    }

    errno = 0;

    if(read_ascii(source, &rd))
      goto fail;
  }

  if(rd.buf)
  {
    free(rd.buf);
    rd.buf = NULL;
  }

  {
    /* remove any channels that have very bad data */
    struct qp_channel **c;
    size_t i = 0, chan_num = 0;
    ASSERT(source->channels);
    c = source->channels;
    while(c[i])
    {
      ASSERT(c[i]->form == QP_CHANNEL_FORM_SERIES);
      if(!is_good_double(c[i]->series.min) ||
          !is_good_double(c[i]->series.max))
      {
        struct qp_channel **n;
        
        qp_channel_destroy(c[i]);

        /* move of all pointers from c[i+1] back one */
        for(n=&c[i]; *n;++n)
          *n = *(n+1);

        /* re-malloc copying and removing one */
        source->channels = 
          qp_realloc(source->channels, sizeof(struct qp_channel *)*
              ((source->num_channels)--));
        
        /* reset c to the next one which is now at the
         * same index */
        c = source->channels;

        QP_NOTICE("removed bad channel number %zu\n", chan_num);
      }
      else
        ++i;
      ++chan_num;
    }
    ASSERT(source->num_channels == i);
  }
  
  
  if(source->num_channels == 0)
    goto fail;


  if(source->num_channels > 1)
  {
    /****** Check that there is at least one point in all the channels */
    ssize_t i, num;
    double *x;
    num = source->num_values;
    x = qp_malloc(sizeof(double)*source->num_channels);
    for(i=0;i<source->num_channels;++i)
      x[i] = qp_channel_series_double_begin(source->channels[i]);

    while(num)
    {
      int found = 0;
      for(i=0;i<source->num_channels;++i)
        if(is_good_double(x[i]))
          ++found;

      if(found >= 2)
        /* that means there is at least one x/y point
         * in all the channels. */
        break;

      --num;
      if(!num)
        break;

      for(i=0;i<source->num_channels;++i)
        x[i] = qp_channel_series_double_next(source->channels[i]);
    }

    if(!num)
    {
      QP_WARN("Failed to find a good point in data from file \"%s\"\n",
          filename);
      goto fail;
    }
  }

  
  if(source->num_channels == 0)
    goto fail;


  if(app->op_linear_channel || source->num_channels == 1)
  {
    /* Prepend a linear channel */

    /* TODO: Make this use less memory */
    
    struct qp_channel *c, **new_channels;
    double start = 0, step = 1;
    size_t len, i;

    if(app->op_linear_channel)
    {
      c = app->op_linear_channel;
      ASSERT(c->data);
      start = ((double*)c->data)[0];
      step = ((double*)c->data)[1];
    }
    else
    {
      c = qp_channel_linear_create(start, step);
    }


    len = source->num_values;
    for(i=0;i<len;++i)
      qp_channel_series_double_append(c, start + i*step);
   
    /* Prepend the channel to source->channels */
    /* reuse dummy len */
    len = source->num_channels + 1;
    new_channels = qp_malloc(sizeof(c)*len+1);
    new_channels[0] = c;
    for(i=1;i<len;++i)
      new_channels[i] = source->channels[i-1];
    new_channels[i] = NULL;
    free(source->channels);
    source->channels = new_channels;
    ++(source->num_channels);

    if(source->labels && source->num_labels !=  source->num_channels)
    {
      // shift the labels and add the linear channel label
      source->labels = qp_realloc(source->labels,
          sizeof(char *)*(source->num_labels+2));
      source->labels[source->num_labels+1] = NULL;
      for(i=source->num_labels;i>=1;--i)
        source->labels[i] = source->labels[i-1];

      char s[128];
      snprintf(s,128, "%s[0]", source->name);
      // The first channel is the linear channel.
      source->labels[0] = qp_strdup(s);
      ++source->num_labels;
    }

    /* Another source may have more values so
     * we must make a new one in case it is used again. */
    if(app->op_linear_channel)
      app->op_linear_channel = qp_channel_linear_create(start, step);
  }
  
  add_source_buffer_remove_menus(source);
  
  {
    char skip[64];
    skip[0] = '\0';
    if(app->op_skip_lines)
      snprintf(skip, 64, "(after skipping %zu) ", app->op_skip_lines);


    INFO("created source with %zu sets of values %s"
      "in %zu channels from file %s\n",
      source->num_values, skip, source->num_channels,
      filename);

    QP_INFO("created source with %zu sets of "
      "values %sin %zu channels from file \"%s\"\n",
      source->num_values, skip, source->num_channels,
      filename);
#if QP_DEBUG
    if(source->labels)
    {
      char **labels;
      APPEND("Read labels:");
      for(labels = source->labels; *labels; ++labels)
        APPEND(" \"%s\"", *labels);
      APPEND("\n");
    }
#endif
  }

  qp_rd = NULL;

  if(strcmp(filename,"-") == 0)
    /* We do not close stdin */
    return source;

  if(rd.file)
    fclose(rd.file);
  else if(rd.fd != -1)
    close(rd.fd);

  qp_app_graph_detail_source_remake();
  qp_app_set_window_titles();

  return source;

fail:

  QP_WARN("No data loaded from file \"%s\"\n",
      filename);

  if(rd.buf)
    free(rd.buf);

  if(strcmp(filename,"-") != 0)
  {
    if(rd.file)
      fclose(rd.file);
    else if(rd.fd != -1)
      close(rd.fd);
  }

  if(source)
    qp_source_destroy(source);

  qp_rd = NULL;

  return NULL;
}
Beispiel #10
0
bool		is_redir_or_sep(char *s)
{
	if (is_left_redir(s) || is_right_redir(s) || is_sep(s) || is_pipe(s))
		return (TRUE);
	return (FALSE);
}
Beispiel #11
0
bool		is_redir(char *str)
{
	if (is_left_redir(str) || is_right_redir(str) || is_pipe(str))
		return (TRUE);
	return (FALSE);
}
Beispiel #12
0
/**************************
 * command* create_parse_tree_recursive(
 *      struct tokenized_node*,
 *
 * Input:
 *  tokenized_command   - Token node to start at
 *  
 * Given a tokenized command, create a parse tree out of it.
 */
command* create_parse_tree_recursive(struct tokenized_node* tokenized_command)
{

    // Used so we don't have to special-case first node in the tree
    command fake_start_node;
    fake_start_node.piped_to = NULL;
    command* current_command = &fake_start_node;
    bool in_command = false;

    commanditem fake_start_item;
    fake_start_item.next = NULL;
    commanditem* current_command_item = &fake_start_item;

    struct tokenized_node* token_iterator = tokenized_command;

    for (iterator(token_iterator, tokenized_command))
    {

        if (!in_command)
        {
            current_command->piped_to = create_command();
            current_command = current_command->piped_to;

            in_command = true;
        }

        if (is_pipe(token_iterator))
        {
            in_command = false;

            current_command->contents = fake_start_item.next;
            current_command_item = &fake_start_item;

            continue;
        }

        if (is_backtick(token_iterator))
        {
            perror("You're f****d.\n");
            exit(1);
        }

        // Input redirect
        if ('<' == *(token_iterator->contents))
        {
            token_iterator = token_iterator->next;
            
            current_command->input
                = malloc(sizeof(char) * (strlen(token_iterator->contents) + 1));
            strcpy(current_command->input, token_iterator->contents);

            continue;
        }

        // Output redirect
        if ('>' == *(token_iterator->contents))
        {
            token_iterator = token_iterator->next;
            
            if (token_iterator && '>' == *(token_iterator->contents))
            {
                current_command->output_append = true;
                token_iterator = token_iterator->next;
            }

            current_command->output
                = malloc(sizeof(char) * (strlen(token_iterator->contents) + 1));
            strcpy(current_command->output, token_iterator->contents);

            continue;

        }

        // Background
        if ('&' == *(token_iterator->contents))
        {
            in_command = false;

            current_command->background = true;
            current_command->contents = fake_start_item.next;
            current_command_item = &fake_start_item;

            continue;
        }

        commanditem* newitem = create_commanditem(ARGUMENT);

        newitem->contents
            = malloc(sizeof(char) * (strlen(token_iterator->contents) + 1));
        strcpy(newitem->contents, token_iterator->contents);

        current_command_item->next = newitem;
        current_command_item = current_command_item->next;

    }
 
    // Make sure last command has contents.
    current_command->contents = fake_start_item.next;

    return fake_start_node.piped_to;

}