da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef JOB_NFLAG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Interface to job control for shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * written by David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOBTTY 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sfio.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef SIGINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <signal.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !SIGINT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/options"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(SIGCLD) && !defined(SIGCHLD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define SIGCHLD SIGCLD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGCHLD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define JOBS 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "terminal.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef FIOLOOKLD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Ninth edition */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int tty_ld, ntty_ld;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define OTTYDISC tty_ld
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define NTTYDISC ntty_ld
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* FIOLOOKLD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef SH_MONITOR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define SH_MONITOR 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define job_set(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define job_reset(x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct process
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct process *p_nxtjob; /* next job structure */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct process *p_nxtproc; /* next process in current job */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t p_pid; /* process id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t p_pgrp; /* process group */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t p_fgrp; /* process group when stopped */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short p_job; /* job number of process */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short p_exit; /* exit value or signal number */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned short p_exitmin; /* minimum exit value for xargs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short p_flag; /* flags - see below */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int p_env; /* subshell environment number */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t p_name; /* history file offset for command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct termios p_stty; /* terminal state for job */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct jobs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct process *pwlist; /* head of process list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t curpgid; /* current process gid id */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t parent; /* set by fork() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t mypid; /* process id of shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t mypgid; /* process group id of shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t mytgid; /* terminal group id of shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned int in_critical; /* >0 => in critical region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int savesig; /* active signal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int numpost; /* number of posted jobs */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef SHOPT_BGX
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int numbjob; /* number of background jobs */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* SHOPT_BGX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short fd; /* tty descriptor number */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int suspend; /* suspend character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int linedisc; /* line dicipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char jobcontrol; /* turned on for real job control */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char waitsafe; /* wait will not block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char waitall; /* wait for all jobs in pipe */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char toclear; /* job table needs clearing */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char *freejobs; /* free jobs numbers */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* flags for joblist */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOB_LFLAG 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOB_NFLAG 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOB_PFLAG 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define JOB_NLFLAG 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern struct jobs job;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if !_std_malloc
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <vmalloc.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if VMALLOC_VERSION >= 20070911L
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define vmbusy() (vmstat(0,0)!=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifndef vmbusy
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define vmbusy() 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define job_lock() (job.in_critical++)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define job_unlock() \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do { \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int sig; \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!--job.in_critical && (sig = job.savesig)) \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!job.in_critical++ && !vmbusy()) \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz job_reap(sig); \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz job.in_critical--; \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_jobusage[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_done[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_running[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_coredump[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_no_proc[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_no_job[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_jobsrunning[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_nlspace[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_access[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_terminate[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_no_jctl[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char e_signo[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern const char e_no_start[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef NTTYDISC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern const char e_newtty[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern const char e_oldtty[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* NTTYDISC */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following are defined in jobs.c
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void job_clear(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void job_bwait(char**);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int job_walk(Sfio_t*,int(*)(struct process*,int),int,char*[]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int job_kill(struct process*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinextern int job_wait(pid_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int job_post(pid_t,pid_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void *job_subsave(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void job_subrestore(void*);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef SHOPT_BGX
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzextern void job_chldtrap(Shell_t*, const char*,int);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* SHOPT_BGX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin extern void job_init(Shell_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin extern int job_close(Shell_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int job_list(struct process*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int job_terminate(struct process*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int job_switch(struct process*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern void job_fork(pid_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern int job_reap(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define job_init(s,flag)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define job_close(s) (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define job_fork(p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !JOB_NFLAG */