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

📄 process.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		sleep (1);		immediate_quit = 0;		continue;	      }#endif	    report_file_error ("writing to process", Fcons (proc, Qnil));	  }	buf += rv;	len -= rv;      }  else    {      XPROCESS (proc)->raw_status_low = Qnil;      XPROCESS (proc)->raw_status_high = Qnil;      XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil));      XSETINT (XPROCESS (proc)->tick, ++process_tick);      deactivate_process (proc);      error ("SIGPIPE raised on process %s; closed it", procname);    }}DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,  3, 3, 0,  "Send current contents of region as input to PROCESS.\n\PROCESS may be a process name.\n\Called from program, takes three arguments, PROCESS, START and END.")  (process, start, end)     Lisp_Object process, start, end;{  Lisp_Object proc;  int start1;  proc = get_process (process);  validate_region (&start, &end);  if (XINT (start) < GPT && XINT (end) > GPT)    move_gap (start);  start1 = XINT (start);  send_process (proc, &FETCH_CHAR (start1), XINT (end) - XINT (start));  return Qnil;}DEFUN ("process-send-string", Fprocess_send_string, Sprocess_send_string,  2, 2, 0,  "Send PROCESS the contents of STRING as input.\n\PROCESS may be a process name.")  (process, string)     Lisp_Object process, string;{  Lisp_Object proc;  CHECK_STRING (string, 1);  proc = get_process (process);  send_process (proc, XSTRING (string)->data, XSTRING (string)->size);  return Qnil;}/* send a signal number SIGNO to PROCESS.   CURRENT_GROUP means send to the process group that currently owns   the terminal being used to communicate with PROCESS.   This is used for various commands in shell mode.   If NOMSG is zero, insert signal-announcements into process's buffers   right away.  */process_send_signal (process, signo, current_group, nomsg)     Lisp_Object process;     int signo;     Lisp_Object current_group;     int nomsg;{  Lisp_Object proc;  register struct Lisp_Process *p;  int gid;  proc = get_process (process);  p = XPROCESS (proc);  if (!EQ (p->childp, Qt))    error ("Process %s is not a subprocess",	   XSTRING (p->name)->data);  if (!XFASTINT (p->infd))    error ("Process %s is not active",	   XSTRING (p->name)->data);  if (NULL (p->pty_flag))    current_group = Qnil;#ifdef TIOCGPGRP		/* Not sure about this! (fnf) */  /* If we are using pgrps, get a pgrp number and make it negative.  */  if (!NULL (current_group))    {      ioctl (XFASTINT (p->infd), TIOCGPGRP, &gid);      gid = - gid;    }  else    gid = - XFASTINT (p->pid);#else /* not using pgrps */  /* Can't select pgrps on this system, so we know that     the child itself heads the pgrp.  */  gid = - XFASTINT (p->pid);#endif /* not using pgrps */  switch (signo)    {#ifdef SIGCONT    case SIGCONT:      p->raw_status_low = Qnil;      p->raw_status_high = Qnil;      p->status = Qrun;      XSETINT (p->tick, ++process_tick);      if (!nomsg)	status_notify ();      break;#endif    case SIGINT:    case SIGQUIT:    case SIGKILL:      flush_pending_output (XFASTINT (p->infd));      break;    }  /* gid may be a pid, or minus a pgrp's number */#ifdef TIOCSIGSEND  if (!NULL (current_group))    ioctl (XFASTINT (p->infd), TIOCSIGSEND, signo);  else    {      gid = - XFASTINT (p->pid);      kill (gid, signo);    }#else /* no TIOCSIGSEND */#ifdef BSD  /* On bsd, [man says] kill does not accept a negative number to kill a pgrp.     Must do that differently.  */  killpg (-gid, signo);#else /* Not BSD.  */  kill (gid, signo);#endif /* Not BSD.  */#endif /* no TIOCSIGSEND */}DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0,  "Interrupt process PROCESS.  May be process or name of one.\n\Nil or no arg means current buffer's process.\n\Second arg CURRENT-GROUP non-nil means send signal to\n\the current process-group of the process's controlling terminal\n\rather than to the process's own process group.\n\If the process is a shell, this means interrupt current subjob\n\rather than the shell.")  (process, current_group)     Lisp_Object process, current_group;{  process_send_signal (process, SIGINT, current_group, 0);  return process;}DEFUN ("kill-process", Fkill_process, Skill_process, 0, 2, 0,  "Kill process PROCESS.  May be process or name of one.\n\See function interrupt-process for more details on usage.")  (process, current_group)     Lisp_Object process, current_group;{  process_send_signal (process, SIGKILL, current_group, 0);  return process;}DEFUN ("quit-process", Fquit_process, Squit_process, 0, 2, 0,  "Send QUIT signal to process PROCESS.  May be process or name of one.\n\See function interrupt-process for more details on usage.")  (process, current_group)     Lisp_Object process, current_group;{  process_send_signal (process, SIGQUIT, current_group, 0);  return process;}DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0,  "Stop process PROCESS.  May be process or name of one.\n\See function interrupt-process for more details on usage.")  (process, current_group)     Lisp_Object process, current_group;{#ifndef SIGTSTP  error ("no SIGTSTP support");#else  process_send_signal (process, SIGTSTP, current_group, 0);#endif  return process;}DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0,  "Continue process PROCESS.  May be process or name of one.\n\See function interrupt-process for more details on usage.")  (process, current_group)     Lisp_Object process, current_group;{#ifdef SIGCONT    process_send_signal (process, SIGCONT, current_group, 0);#else    error ("no SIGCONT support");#endif  return process;}DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,  "Make PROCESS see end-of-file in its input.\n\Eof comes after any text already sent to it.\n\nil or no arg means current buffer's process.")  (process)     Lisp_Object process;{  Lisp_Object proc;  proc = get_process (process);  /* Sending a zero-length record is supposed to mean eof     when TIOCREMOTE is turned on.  */#ifdef DID_REMOTE  {    char buf[1];    write (XFASTINT (XPROCESS (proc)->outfd), buf, 0);  }#else /* did not do TOICREMOTE */  send_process (proc, "\004", 1);#endif /* did not do TOICREMOTE */  return process;}/* Kill all processes associated with `buffer'. If `buffer' is nil, kill all processes  */kill_buffer_processes (buffer)     Lisp_Object buffer;{  Lisp_Object tail, proc;  for (tail = Vprocess_alist; XGCTYPE (tail) == Lisp_Cons;       tail = XCONS (tail)->cdr)    {      proc = XCONS (XCONS (tail)->car)->cdr;      if (XGCTYPE (proc) == Lisp_Process	  && (NULL (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))	{	  if (NETCONN_P (proc))	    deactivate_process (proc);	  else if (XFASTINT (XPROCESS (proc)->infd))	    process_send_signal (proc, SIGHUP, Qnil, 1);	}    }}/* On receipt of a signal that a child status has changed, loop asking about children with changed statuses until the system says there are no more.   All we do is change the status; we do not run sentinels or print notifications. That is saved for the next time keyboard input is done, in order to avoid timing errors.  *//** WARNING: this can be called during garbage collection. Therefore, it must not be fooled by the presence of mark bits in Lisp objects.  *//** USG WARNING:  Although it is not obvious from the documentation in signal(2), on a USG system the SIGCLD handler MUST NOT call signal() before executing at least one wait(), otherwise the handler will be called again, resulting in an infinite loop.  The relevant portion of the documentation reads "SIGCLD signals will be queued and the signal-catching function will be continually reentered until the queue is empty".  Invoking signal() causes the kernel to reexamine the SIGCLD queue.   Fred Fish, UniSoft Systems Inc. */sigchld_handler (signo)     int signo;{  int old_errno = errno;  Lisp_Object proc;  register struct Lisp_Process *p;#ifdef BSD4_1  extern int synch_process_pid;  extern int sigheld;  sigheld |= sigbit (SIGCHLD);#endif  while (1)    {      register int pid;      WAITTYPE w;      Lisp_Object tail;#ifdef WNOHANG#ifndef WUNTRACED#define WUNTRACED 0#endif /* no WUNTRACED */      /* Keep trying to get a status until we get a definitive result.  */      do 	{	  errno = 0;	  pid = wait3 (&w, WNOHANG | WUNTRACED, 0);	}      while (pid <= 0 && errno == EINTR);      if (pid <= 0)	{	  /* A real failure.  We have done all our job, so return.  */	  /* USG systems forget handlers when they are used;	     must reestablish each time */#ifdef USG	  signal (signo, sigchld_handler);   /* WARNING - must come after wait3() */#endif#ifdef  BSD4_1	  sigheld &= ~sigbit (SIGCHLD);	  sigrelse (SIGCHLD);#endif	  errno = old_errno;	  return;	}#else      pid = wait (&w);#endif /* no WNOHANG */#ifdef BSD4_1      if (synch_process_pid == pid)	synch_process_pid = 0;         /* Zero it to show process has died. */#endif      /* Find the process that signaled us, and record its status.  */      p = 0;      for (tail = Vprocess_alist; XSYMBOL (tail) != XSYMBOL (Qnil); tail = XCONS (tail)->cdr)	{	  proc = XCONS (XCONS (tail)->car)->cdr;	  p = XPROCESS (proc);	  if (EQ (p->childp, Qt) && XFASTINT (p->pid) == pid)	    break;	  p = 0;	}      /* If we don't recognize the pid number,	 look for a process being created.  */      if (p == 0)	for (tail = Vprocess_alist; XSYMBOL (tail) != XSYMBOL (Qnil); tail = XCONS (tail)->cdr)	  {	    proc = XCONS (XCONS (tail)->car)->cdr;	    p = XPROCESS (proc);	    if (XINT (p->pid) == -1)	      break;	    p = 0;	  }      /* Change the status of the process that was found.  */      if (p != 0)	{	  union { int i; WAITTYPE wt; } u;	  XSETINT (p->tick, ++process_tick);	  u.wt = w;	  XFASTINT (p->raw_status_low) = u.i & 0xffff;	  XFASTINT (p->raw_status_high) = u.i >> 16;	  /* If process has terminated, stop waiting for its output.  */	  if (WIFSIGNALED (w) || WIFEXITED (w))	    if (p->infd)	      FD_CLR (p->infd, &input_wait_mask);	}      /* On some systems, we must return right away.	 If any more processes want to signal us, we will	 get another signal.	 Otherwise (on systems that have WNOHANG), loop around	 to use up all the processes that have something to tell us.  */#if defined (USG) && ! (defined (HPUX) && defined (WNOHANG))#ifdef USG      signal (signo, sigchld_handler);#endif      errno = old_errno;      return;#endif /* USG, but not HPUX with WNOHANG */    }}/* Report all recent events of a change in process status   (either run the sentinel or output a message).   This is done while Emacs is waiting for keyboard input.  */status_notify (){  register Lisp_Object tail, proc, buffer;  for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail))    {      Lisp_Object symbol, msg;      register struct Lisp_Process *p;      proc = Fcdr (Fcar (tail));      p = XPROCESS (proc);      if (XINT (p->tick) != XINT (p->update_tick))	{	  struct gcpro gcpro1;	  XSETINT (p->update_tick, XINT (p->tick));	  /* If process is still active, read any output that remains.  */	  if (XFASTINT (p->infd))	    while (read_process_output (proc, XFASTINT (p->infd)) > 0);	  buffer = p->buffer;	  /* Get the text to use for the message.  */	  if (!NULL (p->raw_status_low))	    update_status (p);	  msg = status_message (p->status);	  GCPRO1 (msg);	  /* If process is terminated, deactivate it or delete it.  */	  symbol = p->status;	  if (XTYPE (p->status) == Lisp_Cons)	    symbol = XCONS (p->status)->car;	  if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)	      || EQ (symbol, Qclosed))	    {	      if (delete_exited_processes)		remove_process (proc);	      else		deactivate_process (proc);	    }	  UNGCPRO;	  /* Now output the message suitably.  */	  if (!NULL (p->sentinel))	    exec_sentinel (proc, msg);	  /* Don't bother with a message in the buffer	     when a process becomes runnable.  */	  else if (!EQ (symbol, Qrun) && !NULL (buffer))	    {	      Lisp_Object ro = XBUFFER (buffer)->read_only;	      Lisp_Object tem;	      struct buffer *old = current_buffer;	      int opoint;	      /* Avoid error if buffer is deleted		 (probably that's why the process is dead, too) */	      if (NULL (XBUFFER (buffer)->name))		continue;	      Fset_buffer (buffer);	      opoint = point;	      /* Insert new output into buffer		 at the current end-of-output marker,		 thus preserving logical ordering of input and output.  */	      if (XMARKER (p->mark)->buffer)		SET_PT (marker_position (p->mark));	      else		SET_PT (ZV);	      if (point <= opoint)		opoint += XSTRING (msg)->size + XSTRING (p->name)->size + 10;	      tem = current_buffer->read_only;	      current_buffer->read_only = Qnil;	      GCPRO1 (msg);	      InsStr ("\nProcess ");	      Finsert (1, &p->name);	      InsStr (" ");	      Finsert (1, &msg);	      current_buffer->read_only = tem;	      Fset_marker (p->mark, make_number (point), p->buffer);	      UNGCPRO;	      SET_PT (opoint);	      set_buffer_internal (old);	    }	}    } /* end for */  update_mode_lines++;  /* in case buffers use %s in mode-line-format */  redisplay_preserve_echo_area ();

⌨️ 快捷键说明

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