jobs.c revision 965005c81e0f731867d47892b9fb677030b102df
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2001 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Job control for UNIX Shell
*/
#include <fcntl.h>
#include <errno.h>
#include "defs.h"
/*
* one of these for each active job
*/
struct job
{
char *j_pwd; /* job's working directory */
char *j_cmd; /* cmd used to invoke this job */
};
/* defines for j_flag */
/* termio settings were saved */
/* options to the printjob() function defined below */
static int eofflg,
jobcnt, /* number of active jobs */
jobdone, /* number of active but finished jobs */
jobnote; /* jobs requiring notification */
svtgid; /* saved foreground process group ID */
**nextjob,
*thisjob,
*joblst; /* active jobs listed in job ID order */
{
return (pgid);
return ((pid_t)-1);
}
int
int fd;
{
}
static struct job *
{
continue;
return (jp);
}
static struct job *
{
int i;
if (*job != '%')
continue;
} else if (*job == '?') {
int j;
char *p;
jp = 0;
continue;
if (jp != 0)
break;
}
}
}
} else {
jp = 0;
continue;
if (jp != 0)
}
}
}
return (jp);
}
static void
{
continue;
continue;
jobcnt--;
jobdone--;
}
/*
* Collect the foreground job.
* Used in the case where the subshell wants
* to exit, but needs to wait until the fg job
* is done.
*/
void
collect_fg_job(void)
{
int stat;
break;
if (!jp)
/* no foreground job */
return;
/*
* Wait on fg job until wait succeeds
* or it fails due to no waitable children.
*/
while (1) {
errno = 0;
break;
}
}
/*
* analyze the status of a job
*/
static int
{
int done = 0;
if (WIFCONTINUED(stat)) {
jobnote++;
}
}
} else if (WIFSTOPPED(stat)) {
if (fg) {
else {
}
}
jobnote++;
}
} else {
done++;
jobdone++;
if (WIFSIGNALED(stat)) {
jobnote++;
}
} else { /* WIFEXITED */
jobnote++;
}
}
if (fg) {
}
}
if (rc) {
exitset();
}
return (done);
}
/*
* collect the status of jobs that have recently exited or stopped -
* if wnohang == WNOHANG, wait until error, or all jobs are accounted for;
*
* called after each command is executed, with wnohang == 0, and as part
* of "wait" builtin with wnohang == WNOHANG
*
* We do not need to call chktrap here if waitpid(2) is called with
* wnohang == 0, because that only happens from syswait() which is called
* from builtin() where chktrap() is already called.
*/
static void
{
int stat, n;
int wflags;
else
wflags = 0;
break;
}
}
void
freejobs()
{
if (jobnote) {
else
}
}
}
if (jobdone) {
}
}
}
static void
{
int stat;
int done;
int wflags;
int ret = 0;
int err = 0;
else
wflags = 0;
do {
errno = 0;
stat = 0;
break;
}
}
/*
* modify the foreground process group to *new* only if the
* current foreground process group is equal to *expected*
*/
int
{
return (current);
return (0);
}
static void
{
struct job *t;
}
if (fg) {
}
}
if (fg) {
} else {
}
}
static void
{
int sp = 0;
jobnote--;
}
prc_buff('[');
prc_buff(']');
sp = 1;
}
while (sp-- > 0)
sp = 1;
prc_buff('+');
prc_buff('-');
else
sp++;
}
while (sp-- > 0)
sp = 1;
}
while (sp-- > 0)
sp = 28;
} else {
prs_buff("Signal ");
}
}
prc_buff('(');
prc_buff(')');
} else {
}
if (sp < 1)
sp = 1;
}
while (sp-- > 0)
sp = 1;
}
while (sp-- > 0)
prc_buff('&');
sp = 1;
}
while (sp-- > 0)
prs_buff("(wd: ");
prc_buff(')');
}
flushb();
}
/*
* called to initialize job control for each new input file to the shell,
* and after the "exec" builtin
*/
void
{
return;
}
setpgid(0, 0);
}
}
int
int check_if;
{
return (1);
if (check_if & JOB_STOPPED) {
return (0);
}
}
}
if (check_if & JOB_RUNNING) {
return (0);
}
}
}
}
}
return (1);
}
/*
* called by the shell to reserve a job slot for a job about to be spawned
*/
void
{
jobcnt--;
}
void
{
cmdlen -= 2;
}
if (jp == 0)
jobcnt++;
if (monitor) {
break;
break;
} else
jid = 0;
}
void
clearjobs(void)
{
}
jobcnt = 0;
jobnote = 0;
jobdone = 0;
}
void
{
if (monitor) {
setpgid(0, 0);
if (fg)
} else if (!fg) {
#ifdef NICE
#endif
if (!ioset)
}
}
/*
* called by the shell after job has been spawned, to fill in the
* job slot, and wait for the job if in the foreground
*/
void
int fg;
{
int propts;
} else {
}
eofflg = 0;
if (fg) {
} else {
}
}
/*
* the builtin "jobs" command
*/
void
int argc;
char *argv[];
{
int propts, c;
extern int opterr, i;
int loptind = -1;
optind = 1;
opterr = 0;
_sp = 1;
propts = 0;
if (propts) {
goto err;
}
switch (c) {
case 'x':
propts = -1;
break;
case 'p':
break;
case 'l':
break;
case '?':
goto err;
}
}
err:
if (loptind == -1)
return;
if (propts == -1) {
unsigned char *bp;
char *cp;
unsigned char *savebp;
if (*cp == '%') {
}
while (*cp) {
}
}
return;
}
if (propts == 0)
}
} else do
}
/*
* the builtin "fg" and "bg" commands
*/
void
{
int fg;
if (*++argv == 0) {
if (jp == 0)
break;
}
}
else do
while (*++argv);
}
/*
* the builtin "wait" commands
*/
void
int argc;
char *argv[];
{
int stat;
int wflags;
else
wflags = 0;
if (argc == 1)
collectjobs(0);
else while (--argc) {
continue;
continue;
break;
}
}
static void
{
int pgrp = 0;
int stopme = 0;
if (*args == '%') {
pgrp++;
} else {
if (*args == '-') {
pgrp++;
args++;
}
id = 0;
do {
return;
}
} while (*++args);
if (id == 0) {
pgrp++;
}
}
return;
}
stopme++;
}
}
if (pgrp)
switch (errno) {
case EPERM:
break;
case EINVAL:
break;
default:
if (pgrp)
else
break;
}
if (stopme) {
}
}
void
{
if (argc <= 1)
while (*++argv)
}
void
{
if (argc == 1) {
return;
}
if (argc == 2) {
int i;
int cnt = 0;
char sep = 0;
char buf[12];
return;
}
for (i = 1; i < MAXTRAP; i++) {
continue;
if (sep)
else
}
return;
}
return;
}
argv++;
}
while (*++argv)
}
void
{
if (argc != 1)
}