14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1982-2010 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin #ifndef JOB_NFLAG 224887Schin /* 234887Schin * Interface to job control for shell 244887Schin * written by David Korn 254887Schin * 264887Schin */ 274887Schin 284887Schin #define JOBTTY 2 294887Schin 304887Schin #include <ast.h> 314887Schin #include <sfio.h> 324887Schin #ifndef SIGINT 334887Schin # include <signal.h> 344887Schin #endif /* !SIGINT */ 354887Schin #include "FEATURE/options" 364887Schin 374887Schin #undef JOBS 384887Schin #if defined(SIGCLD) && !defined(SIGCHLD) 394887Schin # define SIGCHLD SIGCLD 404887Schin #endif 414887Schin #ifdef SIGCHLD 424887Schin # define JOBS 1 434887Schin # include "terminal.h" 444887Schin # ifdef FIOLOOKLD 454887Schin /* Ninth edition */ 464887Schin extern int tty_ld, ntty_ld; 474887Schin # define OTTYDISC tty_ld 484887Schin # define NTTYDISC ntty_ld 494887Schin # endif /* FIOLOOKLD */ 504887Schin #else 514887Schin # undef SIGTSTP 524887Schin # undef SH_MONITOR 534887Schin # define SH_MONITOR 0 544887Schin # define job_set(x) 554887Schin # define job_reset(x) 564887Schin #endif 574887Schin 584887Schin struct process 594887Schin { 604887Schin struct process *p_nxtjob; /* next job structure */ 614887Schin struct process *p_nxtproc; /* next process in current job */ 624887Schin pid_t p_pid; /* process id */ 634887Schin pid_t p_pgrp; /* process group */ 644887Schin pid_t p_fgrp; /* process group when stopped */ 654887Schin short p_job; /* job number of process */ 664887Schin unsigned short p_exit; /* exit value or signal number */ 678462SApril.Chin@Sun.COM unsigned short p_exitmin; /* minimum exit value for xargs */ 684887Schin unsigned short p_flag; /* flags - see below */ 694887Schin int p_env; /* subshell environment number */ 704887Schin #ifdef JOBS 714887Schin off_t p_name; /* history file offset for command */ 724887Schin struct termios p_stty; /* terminal state for job */ 734887Schin #endif /* JOBS */ 744887Schin }; 754887Schin 764887Schin struct jobs 774887Schin { 784887Schin struct process *pwlist; /* head of process list */ 794887Schin pid_t curpgid; /* current process gid id */ 804887Schin pid_t parent; /* set by fork() */ 814887Schin pid_t mypid; /* process id of shell */ 824887Schin pid_t mypgid; /* process group id of shell */ 834887Schin pid_t mytgid; /* terminal group id of shell */ 844887Schin unsigned int in_critical; /* >0 => in critical region */ 854887Schin int savesig; /* active signal */ 864887Schin int numpost; /* number of posted jobs */ 8710898Sroland.mainz@nrubsig.org #ifdef SHOPT_BGX 8810898Sroland.mainz@nrubsig.org int numbjob; /* number of background jobs */ 8910898Sroland.mainz@nrubsig.org #endif /* SHOPT_BGX */ 904887Schin short fd; /* tty descriptor number */ 914887Schin #ifdef JOBS 924887Schin int suspend; /* suspend character */ 934887Schin int linedisc; /* line dicipline */ 944887Schin #endif /* JOBS */ 954887Schin char jobcontrol; /* turned on for real job control */ 964887Schin char waitsafe; /* wait will not block */ 974887Schin char waitall; /* wait for all jobs in pipe */ 984887Schin char toclear; /* job table needs clearing */ 994887Schin unsigned char *freejobs; /* free jobs numbers */ 1004887Schin }; 1014887Schin 1024887Schin /* flags for joblist */ 1034887Schin #define JOB_LFLAG 1 1044887Schin #define JOB_NFLAG 2 1054887Schin #define JOB_PFLAG 4 1064887Schin #define JOB_NLFLAG 8 1074887Schin 1084887Schin extern struct jobs job; 1094887Schin 1104887Schin #ifdef JOBS 1114887Schin 1128462SApril.Chin@Sun.COM #if !_std_malloc 1138462SApril.Chin@Sun.COM #include <vmalloc.h> 1148462SApril.Chin@Sun.COM #if VMALLOC_VERSION >= 20070911L 1158462SApril.Chin@Sun.COM #define vmbusy() (vmstat(0,0)!=0) 1168462SApril.Chin@Sun.COM #endif 1178462SApril.Chin@Sun.COM #endif 1188462SApril.Chin@Sun.COM #ifndef vmbusy 1198462SApril.Chin@Sun.COM #define vmbusy() 0 1208462SApril.Chin@Sun.COM #endif 1218462SApril.Chin@Sun.COM 1224887Schin #define job_lock() (job.in_critical++) 12310898Sroland.mainz@nrubsig.org #define job_unlock() \ 12410898Sroland.mainz@nrubsig.org do { \ 12510898Sroland.mainz@nrubsig.org int sig; \ 12610898Sroland.mainz@nrubsig.org if (!--job.in_critical && (sig = job.savesig)) \ 12710898Sroland.mainz@nrubsig.org { \ 12810898Sroland.mainz@nrubsig.org if (!job.in_critical++ && !vmbusy()) \ 12910898Sroland.mainz@nrubsig.org job_reap(sig); \ 13010898Sroland.mainz@nrubsig.org job.in_critical--; \ 13110898Sroland.mainz@nrubsig.org } \ 13210898Sroland.mainz@nrubsig.org } while(0) 1334887Schin 1344887Schin extern const char e_jobusage[]; 1354887Schin extern const char e_done[]; 1364887Schin extern const char e_running[]; 1374887Schin extern const char e_coredump[]; 1384887Schin extern const char e_no_proc[]; 1394887Schin extern const char e_no_job[]; 1404887Schin extern const char e_jobsrunning[]; 1414887Schin extern const char e_nlspace[]; 1424887Schin extern const char e_access[]; 1434887Schin extern const char e_terminate[]; 1444887Schin extern const char e_no_jctl[]; 1454887Schin extern const char e_signo[]; 1464887Schin #ifdef SIGTSTP 1474887Schin extern const char e_no_start[]; 1484887Schin #endif /* SIGTSTP */ 1494887Schin #ifdef NTTYDISC 1504887Schin extern const char e_newtty[]; 1514887Schin extern const char e_oldtty[]; 1524887Schin #endif /* NTTYDISC */ 1534887Schin #endif /* JOBS */ 1544887Schin 1554887Schin /* 1564887Schin * The following are defined in jobs.c 1574887Schin */ 1584887Schin 1594887Schin extern void job_clear(void); 1604887Schin extern void job_bwait(char**); 1614887Schin extern int job_walk(Sfio_t*,int(*)(struct process*,int),int,char*[]); 1624887Schin extern int job_kill(struct process*,int); 1638462SApril.Chin@Sun.COM extern int job_wait(pid_t); 1644887Schin extern int job_post(pid_t,pid_t); 1654887Schin extern void *job_subsave(void); 1664887Schin extern void job_subrestore(void*); 16710898Sroland.mainz@nrubsig.org #ifdef SHOPT_BGX 16810898Sroland.mainz@nrubsig.org extern void job_chldtrap(Shell_t*, const char*,int); 16910898Sroland.mainz@nrubsig.org #endif /* SHOPT_BGX */ 1704887Schin #ifdef JOBS 1718462SApril.Chin@Sun.COM extern void job_init(Shell_t*,int); 1728462SApril.Chin@Sun.COM extern int job_close(Shell_t*); 1734887Schin extern int job_list(struct process*,int); 1744887Schin extern int job_terminate(struct process*,int); 1754887Schin extern int job_switch(struct process*,int); 1764887Schin extern void job_fork(pid_t); 1774887Schin extern int job_reap(int); 1784887Schin #else 1798462SApril.Chin@Sun.COM # define job_init(s,flag) 1808462SApril.Chin@Sun.COM # define job_close(s) (0) 1814887Schin # define job_fork(p) 1824887Schin #endif /* JOBS */ 1834887Schin 1844887Schin 1854887Schin #endif /* !JOB_NFLAG */ 186