📄 process.c
字号:
register Lisp_Object val, tem, name1; register struct Lisp_Process *p; char suffix[10]; register int i; /* size of process structure includes the vector header, so deduct for that. But struct Lisp_Vector includes the first element, thus deducts too much, so add it back. */ val = Fmake_vector (make_number ((sizeof (struct Lisp_Process) - sizeof (struct Lisp_Vector) + sizeof (Lisp_Object)) / sizeof (Lisp_Object)), Qnil); XSETTYPE (val, Lisp_Process); p = XPROCESS (val); XFASTINT (p->infd) = 0; XFASTINT (p->outfd) = 0; XFASTINT (p->pid) = 0; XFASTINT (p->tick) = 0; XFASTINT (p->update_tick) = 0; p->raw_status_low = Qnil; p->raw_status_high = Qnil; p->status = Qrun; p->mark = Fmake_marker (); /* If name is already in use, modify it until it is unused. */ name1 = name; for (i = 1; ; i++) { tem = Fget_process (name1); if (NULL (tem)) break; sprintf (suffix, "<%d>", i); name1 = concat2 (name, build_string (suffix)); } name = name1; p->name = name; Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist); return val;}remove_process (proc) register Lisp_Object proc;{ register Lisp_Object pair; pair = Frassq (proc, Vprocess_alist); Vprocess_alist = Fdelq (pair, Vprocess_alist); Fset_marker (XPROCESS (proc)->mark, Qnil, Qnil); deactivate_process (proc);}DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0, "Return t if OBJECT is a process.") (obj) Lisp_Object obj;{ return XTYPE (obj) == Lisp_Process ? Qt : Qnil;}DEFUN ("get-process", Fget_process, Sget_process, 1, 1, 0, "Return the process named NAME, or nil if there is none.") (name) register Lisp_Object name;{ if (XTYPE (name) == Lisp_Process) return name; CHECK_STRING (name, 0); return Fcdr (Fassoc (name, Vprocess_alist));}DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, "Return the (or, a) process associated with BUFFER.\n\BUFFER may be a buffer or the name of one.") (name) register Lisp_Object name;{ register Lisp_Object buf, tail, proc; if (NULL (name)) return Qnil; buf = Fget_buffer (name); if (NULL (buf)) return Qnil; for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) { proc = Fcdr (Fcar (tail)); if (XTYPE (proc) == Lisp_Process && EQ (XPROCESS (proc)->buffer, buf)) return proc; } return Qnil;}/* This is how commands for the user decode process arguments */Lisp_Objectget_process (name) register Lisp_Object name;{ register Lisp_Object proc; if (NULL (name)) proc = Fget_buffer_process (Fcurrent_buffer ()); else { proc = Fget_process (name); if (NULL (proc)) proc = Fget_buffer_process (Fget_buffer (name)); } if (!NULL (proc)) return proc; if (NULL (name)) error ("Current buffer has no process"); else error ("Process %s does not exist", XSTRING (name)->data); /* NOTREACHED */}DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, "Delete PROCESS: kill it and forget about it immediately.\n\PROCESS may be a process or the name of one, or a buffer name.") (proc) register Lisp_Object proc;{ proc = get_process (proc); XPROCESS (proc)->raw_status_low = Qnil; XPROCESS (proc)->raw_status_high = Qnil; if (NETCONN_P (proc)) { XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (0), Qnil)); XSETINT (XPROCESS (proc)->tick, ++process_tick); } else if (XFASTINT (XPROCESS (proc)->infd)) { Fkill_process (proc, Qnil); /* Do this now, since remove_process will make sigchld_handler do nothing. */ XPROCESS (proc)->status = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); XSETINT (XPROCESS (proc)->tick, ++process_tick); status_notify (); } remove_process (proc); return Qnil;}DEFUN ("process-status", Fprocess_status, Sprocess_status, 1, 1, 0, "Return the status of PROCESS: a symbol, one of these:\n\run -- for a process that is running.\n\stop -- for a process stopped but continuable.\n\exit -- for a process that has exited.\n\signal -- for a process that has got a fatal signal.\n\open -- for a network stream connection that is open.\n\closed -- for a network stream connection that is closed.\n\nil -- if arg is a process name and no such process exists.")/* command -- for a command channel opened to Emacs by another process.\n\ external -- for an i/o channel opened to Emacs by another process.\n\ */ (proc) register Lisp_Object proc;{ register struct Lisp_Process *p; proc = Fget_process (proc); if (NULL (proc)) return proc; p = XPROCESS (proc); if (!NULL (p->raw_status_low)) update_status (p); if (XTYPE (p->status) == Lisp_Cons) return XCONS (p->status)->car; return p->status;}DEFUN ("process-exit-status", Fprocess_exit_status, Sprocess_exit_status, 1, 1, 0, "Return the exit status of PROCESS or the signal number that killed it.\n\If PROCESS has not yet exited or died, return 0.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); if (!NULL (XPROCESS (proc)->raw_status_low)) update_status (XPROCESS (proc)); if (XTYPE (XPROCESS (proc)->status) == Lisp_Cons) return XCONS (XCONS (XPROCESS (proc)->status)->cdr)->car; return make_number (0);}DEFUN ("process-id", Fprocess_id, Sprocess_id, 1, 1, 0, "Return the process id of PROCESS.\n\This is the pid of the Unix process which PROCESS uses or talks to.\n\For a network connection, this value is nil.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->pid;}DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0, "Return the name of PROCESS, as a string.\n\This is the name of the program invoked in PROCESS,\n\possibly modified to make it unique among process names.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->name;}DEFUN ("process-command", Fprocess_command, Sprocess_command, 1, 1, 0, "Return the command that was executed to start PROCESS.\n\This is a list of strings, the first string being the program executed\n\and the rest of the strings being the arguments given to it.\n\For a non-child channel, this is nil.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->command;}DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer, 2, 2, 0, "Set buffer associated with PROCESS to BUFFER (a buffer, or nil).") (proc, buffer) register Lisp_Object proc, buffer;{ CHECK_PROCESS (proc, 0); if (!NULL (buffer)) CHECK_BUFFER (buffer, 1); XPROCESS (proc)->buffer = buffer; return buffer;}DEFUN ("process-buffer", Fprocess_buffer, Sprocess_buffer, 1, 1, 0, "Return the buffer PROCESS is associated with.\n\Output from PROCESS is inserted in this buffer\n\unless PROCESS has a filter.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->buffer;}DEFUN ("process-mark", Fprocess_mark, Sprocess_mark, 1, 1, 0, "Return the marker for the end of the last output from PROCESS.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->mark;}DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, 2, 2, 0, "Give PROCESS the filter function FILTER; nil means no filter.\n\When a process has a filter, each time it does output\n\the entire string of output is passed to the filter.\n\The filter gets two arguments: the process and the string of output.\n\If the process has a filter, its buffer is not used for output.") (proc, filter) register Lisp_Object proc, filter;{ CHECK_PROCESS (proc, 0); XPROCESS (proc)->filter = filter; return filter;}DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, 1, 1, 0, "Returns the filter function of PROCESS; nil if none.\n\See set-process-filter for more info on filter functions.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->filter;}DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel, 2, 2, 0, "Give PROCESS the sentinel SENTINEL; nil for none.\n\The sentinel is called as a function when the process changes state.\n\It gets two arguments: the process, and a string describing the change.") (proc, sentinel) register Lisp_Object proc, sentinel;{ CHECK_PROCESS (proc, 0); XPROCESS (proc)->sentinel = sentinel; return sentinel;}DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, 1, 1, 0, "Return the sentinel of PROCESS; nil if none.\n\See set-process-sentinel for more info on sentinels.") (proc) register Lisp_Object proc;{ CHECK_PROCESS (proc, 0); return XPROCESS (proc)->sentinel;}DEFUN ("process-kill-without-query", Fprocess_kill_without_query, Sprocess_kill_without_query, 1, 2, 0, "Say no query needed if PROCESS is running when Emacs is exited.\n\Optional second argument if non-nil says to require a query.\n\Value is t if a query was formerly required.") (proc, value) register Lisp_Object proc, value;{ Lisp_Object tem; CHECK_PROCESS (proc, 0); tem = XPROCESS (proc)->kill_without_query; XPROCESS (proc)->kill_without_query = Fnull (value); return Fnull (tem);}Lisp_Objectlist_processes_1 (){ register Lisp_Object tail, tem; Lisp_Object proc, minspace, tem1; register struct buffer *old = current_buffer; register struct Lisp_Process *p; register int state; char tembuf[80]; XFASTINT (minspace) = 1; set_buffer_internal (XBUFFER (Vstandard_output)); Fbuffer_flush_undo (Vstandard_output); current_buffer->truncate_lines = Qt; write_string ("\Proc Status Buffer Command\n\---- ------ ------ -------\n", -1); for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) { Lisp_Object symbol; proc = Fcdr (Fcar (tail)); p = XPROCESS (proc); if (NULL (p->childp)) continue; Finsert (1, &p->name); Findent_to (make_number (13), minspace); if (!NULL (p->raw_status_low)) update_status (p); symbol = p->status; if (XTYPE (p->status) == Lisp_Cons) symbol = XCONS (p->status)->car; if (EQ (symbol, Qsignal)) { Lisp_Object tem; tem = Fcar (Fcdr (p->status)); if (XINT (tem) < NSIG) write_string (sys_siglist [XINT (tem)], -1); else Fprinc (symbol, Qnil); } else Fprinc (symbol, Qnil); if (EQ (symbol, Qexit)) { Lisp_Object tem; tem = Fcar (Fcdr (p->status)); if (XFASTINT (tem)) { sprintf (tembuf, " %d", XFASTINT (tem)); write_string (tembuf, -1); } } if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)) remove_process (proc); Findent_to (make_number (22), minspace); if (NULL (p->buffer)) InsStr ("(none)"); else if (NULL (XBUFFER (p->buffer)->name)) InsStr ("(Killed)"); else Finsert (1, &XBUFFER (p->buffer)->name); Findent_to (make_number (37), minspace); if (NETCONN_P (proc)) { sprintf (tembuf, "(network stream connection to %s)\n", XSTRING (p->childp)->data); InsStr (tembuf); } else { tem = p->command; while (1) { tem1 = Fcar (tem); Finsert (1, &tem1); tem = Fcdr (tem); if (NULL (tem)) break; InsStr (" "); } InsStr ("\n"); } } return Qnil;}DEFUN ("list-processes", Flist_processes, Slist_processes, 0, 0, "", "Display a list of all processes.\n\\(Any processes listed as Exited or Signaled are actually eliminated\n\after the listing is made.)") (){ internal_with_output_to_temp_buffer ("*Process List*", list_processes_1, Qnil); return Qnil;}DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, "Return a list of all processes.") (){ return Fmapcar (Qcdr, Vprocess_alist);}DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, "Start a program in a subprocess. Return the process object for it.\n\Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\NAME is name for process. It is modified if necessary to make it unique.\n\BUFFER is the buffer or (buffer-name) to associate with the process.\n\ Process output goes at end of that buffer, unless you specify\n\ an output stream or filter function to handle the output.\n\ BUFFER may be also nil, meaning that this process is not associated\n\ with any buffer\n\Third arg is program file name. It is searched for as in the shell.\n\Remaining arguments are strings to give program as arguments.") (nargs, args) int nargs; register Lisp_Object *args;{ Lisp_Object buffer, name, program, proc, tem; register unsigned char **new_argv; register int i; buffer = args[1]; if (!NULL (buffer)) buffer = Fget_buffer_create (buffer); name = args[0]; CHECK_STRING (name, 0); program = args[2]; CHECK_STRING (program, 2); new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); for (i = 3; i < nargs; i++) { tem = args[i]; CHECK_STRING (tem, i); new_argv[i - 2] = XSTRING (tem)->data; } new_argv[i - 2] = 0; new_argv[0] = XSTRING (program)->data; /* If program file name is not absolute, search our path for it */ if (new_argv[0][0] != '/')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -