fcntl for saving fds, new option to distinguish interactive shell or not

This commit is contained in:
Jack Halford 2017-02-08 22:47:12 +01:00
parent a99ef894e7
commit 5a033a8789
18 changed files with 51 additions and 66 deletions

View file

@ -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\

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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))

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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();

View file

@ -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');
} }

View file

@ -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);
} }

View file

@ -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);

View file

@ -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)

View file

@ -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);
} }

View file

@ -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);