Пример #1
0
/* Executes a set of commands that are piped together.
 * If it's a single command, it simply calls `exec_command`.
 */
int exec_commands(struct commands *cmds)
{
	int exec_ret;

	/* single command? run it */
	if (cmds->cmd_count == 1) {
		cmds->cmds[0]->fds[STDIN_FILENO] = STDIN_FILENO;
		cmds->cmds[0]->fds[STDOUT_FILENO] = STDOUT_FILENO;
		exec_ret = exec(cmds, cmds->cmds[0], NULL);
		wait(NULL);
	} else {
		/* execute a pipeline */
		int pipe_count = cmds->cmd_count - 1;

		/* if any command in the pipeline is a built-in, raise error */
		int i;

		for (i = 0; i < cmds->cmd_count; i++) {
			if (check_built_in(cmds->cmds[i])) {
				fprintf(stderr, "error: no builtins in pipe\n");
				return 0;
			}

		}

		/* allocate an array of pipes. Each member is array[2] */
		int (*pipes)[2] = calloc(pipe_count * sizeof(int[2]), 1);

		if (pipes == NULL) {
			fprintf(stderr, "error: memory alloc error\n");
			return 0;
		}


		/* create pipes and set file descriptors on commands */
		cmds->cmds[0]->fds[STDIN_FILENO] = STDIN_FILENO;
		for (i = 1; i < cmds->cmd_count; i++) {
			pipe(pipes[i-1]);
			cmds->cmds[i-1]->fds[STDOUT_FILENO] = pipes[i-1][1];
			cmds->cmds[i]->fds[STDIN_FILENO] = pipes[i-1][0];
		}
		cmds->cmds[pipe_count]->fds[STDOUT_FILENO] = STDOUT_FILENO;

		/* execute the commands */
		for (i = 0; i < cmds->cmd_count; i++)
			exec_ret = exec(cmds, cmds->cmds[i], pipes);

		close_pipes(pipes, pipe_count);

		/* wait for children to finish */
		for (i = 0; i < cmds->cmd_count; ++i)
			wait(NULL);

		free(pipes);
	}

	return exec_ret;
}
Пример #2
0
int exec(struct commands *cmds, struct command *cmd, int (*pipes)[2])
{
	if (check_built_in(cmd) == 1)
		return handle_built_in(cmds, cmd);

	pid_t child_pid = fork();

	if (child_pid == -1) {
		fprintf(stderr, "error: fork error\n");
		return 0;
	}

	/* in the child */
	if (child_pid == 0) {

		int input_fd = cmd->fds[0];
		int output_fd = cmd->fds[1];

		// change input/output file descriptors if they aren't standard
		if (input_fd != -1 && input_fd != STDIN_FILENO)
			dup2(input_fd, STDIN_FILENO);

		if (output_fd != -1 && output_fd != STDOUT_FILENO)
			dup2(output_fd, STDOUT_FILENO);

		if (pipes != NULL) {
			int pipe_count = cmds->cmd_count - 1;

			close_pipes(pipes, pipe_count);
		}

		/* execute the command */
		execv(cmd->name, cmd->argv);

		/* execv returns only if an error occurs */
		fprintf(stderr, "error: %s\n", strerror(errno));

		/* cleanup in the child to avoid memory leaks */
		clear();
		free(history);
		free(pipes);
		free(input);
		cleanup_commands(cmds);

		if (parent_cmd != NULL) {
			free(parent_cmd);
			free(temp_line);
			free(parent_cmds);
		}


		/* exit from child so that the parent can handle the scenario*/
		_exit(EXIT_FAILURE);
	}
	/* parent continues here */
	return child_pid;
}
Пример #3
0
void			execute_son(int fd_in, int fd_out, t_list_p *item, char **envp)
{
	st_exec_test(fd_in, fd_out);
	if (item->in)
		process_redir_r(item, envp);
	else if (item->out)
		process_redir_w(item, envp);
	else if (item->app)
		process_redir_a(item, envp);
	if (!is_built_in(item->str))
		process_command(item->str, envp);
	else if (ft_is_env_i(item->str) > 0)
		process_command((item->str + ft_is_env_i(item->str)), NULL);
	else
		check_built_in(item->str);
	exit(0);
}
Пример #4
0
int main(int argc, char *argv[]) {
	
	//Checks that only ./whoosh is entered to invoke shell
	if(argc != 1) {
		error_msg();
		exit(1);
	}
	
	int CHAR_LIMIT = 129;
	int BUFFER_LIMIT = 1024;
	char buffer[BUFFER_LIMIT];
	
	int path_num = 1;
	char* s_path[BUFFER_LIMIT];
	s_path[0] = "/bin";
	
	while(1) {
		printf("whoosh> ");
		fflush(stdout);		
		fgets(buffer, sizeof(buffer), stdin);
		
		get_line(buffer);
		
		int line_size = strlen(buffer);
		
		if(line_size > CHAR_LIMIT) {
			error_msg();
			continue;
		}
		
		//Get num of args in command 
		int num_args = count_args(buffer);
		
		if(num_args != 0) {
			
			char* myargv[num_args + 1];
			int r_count = 0;
			int last_r = 0;
			char* r_path = NULL;
			int i;
			char buf[PATH_MAX + 1];
			char *cwd;
			char *r_output;
			
			//Put each argument in myargv array
			get_args(buffer, myargv, num_args);
			
			//Check for redirect
			check_redirect(myargv, num_args, &r_count, &last_r);
		
			//Redirect error handling
			if(r_count > 1) {
				error_msg();
				continue;
			}
			else if (r_count == 1) {
				if(last_r != num_args - 2) {
					error_msg();
					continue;
				}
				if(myargv[num_args - 1][0] == '/') {
					if(chdir(myargv[num_args - 1]) == 0) {
						r_path = strdup(myargv[num_args - 1]);
					}
					else {
						error_msg();
						continue;
					}
				}
				
				r_output = malloc(strlen(myargv[num_args - 1]) + strlen(".out"));
				sprintf(r_output, "%s", myargv[num_args - 1]);	
				//Take off > and path from arguments
				num_args = num_args - 2;
			}
			
			//Set last element in myargv array to NULL
			myargv[num_args] = NULL;
	
			//Check if exit was entered
			check_exit(myargv);
			
			//Check if any built-in commands were called
			if(check_built_in(myargv, num_args, s_path, &path_num) == 0) {
				continue;
			}
			else{
				int file_exist = 0;
				
				cwd = getcwd(buf, PATH_MAX + 1);
				for(i=0; i<path_num; i++) {
					chdir(s_path[i]);
					struct stat path_buff;
					if(stat(myargv[0], &path_buff) == 0) {
						file_exist = 1;
						char *exec_path = malloc(strlen(s_path[i]) + strlen("/") + strlen(myargv[0]) + 1);
						sprintf(exec_path, "%s/%s", s_path[i], myargv[i]);
						myargv[0] = exec_path;
						chdir(cwd);
						break;
					}
				}	
				if(file_exist == 0) {
					error_msg();
					continue;
				}
				else {
					exec_cmd(myargv, r_output, r_path, r_count);
				}
			}
		}	
	}
}