Пример #1
0
int execute_builtin(cmd_t* cmd, job_list_t* jobs, history_t* hist) {
  // List jobs.
  if (strcmp(cmd->args[0], "jobs") == 0) {
    add_to_history(hist, cmd);
    return builtin_jobs(jobs);
  }

  // List history.
  if (strcmp(cmd->args[0], "history") == 0) {
    int exit_code = builtin_history(hist);
    add_to_history(hist, cmd);
    return exit_code;
  }

  // Exit.
  if (strcmp(cmd->args[0], "exit") == 0) {
    return builtin_exit();
  }

  // Change directory.
  if (strcmp(cmd->args[0], "cd") == 0) {
    int exit_code = builtin_cd(cmd);
    if (exit_code == 0) {
      add_to_history(hist, cmd);
    }
    return exit_code;
  }

  // Print working directory.
  if (strcmp(cmd->args[0], "pwd") == 0) {
    add_to_history(hist, cmd);
    return builtin_pwd();
  }

  // Bring to foreground.
  if (strcmp(cmd->args[0], "fg") == 0) {
    int exit_code = builtin_fg(cmd, jobs);
    if (exit_code == 0) {
      add_to_history(hist, cmd);
    }
    return exit_code;
  }

  // Execute from history.
  char* endptr = NULL;
  long num = strtol(cmd->args[0], &endptr, 10);
  if (*endptr == '\0' && !(num == 0 && errno == EINVAL)) {
    // Do not save to history to avoid confusion.
    int exit_code = builtin_exec_from_history(cmd, jobs, hist);
    freecmd(cmd);
    return exit_code;
  }

  // Command not found.
  return COMMAND_NOT_FOUND;
}
Пример #2
0
TEST builtin_cd_dotdot(void) {
  char *argv[] = {"cd", ".."};
  int argc = sizeof(argv) / sizeof(argv[0]);
  char *old_path = getcwd(NULL, 0);
  int cd_exit_status = builtin_cd(-1, -1, argc, argv);
  char *new_path = getcwd(NULL, 0);
  ASSERT_EQ(0, cd_exit_status);
  ASSERT(strcmp(old_path, new_path) > 0);
  free(old_path);
  free(new_path);
  PASS();
}
Пример #3
0
TEST builtin_cd_permission_denied(void) {
  char *argv[] = {"cd", "/root"};
  int argc = sizeof(argv) / sizeof(argv[0]);
  char *old_path = getcwd(NULL, 0);
  int cd_exit_status = builtin_cd(-1, -1, argc, argv);
  char *new_path = getcwd(NULL, 0);
  ASSERT_EQ(1, cd_exit_status);
  ASSERT_STR_EQ(old_path, new_path);
  free(old_path);
  free(new_path);
  PASS();
}
Пример #4
0
TEST builtin_cd_no_such_directory(void) {
  char *argv[] = {"cd", "non_existing_direcotry"};
  int argc = sizeof(argv) / sizeof(argv[0]);
  char *old_path = getcwd(NULL, 0);
  int cd_exit_status = builtin_cd(-1, -1, argc, argv);
  char *new_path = getcwd(NULL, 0);
  ASSERT_EQ(1, cd_exit_status);
  ASSERT_STR_EQ(old_path, new_path);
  free(old_path);
  free(new_path);
  PASS();
}
Пример #5
0
void
script_process(char* script)
{
	// Split script in independent pipelines
	char* array[10];
	int numPipelines = gettokens(script, array, 10, ";");

	// run script commands
	int i;
	for(i = 0; i < numPipelines; ++i)
	{
		// expand environment variables and substitute command line char pointer
		// with the one with expanded environment variables (if necesary)
//		char* expanded = expand_envVars(array[i]);
//		if(expanded) array[i] = expanded;
		array[i] = environment_expand(array[i]);

		// move commands to background (if necesary)
		background(array[i]);

		// Exec `cd` (it's a built-in, but must change shell environment itself,
		// so we check and exec for it directly here)
		if(builtin_cd(array[i]))
		{
			free(array[i]);
			continue;
		}

		// Set environment variable
		if(environment_set(array[i]))
		{
			free(array[i]);
			continue;
		}

		// run foreground command
		pipeline_process(array[i]);

		// free line created by environment variables expansion
		free(array[i]);
	}
}
Пример #6
0
/**
 * Command node: fork synchronously and call exec
 */
static int do_command(CommandNode *node)
{
  pid_t child;

  if (strcmp(node->command, "cd") == 0)
    return builtin_cd(node->arguments);

  if (((child = fork())) == 0)
  {
    /* child process */
    setup_redirections(node);
    replace_process(node->command, node->arguments);
    /* noreturn */
  }
  else
  {
    /* parent process */
    return check_wait(child);
  }
  return 1;
}
Пример #7
0
void execute(struct parsed_line *p)
{
    int status;
    extern void execute_one_subcommand(struct parsed_line *p);

    for (; p; p = p->next) {
	if (p->conntype == CONN_OR && laststatus == 0) {
	    /* last command succeeded, so don't do this one */
	} else if (p->conntype == CONN_AND && laststatus) {
	    /* last command failed, so don't do this one */
	} else {
	    /*
	     * "exit" and "cd" are handled specially to avoid the fork().
	     * Ideally the check should be later to make i/o redirection and
	     * piping work, but we'd have to fudge the forking that way.
	     */
	    if (p->pl && strcmp(p->pl->argv[0], "exit") == 0) {
		laststatus = builtin_exit(p->pl->argv);
	    } else if (p->pl && strcmp(p->pl->argv[0], "cd") == 0) {
		laststatus = builtin_cd(p->pl->argv);
	    } else {
		fflush(stdout);
		switch (fork()) {
		case -1:
		    perror("fork");
		    laststatus = 127;
		    break;
		case 0:
		    /* child */
		    execute_one_subcommand(p);
		    break;
		default:
		    /* parent */
		    wait(&status);
		    laststatus = status >> 8;
		}
	    }
	}
    }
}