This file is jobs.def, from which is created jobs.c.
It implements the builtins "jobs" and "disown" in Bash.

Copyright (C) 1987-2009 Free Software Foundation, Inc.

This file is part of GNU Bash, the Bourne Again SHell.

Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Bash.  If not, see <http://www.gnu.org/licenses/>.

$PRODUCES jobs.c

$BUILTIN jobs
$FUNCTION jobs_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC jobs [-lnprs] [jobspec ...] or jobs -x command [args]
Display status of jobs.

Lists the active jobs.  JOBSPEC restricts output to that job.
Without options, the status of all active jobs is displayed.

Options:
  -l	lists process IDs in addition to the normal information
  -n	list only processes that have changed status since the last
	notification
  -p	lists process IDs only
  -r	restrict output to running jobs
  -s	restrict output to stopped jobs

If -x is supplied, COMMAND is run after all job specifications that
appear in ARGS have been replaced with the process ID of that job's
process group leader.

Exit Status:
Returns success unless an invalid option is given or an error occurs.
If -x is used, returns the exit status of COMMAND.
$END

#include <config.h>

#if defined (JOB_CONTROL)
#include "../bashtypes.h"
#include <signal.h>
#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#include "../bashansi.h"
#include "../bashintl.h"

#include "../shell.h"
#include "../jobs.h"
#include "../execute_cmd.h"
#include "bashgetopt.h"
#include "common.h"

#define JSTATE_ANY	0x0
#define JSTATE_RUNNING	0x1
#define JSTATE_STOPPED	0x2

static int execute_list_with_replacements __P((WORD_LIST *));

/* The `jobs' command.  Prints outs a list of active jobs.  If the
   argument `-l' is given, then the process id's are printed also.
   If the argument `-p' is given, print the process group leader's
   pid only.  If `-n' is given, only processes that have changed
   status since the last notification are printed.  If -x is given,
   replace all job specs with the pid of the appropriate process
   group leader and execute the command.  The -r and -s options mean
   to print info about running and stopped jobs only, respectively. */
int
jobs_builtin (list)
     WORD_LIST *list;
{
  int form, execute, state, opt, any_failed, job;
  sigset_t set, oset;

  execute = any_failed = 0;
  form = JLIST_STANDARD;
  state = JSTATE_ANY;

  reset_internal_getopt ();
  while ((opt = internal_getopt (list, "lpnxrs")) != -1)
    {
      switch (opt)
	{
	case 'l':
	  form = JLIST_LONG;
	  break;
	case 'p':
	  form = JLIST_PID_ONLY;
	  break;
	case 'n':
	  form = JLIST_CHANGED_ONLY;
	  break;
	case 'x':
	  if (form != JLIST_STANDARD)
	    {
	      builtin_error (_("no other options allowed with `-x'"));
	      return (EXECUTION_FAILURE);
	    }
	  execute++;
	  break;
	case 'r':
	  state = JSTATE_RUNNING;
	  break;
	case 's':
	  state = JSTATE_STOPPED;
	  break;

	default:
	  builtin_usage ();
	  return (EX_USAGE);
	}
    }

  list = loptend;

  if (execute)
    return (execute_list_with_replacements (list));

  if (!list)
    {
      switch (state)
	{
	case JSTATE_ANY:
	  list_all_jobs (form);
	  break;
	case JSTATE_RUNNING:
	  list_running_jobs (form);
	  break;
	case JSTATE_STOPPED:
	  list_stopped_jobs (form);
	  break;
	}
      return (EXECUTION_SUCCESS);
    }

  while (list)
    {
      BLOCK_CHILD (set, oset);
      job = get_job_spec (list);

      if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0)
	{
	  sh_badjob (list->word->word);
	  any_failed++;
	}
      else if (job != DUP_JOB)
	list_one_job ((JOB *)NULL, form, 0, job);

      UNBLOCK_CHILD (oset);
      list = list->next;
    }
  return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}

static int
execute_list_with_replacements (list)
     WORD_LIST *list;
{
  register WORD_LIST *l;
  int job, result;
  COMMAND *command;
  JOB *j;

  /* First do the replacement of job specifications with pids. */
  for (l = list; l; l = l->next)
    {
      if (l->word->word[0] == '%')	/* we have a winner */
	{
	  job = get_job_spec (l);

	  /* A bad job spec is not really a job spec! Pass it through. */
	  if (INVALID_JOB (job))
	    continue;

	  j = get_job_by_jid (job);
	  free (l->word->word);
	  l->word->word = itos (j->pgrp);
	}
    }

  /* Next make a new simple command and execute it. */
  begin_unwind_frame ("jobs_builtin");

  command = make_bare_simple_command ();
  command->value.Simple->words = copy_word_list (list);
  command->value.Simple->redirects = (REDIRECT *)NULL;
  command->flags |= CMD_INHIBIT_EXPANSION;
  command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;

  add_unwind_protect (dispose_command, command);
  result = execute_command (command);
  dispose_command (command);

  discard_unwind_frame ("jobs_builtin");
  return (result);
}
#endif /* JOB_CONTROL */

$BUILTIN disown
$FUNCTION disown_builtin
$DEPENDS_ON JOB_CONTROL
$SHORT_DOC disown [-h] [-ar] [jobspec ...]
Remove jobs from current shell.

Removes each JOBSPEC argument from the table of active jobs.  Without
any JOBSPECs, the shell uses its notion of the current job.

Options:
  -a	remove all jobs if JOBSPEC is not supplied
  -h	mark each JOBSPEC so that SIGHUP is not sent to the job if the
	shell receives a SIGHUP
  -r	remove only running jobs

Exit Status:
Returns success unless an invalid option or JOBSPEC is given.
$END

#if defined (JOB_CONTROL)
int
disown_builtin (list)
     WORD_LIST *list;
{
  int opt, job, retval, nohup_only, running_jobs, all_jobs;
  sigset_t set, oset;
  intmax_t pid_value;

  nohup_only = running_jobs = all_jobs = 0;
  reset_internal_getopt ();
  while ((opt = internal_getopt (list, "ahr")) != -1)
    {
      switch (opt)
	{
	case 'a':
	  all_jobs = 1;
	  break;
	case 'h':
	  nohup_only = 1;
	  break;
	case 'r':
	  running_jobs = 1;
	  break;
	default:
	  builtin_usage ();
	  return (EX_USAGE);
	}
    }
  list = loptend;
  retval = EXECUTION_SUCCESS;

  /* `disown -a' or `disown -r' */
  if (list == 0 && (all_jobs || running_jobs))
    {
      if (nohup_only)
	nohup_all_jobs (running_jobs);
      else
	delete_all_jobs (running_jobs);
      return (EXECUTION_SUCCESS);
    }

  do
    {
      BLOCK_CHILD (set, oset);
      job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value)
		? get_job_by_pid ((pid_t) pid_value, 0)
		: get_job_spec (list);

      if (job == NO_JOB || jobs == 0 || INVALID_JOB (job))
	{
	  sh_badjob (list ? list->word->word : _("current"));
	  retval = EXECUTION_FAILURE;
	}
      else if (nohup_only)
	nohup_job (job);
      else
	delete_job (job, 1);
      UNBLOCK_CHILD (oset);

      if (list)
	list = list->next;
    }
  while (list);

  return (retval);
}
#endif /* JOB_CONTROL */
