fcntl for saving fds, new option to distinguish interactive shell or not
This commit is contained in:
parent
a99ef894e7
commit
5a033a8789
18 changed files with 51 additions and 66 deletions
|
|
@ -54,7 +54,6 @@ completion/c_terminal.c\
|
||||||
completion/completion.c\
|
completion/completion.c\
|
||||||
exec/ast_free.c\
|
exec/ast_free.c\
|
||||||
exec/bad_fd.c\
|
exec/bad_fd.c\
|
||||||
exec/close_fdsave.c\
|
|
||||||
exec/exec_ampersand.c\
|
exec/exec_ampersand.c\
|
||||||
exec/exec_and_if.c\
|
exec/exec_and_if.c\
|
||||||
exec/exec_command.c\
|
exec/exec_command.c\
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,6 @@ void process_setsig(void);
|
||||||
void process_free(void *content, size_t content_size);
|
void process_free(void *content, size_t content_size);
|
||||||
void process_reset(t_process *p);
|
void process_reset(t_process *p);
|
||||||
void process_resetfds(void);
|
void process_resetfds(void);
|
||||||
void close_fdsave(void);
|
|
||||||
|
|
||||||
int fd_is_valid(int fd);
|
int fd_is_valid(int fd);
|
||||||
int bad_fd(int fd);
|
int bad_fd(int fd);
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,17 @@
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
|
||||||
# define SHELL_OPTS_JOBC (1 << 0)
|
# define SH_INTERACTIVE (1 << 0)
|
||||||
# define SHELL_OPTS_LC (1 << 1)
|
# define SH_OPTS_JOBC (1 << 1)
|
||||||
# define SHELL_MODE_INPUT (1 << 2)
|
# define SH_OPTS_LC (1 << 2)
|
||||||
# define SHELL_MODE_EXEC (1 << 3)
|
# define SH_MODE_INPUT (1 << 3)
|
||||||
|
# define SH_MODE_EXEC (1 << 4)
|
||||||
|
|
||||||
# define SHELL_MODE_MASK (SHELL_MODE_INPUT | SHELL_MODE_EXEC)
|
# define SH_MODE_MASK (SH_MODE_INPUT | SH_MODE_EXEC)
|
||||||
# define SHELL_HAS_JOBC(b) (b & SHELL_OPTS_JOBC)
|
# define SH_HAS_JOBC(b) (b & SH_OPTS_JOBC)
|
||||||
|
# define SH_IS_INTERACTIVE(b) (b & SH_INTERACTIVE)
|
||||||
|
|
||||||
# define SHELL_MSG_NOJOBC "no job-control"
|
# define SH_MSG_NOJOBC "no job-control"
|
||||||
|
|
||||||
struct s_data
|
struct s_data
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit d79c38104bbd45018d03a11d0c60cd6616e77ed8
|
Subproject commit b53fcb9db8b4baf53c73b17726f1740c4af12be0
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* close_fdsave.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2017/02/07 17:45:23 by jhalford #+# #+# */
|
|
||||||
/* Updated: 2017/02/07 17:54:07 by jhalford ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "exec.h"
|
|
||||||
|
|
||||||
void close_fdsave(void)
|
|
||||||
{
|
|
||||||
t_exec *exec;
|
|
||||||
|
|
||||||
exec = &data_singleton()->exec;
|
|
||||||
close(exec->fd0save);
|
|
||||||
close(exec->fd1save);
|
|
||||||
close(exec->fd2save);
|
|
||||||
}
|
|
||||||
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
int exec_ampersand(t_btree **ast)
|
int exec_ampersand(t_btree **ast)
|
||||||
{
|
{
|
||||||
if (SHELL_HAS_JOBC(data_singleton()->opts))
|
if (SH_HAS_JOBC(data_singleton()->opts))
|
||||||
data_singleton()->exec.job.attributes |= JOB_BG;
|
data_singleton()->exec.job.attributes |= JOB_BG;
|
||||||
ft_exec(&(*ast)->left);
|
ft_exec(&(*ast)->left);
|
||||||
if (SHELL_HAS_JOBC(data_singleton()->opts))
|
if (SH_HAS_JOBC(data_singleton()->opts))
|
||||||
data_singleton()->exec.job.attributes &= ~JOB_BG;
|
data_singleton()->exec.job.attributes &= ~JOB_BG;
|
||||||
ft_exec(&(*ast)->right);
|
ft_exec(&(*ast)->right);
|
||||||
btree_delone(ast, &ast_free);
|
btree_delone(ast, &ast_free);
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ int launch_process(t_process *p)
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
close_fdsave();
|
|
||||||
process_setgroup(p, 0);
|
process_setgroup(p, 0);
|
||||||
process_setsig();
|
process_setsig();
|
||||||
if (process_redirect(p))
|
if (process_redirect(p))
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@
|
||||||
int process_setgroup(t_process *p, pid_t pid)
|
int process_setgroup(t_process *p, pid_t pid)
|
||||||
{
|
{
|
||||||
t_job *j;
|
t_job *j;
|
||||||
|
t_data *data;
|
||||||
|
|
||||||
(void)p;
|
(void)p;
|
||||||
if (!SHELL_HAS_JOBC(data_singleton()->opts))
|
data = data_singleton();
|
||||||
|
if (!SH_HAS_JOBC(data->opts))
|
||||||
return (0);
|
return (0);
|
||||||
j = &data_singleton()->exec.job;
|
j = &data->exec.job;
|
||||||
if (!j->pgid)
|
if (!j->pgid)
|
||||||
j->pgid = pid ? pid : getpid();
|
j->pgid = pid ? pid : getpid();
|
||||||
setpgid(pid, j->pgid);
|
setpgid(pid, j->pgid);
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ int builtin_bg(const char *path, char *const av[], char *const envp[])
|
||||||
|
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)envp;
|
(void)envp;
|
||||||
if (!SHELL_HAS_JOBC(data_singleton()->opts))
|
if (!SH_HAS_JOBC(data_singleton()->opts))
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "{red}bg: %s{eoc}\n", SHELL_MSG_NOJOBC);
|
ft_dprintf(2, "{red}bg: %s{eoc}\n", SH_MSG_NOJOBC);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ int builtin_fg(const char *path, char *const av[], char *const envp[])
|
||||||
|
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)envp;
|
(void)envp;
|
||||||
if (!SHELL_HAS_JOBC(data_singleton()->opts))
|
if (!SH_HAS_JOBC(data_singleton()->opts))
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "{red}fg: %s{eoc}\n", SHELL_MSG_NOJOBC);
|
ft_dprintf(2, "{red}fg: %s{eoc}\n", SH_MSG_NOJOBC);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,9 @@ int builtin_jobs(const char *path, char *const av[], char *const envp[])
|
||||||
|
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)envp;
|
(void)envp;
|
||||||
if (!SHELL_HAS_JOBC(data_singleton()->opts))
|
if (!SH_HAS_JOBC(data_singleton()->opts))
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "{red}jobs: %s{eoc}\n", SHELL_MSG_NOJOBC);
|
ft_dprintf(2, "{red}jobs: %s{eoc}\n", SH_MSG_NOJOBC);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if ((opts = bt_jobs_parse((char**)av, &i)) < 0)
|
if ((opts = bt_jobs_parse((char**)av, &i)) < 0)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ int job_wait(int id)
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
DG("gonna wait [%i]", id);
|
||||||
if (job_is_stopped(id))
|
if (job_is_stopped(id))
|
||||||
return (0);
|
return (0);
|
||||||
job_update_status();
|
job_update_status();
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,6 @@ void sigtstp_handler(int signo)
|
||||||
|
|
||||||
(void)signo;
|
(void)signo;
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
DG("got SIGTSTP in process %i", getpid());
|
DG("got SIGTSTP pid=%i, pgrp=%i, shell_pgid=%i", getpid(), getpgrp(), data_singleton()->jobc.shell_pgid);
|
||||||
|
ft_putchar('\x1A');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,24 +16,24 @@ extern char **environ;
|
||||||
|
|
||||||
int data_init(void)
|
int data_init(void)
|
||||||
{
|
{
|
||||||
char *term_name;
|
|
||||||
t_data *data;
|
t_data *data;
|
||||||
|
|
||||||
data = data_singleton();
|
data = data_singleton();
|
||||||
data->env = ft_sstrdup(environ);
|
data->env = ft_sstrdup(environ);
|
||||||
data->comp = NULL;
|
data->comp = NULL;
|
||||||
data->opts = SHELL_OPTS_JOBC;
|
data->opts = SH_OPTS_JOBC;
|
||||||
|
|
||||||
data->exec.process.path = NULL;
|
data->exec.process.path = NULL;
|
||||||
data->exec.process.av = NULL;
|
data->exec.process.av = NULL;
|
||||||
|
data->exec.process.toclose = STDIN;
|
||||||
data->exec.process.fdin = STDIN;
|
data->exec.process.fdin = STDIN;
|
||||||
data->exec.process.fdout = STDOUT;
|
data->exec.process.fdout = STDOUT;
|
||||||
data->exec.process.pid = 0;
|
data->exec.process.pid = 0;
|
||||||
data->exec.process.attributes = PROCESS_PIPESTART | PROCESS_PIPEEND;
|
data->exec.process.attributes = PROCESS_PIPESTART | PROCESS_PIPEEND;
|
||||||
data->exec.process.redirs = NULL;
|
data->exec.process.redirs = NULL;
|
||||||
data->exec.fd0save = dup(0);
|
data->exec.fd0save = fcntl(0, F_DUPFD_CLOEXEC);
|
||||||
data->exec.fd1save = dup(1);
|
data->exec.fd1save = fcntl(1, F_DUPFD_CLOEXEC);
|
||||||
data->exec.fd2save = dup(2);
|
data->exec.fd2save = fcntl(2, F_DUPFD_CLOEXEC);
|
||||||
|
|
||||||
data->exec.aol_status = NULL;
|
data->exec.aol_status = NULL;
|
||||||
data->exec.aol_search = 0;
|
data->exec.aol_search = 0;
|
||||||
|
|
@ -41,11 +41,8 @@ int data_init(void)
|
||||||
data->exec.job.pgid = 0;
|
data->exec.job.pgid = 0;
|
||||||
data->exec.job.attributes = 0;
|
data->exec.job.attributes = 0;
|
||||||
data->exec.job.first_process = 0;
|
data->exec.job.first_process = 0;
|
||||||
|
|
||||||
data->jobc.first_job = NULL;
|
data->jobc.first_job = NULL;
|
||||||
data->jobc.current_id = 1;
|
data->jobc.current_id = 1;
|
||||||
if ((term_name = ft_getenv(data->env, "TERM")) == NULL)
|
|
||||||
return (-1);
|
|
||||||
if (tgetent(NULL, term_name) != 1)
|
|
||||||
return (-1);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,14 @@ int shell_single_command(char *command)
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
|
t_data *data;
|
||||||
|
|
||||||
|
data = data_singleton();
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
DG("{inv}{bol}{gre}start of shell{eoc} pid=%i pgrp=%i job_control is %s", getpid(), getpgrp(), SH_HAS_JOBC(data->opts) ? "ON" : "OFF");
|
||||||
shell_init(ac, av);
|
shell_init(ac, av);
|
||||||
DG("{inv}{bol}{gre}start of shell{eoc} job_control is %s", data_singleton()->opts & SHELL_OPTS_JOBC ? "ON" : "OFF");
|
DG("{inv}{bol}{gre}start of shell{eoc} pid=%i pgrp=%i job_control is %s", getpid(), getpgrp(), SH_HAS_JOBC(data->opts) ? "ON" : "OFF");
|
||||||
if (data_singleton()->opts & SHELL_OPTS_LC)
|
if (data_singleton()->opts & SH_OPTS_LC)
|
||||||
{
|
{
|
||||||
shell_single_command(ft_strdup(shell_get_avdata()));
|
shell_single_command(ft_strdup(shell_get_avdata()));
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
static void shell_parse_long_opt(char *str)
|
static void shell_parse_long_opt(char *str)
|
||||||
{
|
{
|
||||||
if (ft_strcmp("no-jobcontrol", str) == 0)
|
if (ft_strcmp("no-jobcontrol", str) == 0)
|
||||||
data_singleton()->opts &= ~SHELL_OPTS_JOBC;
|
data_singleton()->opts &= ~SH_OPTS_JOBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shell_parse_short_opt(char *str)
|
static void shell_parse_short_opt(char *str)
|
||||||
|
|
@ -27,8 +27,8 @@ static void shell_parse_short_opt(char *str)
|
||||||
{
|
{
|
||||||
if (*str == 'c')
|
if (*str == 'c')
|
||||||
{
|
{
|
||||||
data_singleton()->opts |= SHELL_OPTS_LC;
|
data_singleton()->opts |= SH_OPTS_LC;
|
||||||
data_singleton()->opts &= ~SHELL_OPTS_JOBC;
|
data_singleton()->opts &= ~SH_OPTS_JOBC;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +39,8 @@ void shell_get_opts(int ac, char **av)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
|
if (isatty(STDIN))
|
||||||
|
data_singleton()->opts |= SH_INTERACTIVE;
|
||||||
while (i < ac && av[i][0] == '-')
|
while (i < ac && av[i][0] == '-')
|
||||||
{
|
{
|
||||||
if (ft_strcmp(av[i], "--") == 0)
|
if (ft_strcmp(av[i], "--") == 0)
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,18 @@
|
||||||
void shell_init(int ac, char **av)
|
void shell_init(int ac, char **av)
|
||||||
{
|
{
|
||||||
int *shell_pgid;
|
int *shell_pgid;
|
||||||
|
t_data *data;
|
||||||
|
|
||||||
data_init();
|
data_init();
|
||||||
data_singleton()->argc = ac;
|
data = data_singleton();
|
||||||
data_singleton()->argv = ft_sstrdup(av);
|
data->argc = ac;
|
||||||
|
data->argv = ft_sstrdup(av);
|
||||||
atexit(&shell_exit);
|
atexit(&shell_exit);
|
||||||
if (isatty(STDIN))
|
shell_get_opts(ac, av);
|
||||||
|
if (SH_IS_INTERACTIVE(data->opts))
|
||||||
{
|
{
|
||||||
shell_pgid = &data_singleton()->jobc.shell_pgid;
|
DG("interactive shell settings");
|
||||||
|
shell_pgid = &data->jobc.shell_pgid;
|
||||||
while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp()))
|
while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp()))
|
||||||
kill(-*shell_pgid, SIGTTIN);
|
kill(-*shell_pgid, SIGTTIN);
|
||||||
signal(SIGINT, sigint_handler);
|
signal(SIGINT, sigint_handler);
|
||||||
|
|
@ -38,7 +42,6 @@ void shell_init(int ac, char **av)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
tcsetpgrp(STDIN, *shell_pgid);
|
tcsetpgrp(STDIN, *shell_pgid);
|
||||||
tcgetattr(STDIN, &data_singleton()->jobc.shell_tmodes);
|
tcgetattr(STDIN, &data->jobc.shell_tmodes);
|
||||||
}
|
}
|
||||||
shell_get_opts(ac, av);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ int parse_subshell(t_btree **ast, t_list **start, t_list **lst)
|
||||||
|
|
||||||
(void)start;
|
(void)start;
|
||||||
token = (*lst)->content;
|
token = (*lst)->content;
|
||||||
DG("parsing subshell");
|
|
||||||
if ((*lst)->next && ((t_token*)(*lst)->next->content)->type & TK_WORD)
|
if ((*lst)->next && ((t_token*)(*lst)->next->content)->type & TK_WORD)
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "{red}%s: parse error near ')'{eoc}\n", SHELL_NAME);
|
ft_dprintf(2, "{red}%s: parse error near ')'{eoc}\n", SHELL_NAME);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue