⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jobs.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
  else if (temp == js.j_lastasync)    js.j_lastasync = 0;  free (temp->wd);  ndel = discard_pipeline (temp->pipe);  js.c_injobs -= ndel;  if (temp->state == JDEAD)    {      js.c_reaped -= ndel;      js.j_ndead--;      if (js.c_reaped < 0)	{#ifdef DEBUG	  itrace("delete_job (%d pgrp %d): js.c_reaped (%d) < 0 ndel = %d js.j_ndead = %d", job_index, temp->pgrp, js.c_reaped, ndel, js.j_ndead);#endif	  js.c_reaped = 0;	}    }  if (temp->deferred)    dispose_command (temp->deferred);  free (temp);  js.j_njobs--;  if (js.j_njobs == 0)    js.j_firstj = js.j_lastj = 0;  else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0)    reset_job_indices ();  if (job_index == js.j_current || job_index == js.j_previous)    reset_current ();}/* Must be called with SIGCHLD blocked. */voidnohup_job (job_index)     int job_index;{  register JOB *temp;  if (js.j_jobslots == 0)    return;  if (temp = jobs[job_index])    temp->flags |= J_NOHUP;}/* Get rid of the data structure associated with a process chain. */static intdiscard_pipeline (chain)     register PROCESS *chain;{  register PROCESS *this, *next;  int n;  this = chain;  n = 0;  do    {      next = this->next;      FREE (this->command);      free (this);      n++;      this = next;    }  while (this != chain);  return n;}/* Add this process to the chain being built in the_pipeline.   NAME is the command string that will be exec'ed later.   PID is the process id of the child. */static voidadd_process (name, pid)     char *name;     pid_t pid;{  PROCESS *t, *p;#if defined (RECYCLES_PIDS)  int j;  p = find_process (pid, 0, &j);  if (p)    {#  ifdef DEBUG      if (j == NO_JOB)	internal_warning (_("add_process: process %5ld (%s) in the_pipeline"), (long)p->pid, p->command);#  endif      if (PALIVE (p))        internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command);      p->running = PS_RECYCLED;		/* mark as recycled */    }#endif  t = (PROCESS *)xmalloc (sizeof (PROCESS));  t->next = the_pipeline;  t->pid = pid;  WSTATUS (t->status) = 0;  t->running = PS_RUNNING;  t->command = name;  the_pipeline = t;  if (t->next == 0)    t->next = t;  else    {      p = t->next;      while (p->next != t->next)	p = p->next;      p->next = t;    }}/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last   process in jobs[JID]->pipe.  Used by the lastpipe code. */voidappend_process (name, pid, status, jid)     char *name;     pid_t pid;     int status;     int jid;{  PROCESS *t, *p;  t = (PROCESS *)xmalloc (sizeof (PROCESS));  t->next = (PROCESS *)NULL;  t->pid = pid;  /* set process exit status using offset discovered by configure */  t->status = (status & 0xff) << WEXITSTATUS_OFFSET;  t->running = PS_DONE;  t->command = name;  js.c_reaped++;	/* XXX */  for (p = jobs[jid]->pipe; p->next != jobs[jid]->pipe; p = p->next)    ;  p->next = t;  t->next = jobs[jid]->pipe;}#if 0/* Take the last job and make it the first job.  Must be called with   SIGCHLD blocked. */introtate_the_pipeline (){  PROCESS *p;  if (the_pipeline->next == the_pipeline)    return;  for (p = the_pipeline; p->next != the_pipeline; p = p->next)    ;  the_pipeline = p;}/* Reverse the order of the processes in the_pipeline.  Must be called with   SIGCHLD blocked. */intreverse_the_pipeline (){  PROCESS *p, *n;  if (the_pipeline->next == the_pipeline)    return;  for (p = the_pipeline; p->next != the_pipeline; p = p->next)    ;  p->next = (PROCESS *)NULL;  n = REVERSE_LIST (the_pipeline, PROCESS *);  the_pipeline = n;  for (p = the_pipeline; p->next; p = p->next)    ;  p->next = the_pipeline;}#endif/* Map FUNC over the list of jobs.  If FUNC returns non-zero,   then it is time to stop mapping, and that is the return value   for map_over_jobs.  FUNC is called with a JOB, arg1, arg2,   and INDEX. */static intmap_over_jobs (func, arg1, arg2)     sh_job_map_func_t *func;     int arg1, arg2;{  register int i;  int result;  sigset_t set, oset;  if (js.j_jobslots == 0)    return 0;  BLOCK_CHILD (set, oset);  /* XXX could use js.j_firstj here */  for (i = result = 0; i < js.j_jobslots; i++)    {#if defined (DEBUG)      if (i < js.j_firstj && jobs[i])	itrace("map_over_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);      if (i > js.j_lastj && jobs[i])	itrace("map_over_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);#endif      if (jobs[i])	{	  result = (*func)(jobs[i], arg1, arg2, i);	  if (result)	    break;	}    }  UNBLOCK_CHILD (oset);  return (result);}/* Cause all the jobs in the current pipeline to exit. */voidterminate_current_pipeline (){  if (pipeline_pgrp && pipeline_pgrp != shell_pgrp)    {      killpg (pipeline_pgrp, SIGTERM);      killpg (pipeline_pgrp, SIGCONT);    }}/* Cause all stopped jobs to exit. */voidterminate_stopped_jobs (){  register int i;  /* XXX could use js.j_firstj here */  for (i = 0; i < js.j_jobslots; i++)    {      if (jobs[i] && STOPPED (i))	{	  killpg (jobs[i]->pgrp, SIGTERM);	  killpg (jobs[i]->pgrp, SIGCONT);	}    }}/* Cause all jobs, running or stopped, to receive a hangup signal.  If   a job is marked J_NOHUP, don't send the SIGHUP. */voidhangup_all_jobs (){  register int i;  /* XXX could use js.j_firstj here */  for (i = 0; i < js.j_jobslots; i++)    {      if (jobs[i])	{	  if  (jobs[i]->flags & J_NOHUP)	    continue;	  killpg (jobs[i]->pgrp, SIGHUP);	  if (STOPPED (i))	    killpg (jobs[i]->pgrp, SIGCONT);	}    }}voidkill_current_pipeline (){  stop_making_children ();  start_pipeline ();}/* Return the pipeline that PID belongs to.  Note that the pipeline   doesn't have to belong to a job.  Must be called with SIGCHLD blocked.   If JOBP is non-null, return the index of the job containing PID.  */static PROCESS *find_pipeline (pid, alive_only, jobp)     pid_t pid;     int alive_only;     int *jobp;		/* index into jobs list or NO_JOB */{  int job;  PROCESS *p;  /* See if this process is in the pipeline that we are building. */  if (jobp)    *jobp = NO_JOB;  if (the_pipeline)    {      p = the_pipeline;      do	{	  /* Return it if we found it.  Don't ever return a recycled pid. */	  if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))	    return (p);	  p = p->next;	}      while (p != the_pipeline);    }  job = find_job (pid, alive_only, &p);  if (jobp)    *jobp = job;  return (job == NO_JOB) ? (PROCESS *)NULL : jobs[job]->pipe;}/* Return the PROCESS * describing PID.  If JOBP is non-null return the index   into the jobs array of the job containing PID.  Must be called with   SIGCHLD blocked. */static PROCESS *find_process (pid, alive_only, jobp)     pid_t pid;     int alive_only;     int *jobp;		/* index into jobs list or NO_JOB */{  PROCESS *p;  p = find_pipeline (pid, alive_only, jobp);  while (p && p->pid != pid)    p = p->next;  return p;}/* Return the job index that PID belongs to, or NO_JOB if it doesn't   belong to any job.  Must be called with SIGCHLD blocked. */static intfind_job (pid, alive_only, procp)     pid_t pid;     int alive_only;     PROCESS **procp;{  register int i;  PROCESS *p;  /* XXX could use js.j_firstj here, and should check js.j_lastj */  for (i = 0; i < js.j_jobslots; i++)    {#if defined (DEBUG)      if (i < js.j_firstj && jobs[i])	itrace("find_job: job %d non-null before js.j_firstj (%d)", i, js.j_firstj);      if (i > js.j_lastj && jobs[i])	itrace("find_job: job %d non-null after js.j_lastj (%d)", i, js.j_lastj);#endif      if (jobs[i])	{	  p = jobs[i]->pipe;	  do	    {	      if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))		{		  if (procp)		    *procp = p;		  return (i);		}	      p = p->next;	    }	  while (p != jobs[i]->pipe);	}    }  return (NO_JOB);}/* Find a job given a PID.  If BLOCK is non-zero, block SIGCHLD as   required by find_job. */intget_job_by_pid (pid, block)     pid_t pid;     int block;{  int job;  sigset_t set, oset;  if (block)    BLOCK_CHILD (set, oset);  job = find_job (pid, 0, NULL);  if (block)    UNBLOCK_CHILD (oset);  return job;}/* Print descriptive information about the job with leader pid PID. */voiddescribe_pid (pid)     pid_t pid;{  int job;  sigset_t set, oset;  BLOCK_CHILD (set, oset);  job = find_job (pid, 0, NULL);  if (job != NO_JOB)    fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid);  else    programming_error (_("describe_pid: %ld: no such pid"), (long)pid);  UNBLOCK_CHILD (oset);}static char *j_strsignal (s)     int s;{  char *x;  x = strsignal (s);  if (x == 0)    {      x = retcode_name_buffer;      sprintf (x, _("Signal %d"), s);    }  return x;}static char *printable_job_status (j, p, format)     int j;     PROCESS *p;     int format;{  static char *temp;  int es;  temp = _("Done");  if (STOPPED (j) && format == 0)    {      if (posixly_correct == 0 || p == 0 || (WIFSTOPPED (p->status) == 0))	temp = _("Stopped");      else	{	  temp = retcode_name_buffer;	  sprintf (temp, _("Stopped(%s)"), signal_name (WSTOPSIG (p->status)));	}    }  else if (RUNNING (j))    temp = _("Running");  else    {      if (WIFSTOPPED (p->status))	temp = j_strsignal (WSTOPSIG (p->status));      else if (WIFSIGNALED (p->status))	temp = j_strsignal (WTERMSIG (p->status));      else if (WIFEXITED (p->status))	{	  temp = retcode_name_buffer;	  es = WEXITSTATUS (p->status);	  if (es == 0)	    strcpy (temp, _("Done"));	  else if (posixly_correct)	    sprintf (temp, _("Done(%d)"), es);	  else	    sprintf (temp, _("Exit %d"), es);	}      else	temp = _("Unknown status");    }  return temp;}/* This is the way to print out information on a job if you   know the index.  FORMAT is:    JLIST_NORMAL)   [1]+ Running	   emacs    JLIST_LONG  )   [1]+ 2378 Running      emacs    -1	  )   [1]+ 2378	      emacs    JLIST_NORMAL)   [1]+ Stopped	   ls | more    JLIST_LONG  )   [1]+ 2369 Stopped      ls			 2367	    | more    JLIST_PID_ONLY)	Just list the pid of the process group leader (really	the process group).    JLIST_CHANGED_ONLY)	Use format JLIST_NORMAL, but list only jobs about which	the user has not been notified. *//* Print status for pipeline P.  If JOB_INDEX is >= 0, it is the index into   the JOBS array corresponding to this pipeline.  FORMAT is as described   above.  Must be called with SIGCHLD blocked.   If you're printing a pipeline that's not in the jobs array, like the   current pipeline as it's being created, pass -1 for JOB_INDEX */static voidprint_pipeline (p, job_index, format, stream)     PROCESS *p;     int job_index, format;     FILE *stream;{  PROCESS *first, *last, *show;  int es, name_padding;  char *temp;  if (p == 0)    return;  first = last = p;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -