void proc_launch(t_sh *sh, t_job *j, t_proc *p) { p->pid = getpid(); if (sh->is_interactive == 1) { if (j->pgid == 0) j->pgid = p->pid; if (setpgid(p->pid, j->pgid) == -1) { //log_fatal("setpgid(%d, %d) error: %s", p->pid, j->pgid, strerror(errno)); //exit(EXIT_FAILURE); } if (tcsetpgrp(sh->fd, j->pgid) == -1) { } if (signal_to_default() != ST_OK) { log_fatal("signal_to_default error (pid: %d)", p->pid); exit(EXIT_FAILURE); } } if (p->stdin != STDIN_FILENO) { dup2(p->stdin, STDIN_FILENO); close(p->stdin); } if (p->stdout != STDOUT_FILENO) { dup2(p->stdout, STDOUT_FILENO); close(p->stdout); } if (p->stderr != STDERR_FILENO) { dup2(p->stderr, STDERR_FILENO); close(p->stderr); } builtin_callback(BLTIN_CB_EXEC, sh, p); execvp(p->argv[0], p->argv); // Use execve instead // show error exit(EXIT_FAILURE); }
static void wait_for_job(t_config *conf, t_job *job) { int status; update_last_use(conf->head_job, job); if (kill(job->pgid, SIGCONT) < 0) my_puterr("Error: kill (SIGCONT)\n"); job->head_process->is_stopped = 0; waitpid(job->pgid, &status, WUNTRACED); if (WIFSTOPPED(status)) job->head_process->is_stopped = 1; else job->head_process->is_finish = 1; signal_display(status); if (tcsetpgrp(STDIN_FILENO, getpgid(getpid())) == -1) my_puterr("Error: tcsetpgrp\n"); if (tcsetattr(STDIN_FILENO, TCSADRAIN, &conf->tmodes) == -1) my_puterr("Error: tcsetattr\n"); }
void launchJob(char *command[], char *file, int newDescriptor, int executionMode) { pid_t pid; pid = fork(); switch (pid) { case -1: perror("MyShell"); exit(EXIT_FAILURE); break; case 0: signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTSTP, SIG_DFL); signal(SIGCHLD, &signalHandler_child); signal(SIGTTIN, SIG_DFL); usleep(20000); setpgrp(); if (executionMode == FOREGROUND) tcsetpgrp(MSH_TERMINAL, getpid()); if (executionMode == BACKGROUND) printf("[%d] %d\n", ++numActiveJobs, (int) getpid()); executeCommand(command, file, newDescriptor, executionMode); exit(EXIT_SUCCESS); break; default: setpgid(pid, pid); jobsList = insertJob(pid, pid, *(command), file, (int) executionMode); t_job* job = getJob(pid, BY_PROCESS_ID); if (executionMode == FOREGROUND) { putJobForeground(job, FALSE); } if (executionMode == BACKGROUND) putJobBackground(job, FALSE); break; } }
/// Returns control of the terminal to the shell, and saves the terminal attribute state to the job, /// so that we can restore the terminal ownership to the job at a later time. static bool terminal_return_from_job(job_t *j) { errno = 0; if (j->pgid == 0) { debug(2, "terminal_return_from_job() returning early due to no process group"); return true; } signal_block(); if (tcsetpgrp(STDIN_FILENO, getpgrp()) == -1) { if (errno == ENOTTY) redirect_tty_output(); debug(1, _(L"Could not return shell to foreground")); wperror(L"tcsetpgrp"); signal_unblock(); return false; } // Save jobs terminal modes. if (tcgetattr(STDIN_FILENO, &j->tmodes)) { if (errno == EIO) redirect_tty_output(); debug(1, _(L"Could not return shell to foreground")); wperror(L"tcgetattr"); signal_unblock(); return false; } // Disabling this per // https://github.com/adityagodbole/fish-shell/commit/9d229cd18c3e5c25a8bd37e9ddd3b67ddc2d1b72 On // Linux, 'cd . ; ftp' prevents you from typing into the ftp prompt. See // https://github.com/fish-shell/fish-shell/issues/121 #if 0 // Restore the shell's terminal modes. if (tcsetattr(STDIN_FILENO, TCSADRAIN, &shell_modes) == -1) { if (errno == EIO) redirect_tty_output(); debug(1, _(L"Could not return shell to foreground")); wperror(L"tcsetattr"); return false; } #endif signal_unblock(); return true; }
void sub_stop_handler(int sig) { int pgrp; struct sigaction act_default; struct sigaction act_stop; pgrp = getpgrp(); tcsetpgrp(1, head->pgrp); act_default.sa_handler = SIG_DFL; act_default.sa_flags = 0; sigemptyset(&act_default.sa_mask); sigaction(sig, &act_default, &act_stop); killpg(pgrp, sig); sigaction(sig, &act_stop, NULL); }
void sh_init() { /* List head */ first_job = NULL; /* Check for interactivity */ shell_terminal = STDIN_FILENO; shell_interactive = isatty(shell_terminal); if (shell_interactive) { /* Busy wait until we are foreground */ while (tcgetpgrp(shell_terminal) != (shell_pgid = getpgrp())) kill(-shell_pgid, SIGTTIN); /* Ignore some control signals */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); /* * signal(SIGCHLD, SIG_IGN); * * Ignoring SIGCHLD (or not implementing a handler) _will_ * cause waitpid to immediately return -1, thus, in our case, * completely ruining job polling in job_do_notify(), since it * depends on a valid pid returned. */ /* Insert self into group */ shell_pgid = getpid(); check(setpgid(shell_pgid, shell_pgid) >=0); /* Take control */ tcsetpgrp(shell_terminal, shell_pgid); /* Save attributes */ tcgetattr(shell_terminal, &shell_modes); } }
static int check_job_and_put_in_foreground(t_job *job, char *opt, t_config *conf) { int i; i = atoi(opt); while (job != NULL) { if (job->id == i) break; job = job->next; } if (job != NULL) { if (tcsetpgrp(STDIN_FILENO, job->pgid) == -1) my_puterr("tcsetpgrp error\n"); wait_for_job(conf, job); return (0); } return (-1); }
int fgcmd(int argc __unused, char **argv) { struct job *jp; pid_t pgrp; int status; jp = getjob(argv[1]); if (jp->jobctl == 0) error("job not created under job control"); printjobcmd(jp); flushout(&output); pgrp = jp->ps[0].pid; tcsetpgrp(ttyfd, pgrp); restartjob(jp); jp->foreground = 1; INTOFF; status = waitforjob(jp, (int *)NULL); INTON; return status; }
void util_recoverStdio(void) { int fd = open("/dev/tty", O_RDWR); if (fd == -1) { PLOG_E("Couldn't open '/dev/tty'"); return; } dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (tcsetpgrp(fd, getpid()) == -1) { PLOG_W("tcsetpgrp(%d) failed", getpid()); } if (fd > 2) { close(fd); } }
void init(void) { struct sigaction sa; CWD = getcwd(NULL, 0); UID = geteuid(); while (tcgetpgrp(STDIN_FILENO) != (PGID = getpgrp())) kill(-PGID, SIGTTIN); if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) { fputs("Non-interactive mode not supported\n", stderr); exit(EXIT_FAILURE); } sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGINT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sigaction(SIGTSTP, &sa, NULL); sigaction(SIGTTIN, &sa, NULL); sigaction(SIGTTOU, &sa, NULL); //sigaddset(&sa.sa_mask, SIGCHLD); sa.sa_handler = update_jobs; sigaction(SIGCHLD, &sa, NULL); tcgetattr(STDIN_FILENO, &SHL_TI); tcgetattr(STDIN_FILENO, &INIT_TI); SHL_TI.c_lflag &= (unsigned) ~ECHOCTL; tcsetattr(STDIN_FILENO, TCSANOW, &SHL_TI); PGID = getpid(); if (setpgid(PGID, PGID) < 0) { perror("Unable to take process group"); exit(EXIT_FAILURE); } tcsetpgrp(STDIN_FILENO, PGID); }
void post_fork_inferior (int pid, const char *program) { client_state &cs = get_client_state (); #ifdef SIGTTOU signal (SIGTTOU, SIG_IGN); signal (SIGTTIN, SIG_IGN); terminal_fd = fileno (stderr); old_foreground_pgrp = tcgetpgrp (terminal_fd); tcsetpgrp (terminal_fd, pid); atexit (restore_old_foreground_pgrp); #endif startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED, &cs.last_status, &cs.last_ptid); current_thread->last_resume_kind = resume_stop; current_thread->last_status = cs.last_status; signal_pid = pid; target_post_create_inferior (); fprintf (stderr, "Process %s created; pid = %d\n", program, pid); fflush (stderr); }
void fixerror(void) { didfds = 0; /* Forget about 0,1,2 */ /* * Go away if -e or we are a child shell */ if (!exitset || exiterr || child) xexit(1); /* * Reset the state of the input. This buffered seek to end of file will * also clear the while/foreach stack. */ btoeof(); setcopy(STRstatus, STR1, VAR_READWRITE);/*FIXRESET*/ #ifdef BSDJOBS if (tpgrp > 0) (void) tcsetpgrp(FSHTTY, tpgrp); #endif }
void setfg(void) { sigset_t osigset, nsigset; /* * Block the tty signals till things set correctly. * Taken from util.c of csh in NetBSD. */ sigemptyset(&nsigset); sigaddset(&nsigset, SIGTSTP); sigaddset(&nsigset, SIGTTIN); sigaddset(&nsigset, SIGTTOU); sigprocmask(SIG_BLOCK, &nsigset, &osigset); if (setpgid(0, 0)) fatal("setpgid %s", strerror(errno)); if (tcsetpgrp(0, getpid())) fatal("tcsetpgrp %s", strerror(errno)); sigprocmask(SIG_SETMASK, &osigset, NULL); }
/* Make sure the shell is running interactively as the foreground job before proceeding */ void init_shell () { /* See if we are running interactively. */ shell_terminal = STDIN_FILENO; shell_is_interactive = isatty (shell_terminal); if (shell_is_interactive) { while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ())) kill (- shell_pgid, SIGTTIN); signal (SIGQUIT, SIG_IGN); signal (SIGTSTP, SIG_IGN); signal (SIGTTIN, SIG_IGN); signal (SIGTTOU, SIG_IGN); signal (SIGCHLD, SIG_IGN); shell_pgid = getpid(); if (setpgid (shell_pgid, shell_pgid) < 0) printf("ERROR: Couldn't put the shell in its own process group\n"); /* Grab control of the terminal */ tcsetpgrp(shell_terminal, shell_pgid); /* Save default terminal attributes for shell. */ tcgetattr (shell_terminal, &shell_tmodes); } }
void init_shell() { char* cwd; char buff[PATH_MAX + 1]; /* Check if we are running interactively */ shell_terminal = STDIN_FILENO; /** Note that we cannot take control of the terminal if the shell is not interactive */ shell_is_interactive = isatty(shell_terminal); if(shell_is_interactive){ /* force into foreground */ while(tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp())) kill( - shell_pgid, SIGTTIN); shell_pgid = getpid(); /* Put shell in its own process group */ if(setpgid(shell_pgid, shell_pgid) < 0){ perror("Couldn't put the shell in its own process group"); exit(1); } /* Take control of the terminal */ tcsetpgrp(shell_terminal, shell_pgid); tcgetattr(shell_terminal, &shell_tmodes); } /** YOUR CODE HERE */ signal (SIGINT, SIG_IGN); signal (SIGQUIT, SIG_IGN); signal (SIGTSTP, SIG_IGN); signal (SIGTTIN, SIG_IGN); signal (SIGTTOU, SIG_IGN); signal (SIGCHLD, SIG_IGN); }
bool TTYState::SetTTYState() const { int result = 0; if (IsValid()) { if (TFlagsValid()) result = fcntl(m_fd, F_SETFL, m_tflags); if (TTYStateValid()) result = tcsetattr(m_fd, TCSANOW, &m_ttystate); if (ProcessGroupValid()) { // Save the original signal handler. void (*saved_sigttou_callback)(int) = NULL; saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN); // Set the process group result = tcsetpgrp(m_fd, m_processGroup); // Restore the original signal handler. signal(SIGTTOU, saved_sigttou_callback); } return true; } return false; }
void initShell(){ shell_terminal = STDIN_FILENO; signal (SIGINT, SIG_IGN); signal (SIGQUIT, SIG_IGN); signal (SIGTSTP, SIG_IGN); signal (SIGTTIN, SIG_IGN); signal (SIGTTOU, SIG_IGN); signal (SIGCHLD, SIG_IGN); shell_pgid = getpid (); if (setpgid (shell_pgid, shell_pgid) < 0) { perror ("Falha ao tentar inserir a shell em seu proprio grupo de processos"); exit (1); } tcsetpgrp (shell_terminal, shell_pgid); tcgetattr (shell_terminal, &shell_tmodes_stdin); tcgetattr (STDOUT_FILENO, &shell_tmodes_stdout); }
static void shutdown(int signo) { struct termios tc; #ifdef TIOCCONS int console_fd; int on = 1; #endif if (login_running == RUNNING) kill(loginpid, SIGHUP); if (console_running == RUNNING) kill(consolepid, SIGHUP); if (x_running == RUNNING) kill(xpid, SIGTERM); setpgid(0, 0); /* We have to reset the tty pgrp */ tcsetpgrp(0, getpgrp()); tcflush(0, TCIOFLUSH); (void) tcgetattr(0, &tc); tc.c_lflag |= (ICANON | ISIG | ECHO); (void) tcsetattr(0, TCSADRAIN, &tc); (void) sigprocmask(SIG_SETMASK, &sig_zero, (sigset_t *) 0); /* Stop console redirection. In the SRIOCSREDIR case, it is * sufficient merely to close the slave side of the pty. * In the TIOCCONS case, explicitly redirect to /dev/console. */ close(console_slave_fd); #ifdef TIOCCONS console_fd = open("/dev/console", O_RDWR); if (console_fd >= 0) ioctl(console_fd, TIOCCONS, &on); #endif close(console_master_fd); while (1) pause(); }
void initShell() { shellTerminal = STDIN_FILENO; shellIsInteractive = isatty(shellTerminal); jobs = initJob(); jobs->commandLine = NULL; if(shellIsInteractive) { struct sigaction act, oact; sigset_t new_mask, old_mask; if(memset(&act, 0, sizeof(struct sigaction)) == NULL) printf("Error in signal handler creation!\n"); /* Loop until we are in the foreground. */ while( tcgetpgrp(shellTerminal) != (shellPgid = getpgrp())) kill (-shellPgid, SIGTTIN); // Send signal to stop all process in the shell group // Put ourselves in our own process group shellPgid = getpid(); if(setpgid(shellPgid, shellPgid) < 0) { printf("Error: Couldn't put the shell in its own process group"); exit(EXIT_FAILURE); } // Grab control of the terminal tcsetpgrp(shellTerminal, shellPgid); // Save default terminal attributes for shell. tcgetattr(shellTerminal, &shellTmodes); // Ignore interactive and job-control signals. act.sa_handler = stopJob; sigaction(SIGTSTP, &act, &oact); /* SIGTSTP is ^Z */ sigfillset (&new_mask); sigdelset (&new_mask, SIGTSTP); sigprocmask (SIG_BLOCK, &new_mask, &old_mask); } }
/** Returns control of the terminal to the shell, and saves the terminal attribute state to the job, so that we can restore the terminal ownership to the job at a later time . */ static int terminal_return_from_job(job_t *j) { if (tcsetpgrp(0, getpgrp())) { debug(1, _(L"Could not return shell to foreground")); wperror(L"tcsetpgrp"); return 0; } /* Save jobs terminal modes. */ if (tcgetattr(0, &j->tmodes)) { debug(1, _(L"Could not return shell to foreground")); wperror(L"tcgetattr"); return 0; } /* Disabling this per https://github.com/adityagodbole/fish-shell/commit/9d229cd18c3e5c25a8bd37e9ddd3b67ddc2d1b72 On Linux, 'cd . ; ftp' prevents you from typing into the ftp prompt See https://github.com/fish-shell/fish-shell/issues/121 */ #if 0 /* Restore the shell's terminal modes. */ if (tcsetattr(0, TCSADRAIN, &shell_modes)) { debug(1, _(L"Could not return shell to foreground")); wperror(L"tcsetattr"); return 0; } #endif return 1; }
void init_shell() { /* Check if we are running interactively */ shell_terminal = STDIN_FILENO; /** Note that we cannot take control of the terminal if the shell is not interactive */ shell_is_interactive = isatty(shell_terminal); if(shell_is_interactive) { /* force into foreground */ while(tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp())) { kill( - shell_pgid, SIGTTIN); } signal (SIGINT, SIG_IGN);//interrupt : C-c signal (SIGQUIT, SIG_IGN);/*C-\, same as SIGINT, makes core dump, (like user detects error) */ signal (SIGTSTP, SIG_IGN);//C-z signal (SIGTTIN, SIG_IGN);//sent if tries to read from terminal when in background signal (SIGTTOU, SIG_IGN);//same as previous but writing to terminal shell_pgid = getpid(); /* Put shell in its own process group */ if(setpgid(shell_pgid, shell_pgid) < 0) { perror("Couldn't put the shell in its own process group"); exit(1); } /* Take control of the terminal */ tcsetpgrp(shell_terminal, shell_pgid); tcgetattr(shell_terminal, &shell_tmodes); } /** YOUR CODE HERE */ }
/* * initialize global data structures * set up signal handlers */ void setup() { memset(&root, 0, sizeof(root)); setbuf(stdout, NULL); using_history(); while (tcgetpgrp(0) != (s_pgid = getpgrp())) { kill(-s_pgid, SIGTTIN); } signal(SIGTTOU, SIG_IGN); s_pgid = getpid(); if (setpgid(s_pgid, s_pgid) < 0) { perror("setpgid"); _exit(1); } tcsetpgrp(0, s_pgid); signal(SIGINT, SIG_IGN); signal(SIGTSTP, SIG_IGN); }
int console_init() { int fd; /* * Clean up */ ioctl(0, TIOCNOTTY, 0); close(0); close(1); close(2); setsid(); /* * Reopen console */ if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) { /* * Avoid debug messages is redirected to socket packet if no exist a * UART chip, added by honor, 2003-12-04 */ (void)open("/dev/null", O_RDONLY); (void)open("/dev/null", O_WRONLY); (void)open("/dev/null", O_WRONLY); perror(_PATH_CONSOLE); return errno; } dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); ioctl(0, TIOCSCTTY, 1); tcsetpgrp(0, getpgrp()); set_term(0); return 0; }
void init_shell() { /* See if we are running interactively. */ shell_terminal = STDIN_FILENO; /* isatty test whether a file descriptor referes to a terminal */ shell_is_interactive = isatty(shell_terminal); if(shell_is_interactive) { /* Loop until we are in the foreground. */ while(tcgetpgrp(shell_terminal) != (shell_pgid = getpgrp())) kill(- shell_pgid, SIGTTIN); /* Ignore interactive and job-control signals. */ /* If tcsetpgrp() is called by a member of a background process * group in its session, and the calling process is not blocking or * ignoring SIGTTOU, a SIGTTOU signal is sent to all members of * this background process group. */ signal(SIGTTOU, SIG_IGN); /* Put ourselves in our own process group. */ shell_pgid = getpid(); if(setpgid(shell_pgid, shell_pgid) < 0) { perror("Couldn't put the shell in its own process group"); exit(1); } /* Grab control of the terminal. */ tcsetpgrp(shell_terminal, shell_pgid); /* Save default terminal attributes for shell. */ tcgetattr(shell_terminal, &shell_tmodes); } log_fd = open(LOGFILE, O_WRONLY|O_CREAT|O_TRUNC, 0664); }
int shell_init(t_sh *sh) { int ret; sh->last_exit_status = 0; sh->pgid = getpid(); if ((ret = shell_language(LANG_EN)) < 0) return (-ret); if ((ret = s_shell_fd_init(sh)) != ST_OK) { log_error("s_shell_fd_init() failed"); return (ret); } if (sh->is_interactive == true) { /* jobs */ while (tcgetpgrp(STDIN_FILENO) != (sh->pgid = getpgrp())) { if (kill(-sh->pgid, SIGTTIN) != 0) log_error("kill(-sh->pgid. SIGTTIN) failed"); } if ((ret = signal_to_ignore()) != ST_OK) return (ret); if (setpgid(sh->pgid, sh->pgid) < 0) return (ST_SETPGID); log_info("pgid: %d", sh->pgid); if (tcsetpgrp(STDIN_FILENO, sh->pgid) < 0) return (ST_TCSETPGRP); /* termcaps */ if (!termcaps_init(sh)) return (ST_TERMCAPS_INIT); } return (ST_OK); }
void init(){ orig_program_invocation_name=program_invocation_name; program_invocation_name=program_invocation_short_name; signal (SIGCHLD,signal_handler); signal (SIGINT, signal_handler); signal (SIGQUIT, SIG_IGN); signal (SIGTSTP, SIG_IGN); signal (SIGTTIN, SIG_IGN); signal (SIGTTOU, SIG_IGN); mypid=getpid(); setpgid(mypid,mypid); //process grouping shell_in=STDIN_FILENO; shell_out=STDOUT_FILENO; tcsetpgrp(shell_in,mypid); curr_user_id=getuid(); user_info=getpwuid(curr_user_id); user_name=user_info->pw_name; //homedir=user_info->pw_dir; /* #NOTE Some wierd convention requires the ~ to refer to the * directory the shell was instantiated in instead of the home directory */ homedir=malloc(PATH_LENGTH_MAX); while(getcwd(homedir,PATH_LENGTH_MAX)==NULL){ if(errno==ERANGE){ PATH_LENGTH_MAX*=2; homedir=realloc(homedir,PATH_LENGTH_MAX); } else{ perror("getcwd"); exit(2); } } homelen=strlen(homedir); gethostname(hostname,sizeof(hostname)); last_command=malloc(COMMAND_LENGTH_MAX); comm_history=malloc(HIST_LENGTH_MAX*sizeof(char*)); }
/* Intialization procedures for this shell */ void init_shell() { /* Our shell is connected to standard input. */ shell_terminal = STDIN_FILENO; /* Check if we are running interactively */ shell_is_interactive = isatty(shell_terminal); if (shell_is_interactive) { /* If the shell is not currently in the foreground, we must pause the shell until it becomes a * foreground process. We use SIGTTIN to pause the shell. When the shell gets moved to the * foreground, we'll receive a SIGCONT. */ while (tcgetpgrp(shell_terminal) != (shell_pgid = getpgrp())) kill(-shell_pgid, SIGTTIN); /* Saves the shell's process id */ shell_pgid = getpid(); /* Take control of the terminal */ tcsetpgrp(shell_terminal, shell_pgid); /* Save the current termios to a variable, so it can be restored later. */ tcgetattr(shell_terminal, &shell_tmodes); } }
Val _lib7_P_TTY_tcsetpgrp (Task* task, Val arg) { //===================== // // _lib7_P_TTY_tcsetpgrp : (Int, Int) -> Void // // Set foreground process group id of tty. // // This fn gets bound as tcsetpgrp in: // // src/lib/std/src/posix-1003.1b/posix-tty.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_TTY_tcsetpgrp"); int fd = GET_TUPLE_SLOT_AS_INT(arg, 0); int pgrp = GET_TUPLE_SLOT_AS_INT(arg, 1); RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsetpgrp", NULL ); // int status = tcsetpgrp( fd, pgrp ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsetpgrp" ); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
void process_shell_commad(){ if(last_command[0]=='\0' || (last_command[0]==' ' && last_command[1]=='\0')) return; //STORE HISTORY comm_history[hist_size++]=strdup(last_command); if(hist_size==HIST_LENGTH_MAX){ HIST_LENGTH_MAX*=2; comm_history=realloc(comm_history,HIST_LENGTH_MAX); } //split on pipe; char *pipelist[MAX_PIPE]; int pipcnt=0; pipelist[pipcnt]=strtok(last_command,"|"); while(pipelist[pipcnt]) pipelist[++pipcnt]=strtok(NULL,"|"); int fd[2],curin,curout,prevout; register int i; prevout=STDIN_FILENO; pid_t group_id=0,retid; for(i=0;i<pipcnt;i++){ curin=prevout; if(i+1<pipcnt){ pipe(fd); curout=fd[1]; prevout=fd[0]; } else curout=STDOUT_FILENO; retid=process_single_command(pipelist[i],curin,curout,group_id,(i+1<pipcnt)?EXEC_MORE_PIPES:0); if(group_id==0) group_id=retid; } tcsetpgrp(shell_in,mypid); }
/* * execute the fg builtin command */ void exec_fg_cmd(struct cmdline_tokens* toks) { struct job_t* job; int argc = toks -> argc; if(toks -> argv[argc - 1][0] == '%'){ int jobid = atoi(toks -> argv[argc - 1] + 1); job = getjobjid(job_list, jobid); if(job == NULL){ printf("(%d): No such job\n", jobid); return; } } else if(isdigit(toks -> argv[argc - 1][0])){ int pid = atoi(toks -> argv[argc - 1]); job = getjobpid(job_list, pid); if(job == NULL){ printf("(%d): No such process\n", pid); return; } } else { unix_error("fg: argument must be a pid or %%jobid\n"); return; } tcsetpgrp(STDIN_FILENO, job -> pid); job -> state = FG; kill(job -> pid, SIGCONT); sigset_t emptyset; if(sigemptyset(&emptyset)){ unix_error("set is not empty"); } while(fgpid(job_list) && job -> state == FG) sigsuspend(&emptyset); }