~emersion/mrsh

a96a1547d868ed029d9e651b73954074f1662cd9 — emersion 3 years ago 0cdf0b5
Add some redirections
1 files changed, 45 insertions(+), 1 deletions(-)

M shell.c
M shell.c => shell.c +45 -1
@@ 1,8 1,9 @@
#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <errno.h>
#include <mrsh/shell.h>
#include <fcntl.h>
#include <mrsh/builtin.h>
#include <mrsh/shell.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


@@ 21,6 22,7 @@ static int run_simple_command(struct mrsh_state *state,
	memcpy(argv + 1, sc->arguments.data, sc->arguments.len * sizeof(void *));
	argv[argc] = NULL;

	// TODO: redirections for builtins
	int ret = mrsh_builtin(state, argc, argv);
	if (ret != -1) {
		return ret;


@@ 35,6 37,48 @@ static int run_simple_command(struct mrsh_state *state,
			setenv(assign->name, assign->value, true);
		}

		for (size_t i = 0; i < sc->io_redirects.len; ++i) {
			struct mrsh_io_redirect *redir = sc->io_redirects.data[i];

			// TODO: filename expansions
			int fd, default_redir_fd;
			errno = 0;
			if (strcmp(redir->op, "<") == 0) {
				fd = open(redir->filename, O_RDONLY);
				default_redir_fd = STDIN_FILENO;
			} else if (strcmp(redir->op, ">") == 0 ||
					strcmp(redir->op, ">|") == 0) {
				fd = open(redir->filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
				default_redir_fd = STDOUT_FILENO;
			} else if (strcmp(redir->op, ">>") == 0) {
				fd = open(redir->filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
				default_redir_fd = STDOUT_FILENO;
			} else if (strcmp(redir->op, "<>") == 0) {
				fd = open(redir->filename, O_RDWR | O_CREAT, 0644);
				default_redir_fd = STDIN_FILENO;
			} else {
				assert(false); // TODO
			}
			if (fd < 0) {
				fprintf(stderr, "cannot open %s: %s\n", redir->filename,
					strerror(errno));
				exit(EXIT_FAILURE);
			}

			int redir_fd = redir->io_number;
			if (redir_fd < 0) {
				redir_fd = default_redir_fd;
			}

			errno = 0;
			int ret = dup2(fd, redir_fd);
			if (ret < 0) {
				fprintf(stderr, "cannot duplicate file descriptor: %s\n",
					strerror(errno));
				exit(EXIT_FAILURE);
			}
		}

		errno = 0;
		execvp(sc->name, argv);