20 |
Boston, MA 02111-1307, USA. */ |
Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
|
|
|
#define _GNU_SOURCE /* to get strsignal declared with glibc 2 */ |
|
23 |
#include <config.h> |
#include <config.h> |
24 |
#include <signal.h> |
#include <signal.h> |
25 |
|
|
102 |
#include <sys/sysmacros.h> /* for "minor" */ |
#include <sys/sysmacros.h> /* for "minor" */ |
103 |
#endif /* not IRIS */ |
#endif /* not IRIS */ |
104 |
|
|
105 |
|
#ifdef HAVE_SYS_WAIT |
106 |
|
#include <sys/wait.h> |
107 |
|
#endif |
108 |
|
|
109 |
#include "systime.h" |
#include "systime.h" |
110 |
#include "systty.h" |
#include "systty.h" |
111 |
|
|
132 |
Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; |
Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; |
133 |
Lisp_Object QClocal, QCremote, QCcoding; |
Lisp_Object QClocal, QCremote, QCcoding; |
134 |
Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; |
Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; |
135 |
Lisp_Object QCsentinel, QClog, QCoptions; |
Lisp_Object QCsentinel, QClog, QCoptions, QCplist; |
136 |
|
Lisp_Object QCfilter_multibyte; |
137 |
Lisp_Object Qlast_nonmenu_event; |
Lisp_Object Qlast_nonmenu_event; |
138 |
/* QCfamily is declared and initialized in xfaces.c, |
/* QCfamily is declared and initialized in xfaces.c, |
139 |
QCfilter in keyboard.c. */ |
QCfilter in keyboard.c. */ |
147 |
extern Lisp_Object QCfilter; |
extern Lisp_Object QCfilter; |
148 |
|
|
149 |
/* a process object is a network connection when its childp field is neither |
/* a process object is a network connection when its childp field is neither |
150 |
Qt nor Qnil but is instead a cons cell (HOSTNAME PORTNUM). */ |
Qt nor Qnil but is instead a property list (KEY VAL ...). */ |
151 |
|
|
152 |
#ifdef HAVE_SOCKETS |
#ifdef HAVE_SOCKETS |
153 |
#define NETCONN_P(p) (GC_CONSP (XPROCESS (p)->childp)) |
#define NETCONN_P(p) (GC_CONSP (XPROCESS (p)->childp)) |
334 |
extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system; |
extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system; |
335 |
|
|
336 |
#ifdef HAVE_PTYS |
#ifdef HAVE_PTYS |
337 |
|
#ifdef HAVE_PTY_H |
338 |
|
#include <pty.h> |
339 |
|
#endif |
340 |
/* The file name of the pty opened by allocate_pty. */ |
/* The file name of the pty opened by allocate_pty. */ |
341 |
|
|
342 |
static char pty_name[24]; |
static char pty_name[24]; |
358 |
p->raw_status_high = Qnil; |
p->raw_status_high = Qnil; |
359 |
} |
} |
360 |
|
|
361 |
/* Convert a process status word in Unix format to |
/* Convert a process status word in Unix format to |
362 |
the list that we use internally. */ |
the list that we use internally. */ |
363 |
|
|
364 |
Lisp_Object |
Lisp_Object |
407 |
|
|
408 |
/* Return a string describing a process status list. */ |
/* Return a string describing a process status list. */ |
409 |
|
|
410 |
Lisp_Object |
Lisp_Object |
411 |
status_message (status) |
status_message (status) |
412 |
Lisp_Object status; |
Lisp_Object status; |
413 |
{ |
{ |
426 |
signame = "unknown"; |
signame = "unknown"; |
427 |
string = build_string (signame); |
string = build_string (signame); |
428 |
string2 = build_string (coredump ? " (core dumped)\n" : "\n"); |
string2 = build_string (coredump ? " (core dumped)\n" : "\n"); |
429 |
XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); |
SSET (string, 0, DOWNCASE (SREF (string, 0))); |
430 |
return concat2 (string, string2); |
return concat2 (string, string2); |
431 |
} |
} |
432 |
else if (EQ (symbol, Qexit)) |
else if (EQ (symbol, Qexit)) |
587 |
|
|
588 |
deactivate_process (proc); |
deactivate_process (proc); |
589 |
} |
} |
590 |
|
|
591 |
|
/* Setup coding systems of PROCESS. */ |
592 |
|
|
593 |
|
void |
594 |
|
setup_process_coding_systems (process) |
595 |
|
Lisp_Object process; |
596 |
|
{ |
597 |
|
struct Lisp_Process *p = XPROCESS (process); |
598 |
|
int inch = XINT (p->infd); |
599 |
|
int outch = XINT (p->outfd); |
600 |
|
|
601 |
|
if (inch < 0 || outch < 0) |
602 |
|
return; |
603 |
|
|
604 |
|
if (!proc_decode_coding_system[inch]) |
605 |
|
proc_decode_coding_system[inch] |
606 |
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
607 |
|
setup_coding_system (p->decode_coding_system, |
608 |
|
proc_decode_coding_system[inch]); |
609 |
|
if (! NILP (p->filter)) |
610 |
|
{ |
611 |
|
if (NILP (p->filter_multibyte)) |
612 |
|
setup_raw_text_coding_system (proc_decode_coding_system[inch]); |
613 |
|
} |
614 |
|
else if (BUFFERP (p->buffer)) |
615 |
|
{ |
616 |
|
if (NILP (XBUFFER (p->buffer)->enable_multibyte_characters)) |
617 |
|
setup_raw_text_coding_system (proc_decode_coding_system[inch]); |
618 |
|
} |
619 |
|
|
620 |
|
if (!proc_encode_coding_system[outch]) |
621 |
|
proc_encode_coding_system[outch] |
622 |
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
623 |
|
setup_coding_system (p->encode_coding_system, |
624 |
|
proc_encode_coding_system[outch]); |
625 |
|
} |
626 |
|
|
627 |
DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0, |
DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0, |
628 |
doc: /* Return t if OBJECT is a process. */) |
doc: /* Return t if OBJECT is a process. */) |
680 |
if (NILP (obj)) |
if (NILP (obj)) |
681 |
obj = Fget_buffer (name); |
obj = Fget_buffer (name); |
682 |
if (NILP (obj)) |
if (NILP (obj)) |
683 |
error ("Process %s does not exist", XSTRING (name)->data); |
error ("Process %s does not exist", SDATA (name)); |
684 |
} |
} |
685 |
else if (NILP (name)) |
else if (NILP (name)) |
686 |
obj = Fcurrent_buffer (); |
obj = Fcurrent_buffer (); |
693 |
{ |
{ |
694 |
proc = Fget_buffer_process (obj); |
proc = Fget_buffer_process (obj); |
695 |
if (NILP (proc)) |
if (NILP (proc)) |
696 |
error ("Buffer %s has no process", XSTRING (XBUFFER (obj)->name)->data); |
error ("Buffer %s has no process", SDATA (XBUFFER (obj)->name)); |
697 |
} |
} |
698 |
else |
else |
699 |
{ |
{ |
722 |
{ |
{ |
723 |
Fkill_process (process, Qnil); |
Fkill_process (process, Qnil); |
724 |
/* Do this now, since remove_process will make sigchld_handler do nothing. */ |
/* Do this now, since remove_process will make sigchld_handler do nothing. */ |
725 |
XPROCESS (process)->status |
XPROCESS (process)->status |
726 |
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); |
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); |
727 |
XSETINT (XPROCESS (process)->tick, ++process_tick); |
XSETINT (XPROCESS (process)->tick, ++process_tick); |
728 |
status_notify (); |
status_notify (); |
853 |
p->buffer = buffer; |
p->buffer = buffer; |
854 |
if (NETCONN1_P (p)) |
if (NETCONN1_P (p)) |
855 |
p->childp = Fplist_put (p->childp, QCbuffer, buffer); |
p->childp = Fplist_put (p->childp, QCbuffer, buffer); |
856 |
|
setup_process_coding_systems (process); |
857 |
return buffer; |
return buffer; |
858 |
} |
} |
859 |
|
|
882 |
2, 2, 0, |
2, 2, 0, |
883 |
doc: /* Give PROCESS the filter function FILTER; nil means no filter. |
doc: /* Give PROCESS the filter function FILTER; nil means no filter. |
884 |
t means stop accepting output from the process. |
t means stop accepting output from the process. |
885 |
When a process has a filter, each time it does output |
|
886 |
the entire string of output is passed to the filter. |
When a process has a filter, its buffer is not used for output. |
887 |
|
Instead, each time it does output, the entire string of output is |
888 |
|
passed to the filter. |
889 |
|
|
890 |
The filter gets two arguments: the process and the string of output. |
The filter gets two arguments: the process and the string of output. |
891 |
If the process has a filter, its buffer is not used for output. */) |
The string argument is normally a multibyte string, except: |
892 |
|
- if the process' input coding system is no-conversion or raw-text, |
893 |
|
it is a unibyte string (the non-converted input), or else |
894 |
|
- if `default-enable-multibyte-characters' is nil, it is a unibyte |
895 |
|
string (the result of converting the decoded input multibyte |
896 |
|
string to unibyte with `string-make-unibyte'). */) |
897 |
(process, filter) |
(process, filter) |
898 |
register Lisp_Object process, filter; |
register Lisp_Object process, filter; |
899 |
{ |
{ |
900 |
struct Lisp_Process *p; |
struct Lisp_Process *p; |
901 |
|
|
902 |
CHECK_PROCESS (process); |
CHECK_PROCESS (process); |
903 |
p = XPROCESS (process); |
p = XPROCESS (process); |
904 |
|
|
909 |
(setq process (start-process ...)) |
(setq process (start-process ...)) |
910 |
(debug) |
(debug) |
911 |
(set-process-filter process ...) */ |
(set-process-filter process ...) */ |
912 |
|
|
913 |
if (XINT (p->infd) >= 0) |
if (XINT (p->infd) >= 0) |
914 |
{ |
{ |
915 |
if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) |
if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) |
924 |
FD_SET (XINT (p->infd), &non_keyboard_wait_mask); |
FD_SET (XINT (p->infd), &non_keyboard_wait_mask); |
925 |
} |
} |
926 |
} |
} |
927 |
|
|
928 |
p->filter = filter; |
p->filter = filter; |
929 |
if (NETCONN1_P (p)) |
if (NETCONN1_P (p)) |
930 |
p->childp = Fplist_put (p->childp, QCfilter, filter); |
p->childp = Fplist_put (p->childp, QCfilter, filter); |
931 |
|
setup_process_coding_systems (process); |
932 |
return filter; |
return filter; |
933 |
} |
} |
934 |
|
|
976 |
CHECK_PROCESS (process); |
CHECK_PROCESS (process); |
977 |
CHECK_NATNUM (height); |
CHECK_NATNUM (height); |
978 |
CHECK_NATNUM (width); |
CHECK_NATNUM (width); |
979 |
|
|
980 |
if (XINT (XPROCESS (process)->infd) < 0 |
if (XINT (XPROCESS (process)->infd) < 0 |
981 |
|| set_window_size (XINT (XPROCESS (process)->infd), |
|| set_window_size (XINT (XPROCESS (process)->infd), |
982 |
XINT (height), XINT (width)) <= 0) |
XINT (height), XINT (width)) <= 0) |
1072 |
#ifdef DATAGRAM_SOCKETS |
#ifdef DATAGRAM_SOCKETS |
1073 |
if (DATAGRAM_CONN_P (process) |
if (DATAGRAM_CONN_P (process) |
1074 |
&& (EQ (key, Qt) || EQ (key, QCremote))) |
&& (EQ (key, Qt) || EQ (key, QCremote))) |
1075 |
contact = Fplist_put (contact, QCremote, |
contact = Fplist_put (contact, QCremote, |
1076 |
Fprocess_datagram_address (process)); |
Fprocess_datagram_address (process)); |
1077 |
#endif |
#endif |
1078 |
|
|
1084 |
return Fplist_get (contact, key); |
return Fplist_get (contact, key); |
1085 |
} |
} |
1086 |
|
|
1087 |
|
DEFUN ("process-plist", Fprocess_plist, Sprocess_plist, |
1088 |
|
1, 1, 0, |
1089 |
|
doc: /* Return the plist of PROCESS. */) |
1090 |
|
(process) |
1091 |
|
register Lisp_Object process; |
1092 |
|
{ |
1093 |
|
CHECK_PROCESS (process); |
1094 |
|
return XPROCESS (process)->plist; |
1095 |
|
} |
1096 |
|
|
1097 |
|
DEFUN ("set-process-plist", Fset_process_plist, Sset_process_plist, |
1098 |
|
2, 2, 0, |
1099 |
|
doc: /* Replace the plist of PROCESS with PLIST. Returns PLIST. */) |
1100 |
|
(process, plist) |
1101 |
|
register Lisp_Object process, plist; |
1102 |
|
{ |
1103 |
|
CHECK_PROCESS (process); |
1104 |
|
CHECK_LIST (plist); |
1105 |
|
|
1106 |
|
XPROCESS (process)->plist = plist; |
1107 |
|
return plist; |
1108 |
|
} |
1109 |
|
|
1110 |
#if 0 /* Turned off because we don't currently record this info |
#if 0 /* Turned off because we don't currently record this info |
1111 |
in the process. Perhaps add it. */ |
in the process. Perhaps add it. */ |
1112 |
DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0, |
DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0, |
1119 |
return XPROCESS (process)->type; |
return XPROCESS (process)->type; |
1120 |
} |
} |
1121 |
#endif |
#endif |
1122 |
|
|
1123 |
|
#ifdef HAVE_SOCKETS |
1124 |
|
DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, |
1125 |
|
1, 2, 0, |
1126 |
|
doc: /* Convert network ADDRESS from internal format to a string. |
1127 |
|
If optional second argument OMIT-PORT is non-nil, don't include a port |
1128 |
|
number in the string; in this case, interpret a 4 element vector as an |
1129 |
|
IP address. Returns nil if format of ADDRESS is invalid. */) |
1130 |
|
(address, omit_port) |
1131 |
|
Lisp_Object address, omit_port; |
1132 |
|
{ |
1133 |
|
if (NILP (address)) |
1134 |
|
return Qnil; |
1135 |
|
|
1136 |
|
if (STRINGP (address)) /* AF_LOCAL */ |
1137 |
|
return address; |
1138 |
|
|
1139 |
|
if (VECTORP (address)) /* AF_INET */ |
1140 |
|
{ |
1141 |
|
register struct Lisp_Vector *p = XVECTOR (address); |
1142 |
|
Lisp_Object args[6]; |
1143 |
|
int nargs, i; |
1144 |
|
|
1145 |
|
if (!NILP (omit_port) && (p->size == 4 || p->size == 5)) |
1146 |
|
{ |
1147 |
|
args[0] = build_string ("%d.%d.%d.%d"); |
1148 |
|
nargs = 4; |
1149 |
|
} |
1150 |
|
else if (p->size == 5) |
1151 |
|
{ |
1152 |
|
args[0] = build_string ("%d.%d.%d.%d:%d"); |
1153 |
|
nargs = 5; |
1154 |
|
} |
1155 |
|
else |
1156 |
|
return Qnil; |
1157 |
|
|
1158 |
|
for (i = 0; i < nargs; i++) |
1159 |
|
args[i+1] = p->contents[i]; |
1160 |
|
return Fformat (nargs+1, args); |
1161 |
|
} |
1162 |
|
|
1163 |
|
if (CONSP (address)) |
1164 |
|
{ |
1165 |
|
Lisp_Object args[2]; |
1166 |
|
args[0] = build_string ("<Family %d>"); |
1167 |
|
args[1] = Fcar (address); |
1168 |
|
return Fformat (2, args); |
1169 |
|
|
1170 |
|
} |
1171 |
|
|
1172 |
|
return Qnil; |
1173 |
|
} |
1174 |
|
#endif |
1175 |
|
|
1176 |
Lisp_Object |
Lisp_Object |
1177 |
list_processes_1 (query_only) |
list_processes_1 (query_only) |
1199 |
if (!NILP (query_only) && !NILP (p->kill_without_query)) |
if (!NILP (query_only) && !NILP (p->kill_without_query)) |
1200 |
continue; |
continue; |
1201 |
if (STRINGP (p->name) |
if (STRINGP (p->name) |
1202 |
&& ( i = XSTRING (p->name)->size, (i > w_proc))) |
&& ( i = SCHARS (p->name), (i > w_proc))) |
1203 |
w_proc = i; |
w_proc = i; |
1204 |
if (!NILP (p->buffer)) |
if (!NILP (p->buffer)) |
1205 |
{ |
{ |
1206 |
if (NILP (XBUFFER (p->buffer)->name) && w_buffer < 8) |
if (NILP (XBUFFER (p->buffer)->name) && w_buffer < 8) |
1207 |
w_buffer = 8; /* (Killed) */ |
w_buffer = 8; /* (Killed) */ |
1208 |
else if ((i = XSTRING (XBUFFER (p->buffer)->name)->size, (i > w_buffer))) |
else if ((i = SCHARS (XBUFFER (p->buffer)->name), (i > w_buffer))) |
1209 |
w_buffer = i; |
w_buffer = i; |
1210 |
} |
} |
1211 |
if (STRINGP (p->tty_name) |
if (STRINGP (p->tty_name) |
1212 |
&& (i = XSTRING (p->tty_name)->size, (i > w_tty))) |
&& (i = SCHARS (p->tty_name), (i > w_tty))) |
1213 |
w_tty = i; |
w_tty = i; |
1214 |
} |
} |
1215 |
|
|
1271 |
if (CONSP (p->status)) |
if (CONSP (p->status)) |
1272 |
symbol = XCAR (p->status); |
symbol = XCAR (p->status); |
1273 |
|
|
1274 |
|
|
1275 |
if (EQ (symbol, Qsignal)) |
if (EQ (symbol, Qsignal)) |
1276 |
{ |
{ |
1277 |
Lisp_Object tem; |
Lisp_Object tem; |
1333 |
Lisp_Object port = Fplist_get (p->childp, QCservice); |
Lisp_Object port = Fplist_get (p->childp, QCservice); |
1334 |
if (INTEGERP (port)) |
if (INTEGERP (port)) |
1335 |
port = Fnumber_to_string (port); |
port = Fnumber_to_string (port); |
1336 |
|
if (NILP (port)) |
1337 |
|
port = Fformat_network_address (Fplist_get (p->childp, QClocal), Qnil); |
1338 |
sprintf (tembuf, "(network %s server on %s)\n", |
sprintf (tembuf, "(network %s server on %s)\n", |
1339 |
(DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"), |
(DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"), |
1340 |
XSTRING (port)->data); |
(STRINGP (port) ? (char *)SDATA (port) : "?")); |
1341 |
insert_string (tembuf); |
insert_string (tembuf); |
1342 |
} |
} |
1343 |
else if (NETCONN1_P (p)) |
else if (NETCONN1_P (p)) |
1351 |
if (INTEGERP (host)) |
if (INTEGERP (host)) |
1352 |
host = Fnumber_to_string (host); |
host = Fnumber_to_string (host); |
1353 |
} |
} |
1354 |
|
if (NILP (host)) |
1355 |
|
host = Fformat_network_address (Fplist_get (p->childp, QCremote), Qnil); |
1356 |
sprintf (tembuf, "(network %s connection to %s)\n", |
sprintf (tembuf, "(network %s connection to %s)\n", |
1357 |
(DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"), |
(DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"), |
1358 |
XSTRING (host)->data); |
(STRINGP (host) ? (char *)SDATA (host) : "?")); |
1359 |
insert_string (tembuf); |
insert_string (tembuf); |
1360 |
} |
} |
1361 |
else |
else |
1362 |
{ |
{ |
1363 |
tem = p->command; |
tem = p->command; |
1364 |
while (1) |
while (1) |
1425 |
register unsigned char **new_argv; |
register unsigned char **new_argv; |
1426 |
#endif |
#endif |
1427 |
register int i; |
register int i; |
1428 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
1429 |
|
|
1430 |
buffer = args[1]; |
buffer = args[1]; |
1431 |
if (!NILP (buffer)) |
if (!NILP (buffer)) |
1447 |
|
|
1448 |
GCPRO2 (buffer, current_dir); |
GCPRO2 (buffer, current_dir); |
1449 |
|
|
1450 |
current_dir |
current_dir |
1451 |
= expand_and_dir_to_file (Funhandled_file_name_directory (current_dir), |
= expand_and_dir_to_file (Funhandled_file_name_directory (current_dir), |
1452 |
Qnil); |
Qnil); |
1453 |
if (NILP (Ffile_accessible_directory_p (current_dir))) |
if (NILP (Ffile_accessible_directory_p (current_dir))) |
1472 |
record_unwind_protect (start_process_unwind, proc); |
record_unwind_protect (start_process_unwind, proc); |
1473 |
|
|
1474 |
XPROCESS (proc)->childp = Qt; |
XPROCESS (proc)->childp = Qt; |
1475 |
|
XPROCESS (proc)->plist = Qnil; |
1476 |
XPROCESS (proc)->command_channel_p = Qnil; |
XPROCESS (proc)->command_channel_p = Qnil; |
1477 |
XPROCESS (proc)->buffer = buffer; |
XPROCESS (proc)->buffer = buffer; |
1478 |
XPROCESS (proc)->sentinel = Qnil; |
XPROCESS (proc)->sentinel = Qnil; |
1479 |
XPROCESS (proc)->filter = Qnil; |
XPROCESS (proc)->filter = Qnil; |
1480 |
|
XPROCESS (proc)->filter_multibyte |
1481 |
|
= buffer_defaults.enable_multibyte_characters; |
1482 |
XPROCESS (proc)->command = Flist (nargs - 2, args + 2); |
XPROCESS (proc)->command = Flist (nargs - 2, args + 2); |
1483 |
|
|
1484 |
/* Make the process marker point into the process buffer (if any). */ |
/* Make the process marker point into the process buffer (if any). */ |
1536 |
#ifdef VMS |
#ifdef VMS |
1537 |
/* Make a one member argv with all args concatenated |
/* Make a one member argv with all args concatenated |
1538 |
together separated by a blank. */ |
together separated by a blank. */ |
1539 |
len = STRING_BYTES (XSTRING (program)) + 2; |
len = SBYTES (program) + 2; |
1540 |
for (i = 3; i < nargs; i++) |
for (i = 3; i < nargs; i++) |
1541 |
{ |
{ |
1542 |
tem = args[i]; |
tem = args[i]; |
1543 |
CHECK_STRING (tem); |
CHECK_STRING (tem); |
1544 |
len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */ |
len += SBYTES (tem) + 1; /* count the blank */ |
1545 |
} |
} |
1546 |
new_argv = (unsigned char *) alloca (len); |
new_argv = (unsigned char *) alloca (len); |
1547 |
strcpy (new_argv, XSTRING (program)->data); |
strcpy (new_argv, SDATA (program)); |
1548 |
for (i = 3; i < nargs; i++) |
for (i = 3; i < nargs; i++) |
1549 |
{ |
{ |
1550 |
tem = args[i]; |
tem = args[i]; |
1551 |
CHECK_STRING (tem); |
CHECK_STRING (tem); |
1552 |
strcat (new_argv, " "); |
strcat (new_argv, " "); |
1553 |
strcat (new_argv, XSTRING (tem)->data); |
strcat (new_argv, SDATA (tem)); |
1554 |
} |
} |
1555 |
/* Need to add code here to check for program existence on VMS */ |
/* Need to add code here to check for program existence on VMS */ |
1556 |
|
|
1557 |
#else /* not VMS */ |
#else /* not VMS */ |
1558 |
new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); |
new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); |
1559 |
|
|
1560 |
/* If program file name is not absolute, search our path for it */ |
/* If program file name is not absolute, search our path for it. |
1561 |
if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0]) |
Put the name we will really use in TEM. */ |
1562 |
&& !(XSTRING (program)->size > 1 |
if (!IS_DIRECTORY_SEP (SREF (program, 0)) |
1563 |
&& IS_DEVICE_SEP (XSTRING (program)->data[1]))) |
&& !(SCHARS (program) > 1 |
1564 |
|
&& IS_DEVICE_SEP (SREF (program, 1)))) |
1565 |
{ |
{ |
1566 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
1567 |
|
|
1572 |
if (NILP (tem)) |
if (NILP (tem)) |
1573 |
report_file_error ("Searching for program", Fcons (program, Qnil)); |
report_file_error ("Searching for program", Fcons (program, Qnil)); |
1574 |
tem = Fexpand_file_name (tem, Qnil); |
tem = Fexpand_file_name (tem, Qnil); |
|
tem = ENCODE_FILE (tem); |
|
|
new_argv[0] = XSTRING (tem)->data; |
|
1575 |
} |
} |
1576 |
else |
else |
1577 |
{ |
{ |
1578 |
if (!NILP (Ffile_directory_p (program))) |
if (!NILP (Ffile_directory_p (program))) |
1579 |
error ("Specified program for new process is a directory"); |
error ("Specified program for new process is a directory"); |
1580 |
|
tem = program; |
|
tem = ENCODE_FILE (program); |
|
|
new_argv[0] = XSTRING (tem)->data; |
|
1581 |
} |
} |
1582 |
|
|
1583 |
|
/* If program file name starts with /: for quoting a magic name, |
1584 |
|
discard that. */ |
1585 |
|
if (SBYTES (tem) > 2 && SREF (tem, 0) == '/' |
1586 |
|
&& SREF (tem, 1) == ':') |
1587 |
|
tem = Fsubstring (tem, make_number (2), Qnil); |
1588 |
|
|
1589 |
|
/* Encode the file name and put it in NEW_ARGV. |
1590 |
|
That's where the child will use it to execute the program. */ |
1591 |
|
tem = ENCODE_FILE (tem); |
1592 |
|
new_argv[0] = SDATA (tem); |
1593 |
|
|
1594 |
/* Here we encode arguments by the coding system used for sending |
/* Here we encode arguments by the coding system used for sending |
1595 |
data to the process. We don't support using different coding |
data to the process. We don't support using different coding |
1596 |
systems for encoding arguments and for encoding data sent to the |
systems for encoding arguments and for encoding data sent to the |
1603 |
if (STRING_MULTIBYTE (tem)) |
if (STRING_MULTIBYTE (tem)) |
1604 |
tem = (code_convert_string_norecord |
tem = (code_convert_string_norecord |
1605 |
(tem, XPROCESS (proc)->encode_coding_system, 1)); |
(tem, XPROCESS (proc)->encode_coding_system, 1)); |
1606 |
new_argv[i - 2] = XSTRING (tem)->data; |
new_argv[i - 2] = SDATA (tem); |
1607 |
} |
} |
1608 |
new_argv[i - 2] = 0; |
new_argv[i - 2] = 0; |
1609 |
#endif /* not VMS */ |
#endif /* not VMS */ |
1706 |
|
|
1707 |
if (inchannel >= 0) |
if (inchannel >= 0) |
1708 |
{ |
{ |
1709 |
#ifndef USG |
#if ! defined (USG) || defined (USG_SUBTTY_WORKS) |
1710 |
/* On USG systems it does not work to open the pty's tty here |
/* On most USG systems it does not work to open the pty's tty here, |
1711 |
and then close and reopen it in the child. */ |
then close it and reopen it in the child. */ |
1712 |
#ifdef O_NOCTTY |
#ifdef O_NOCTTY |
1713 |
/* Don't let this terminal become our controlling terminal |
/* Don't let this terminal become our controlling terminal |
1714 |
(in case we don't have one). */ |
(in case we don't have one). */ |
1720 |
report_file_error ("Opening pty", Qnil); |
report_file_error ("Opening pty", Qnil); |
1721 |
#else |
#else |
1722 |
forkin = forkout = -1; |
forkin = forkout = -1; |
1723 |
#endif /* not USG */ |
#endif /* not USG, or USG_SUBTTY_WORKS */ |
1724 |
pty_flag = 1; |
pty_flag = 1; |
1725 |
} |
} |
1726 |
else |
else |
1782 |
chan_process[inchannel] = process; |
chan_process[inchannel] = process; |
1783 |
XSETINT (XPROCESS (process)->infd, inchannel); |
XSETINT (XPROCESS (process)->infd, inchannel); |
1784 |
XSETINT (XPROCESS (process)->outfd, outchannel); |
XSETINT (XPROCESS (process)->outfd, outchannel); |
1785 |
/* Record the tty descriptor used in the subprocess. */ |
|
1786 |
if (forkin < 0) |
/* Previously we recorded the tty descriptor used in the subprocess. |
1787 |
XPROCESS (process)->subtty = Qnil; |
It was only used for getting the foreground tty process, so now |
1788 |
else |
we just reopen the device (see emacs_get_tty_pgrp) as this is |
1789 |
XSETFASTINT (XPROCESS (process)->subtty, forkin); |
more portable (see USG_SUBTTY_WORKS above). */ |
1790 |
|
|
1791 |
XPROCESS (process)->pty_flag = (pty_flag ? Qt : Qnil); |
XPROCESS (process)->pty_flag = (pty_flag ? Qt : Qnil); |
1792 |
XPROCESS (process)->status = Qrun; |
XPROCESS (process)->status = Qrun; |
1793 |
if (!proc_decode_coding_system[inchannel]) |
setup_process_coding_systems (process); |
|
proc_decode_coding_system[inchannel] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (XPROCESS (process)->decode_coding_system, |
|
|
proc_decode_coding_system[inchannel]); |
|
|
if (!proc_encode_coding_system[outchannel]) |
|
|
proc_encode_coding_system[outchannel] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (XPROCESS (process)->encode_coding_system, |
|
|
proc_encode_coding_system[outchannel]); |
|
1794 |
|
|
1795 |
/* Delay interrupts until we have a chance to store |
/* Delay interrupts until we have a chance to store |
1796 |
the new fork's pid in its process structure */ |
the new fork's pid in its process structure */ |
1842 |
XSETINT (XPROCESS (process)->pid, -1); |
XSETINT (XPROCESS (process)->pid, -1); |
1843 |
|
|
1844 |
BLOCK_INPUT; |
BLOCK_INPUT; |
1845 |
|
|
1846 |
{ |
{ |
1847 |
/* child_setup must clobber environ on systems with true vfork. |
/* child_setup must clobber environ on systems with true vfork. |
1848 |
Protect it from permanent change. */ |
Protect it from permanent change. */ |
1907 |
} |
} |
1908 |
#endif |
#endif |
1909 |
#endif |
#endif |
1910 |
#ifdef TIOCNOTTY |
#ifdef TIOCNOTTY |
1911 |
/* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you |
/* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you |
1912 |
can do TIOCSPGRP only to the process's controlling tty. */ |
can do TIOCSPGRP only to the process's controlling tty. */ |
1913 |
if (pty_flag) |
if (pty_flag) |
1914 |
{ |
{ |
1915 |
/* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? |
/* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? |
1916 |
I can't test it since I don't have 4.3. */ |
I can't test it since I don't have 4.3. */ |
1917 |
int j = emacs_open ("/dev/tty", O_RDWR, 0); |
int j = emacs_open ("/dev/tty", O_RDWR, 0); |
1918 |
ioctl (j, TIOCNOTTY, 0); |
ioctl (j, TIOCNOTTY, 0); |
2007 |
#ifdef WINDOWSNT |
#ifdef WINDOWSNT |
2008 |
pid = child_setup (xforkin, xforkout, xforkout, |
pid = child_setup (xforkin, xforkout, xforkout, |
2009 |
new_argv, 1, current_dir); |
new_argv, 1, current_dir); |
2010 |
#else /* not WINDOWSNT */ |
#else /* not WINDOWSNT */ |
2011 |
child_setup (xforkin, xforkout, xforkout, |
child_setup (xforkin, xforkout, xforkout, |
2012 |
new_argv, 1, current_dir); |
new_argv, 1, current_dir); |
2013 |
#endif /* not WINDOWSNT */ |
#endif /* not WINDOWSNT */ |
2040 |
{ |
{ |
2041 |
struct atimer *timer; |
struct atimer *timer; |
2042 |
EMACS_TIME offset; |
EMACS_TIME offset; |
2043 |
|
|
2044 |
stop_polling (); |
stop_polling (); |
2045 |
EMACS_SET_SECS_USECS (offset, 1, 0); |
EMACS_SET_SECS_USECS (offset, 1, 0); |
2046 |
timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0); |
timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0); |
2047 |
|
|
|
XPROCESS (process)->subtty = Qnil; |
|
2048 |
if (forkin >= 0) |
if (forkin >= 0) |
2049 |
emacs_close (forkin); |
emacs_close (forkin); |
2050 |
|
|
2051 |
cancel_atimer (timer); |
cancel_atimer (timer); |
2052 |
start_polling (); |
start_polling (); |
2053 |
} |
} |
2054 |
|
|
2055 |
if (forkin != forkout && forkout >= 0) |
if (forkin != forkout && forkout >= 0) |
2056 |
emacs_close (forkout); |
emacs_close (forkout); |
2057 |
|
|
2227 |
if (family == AF_LOCAL) |
if (family == AF_LOCAL) |
2228 |
{ |
{ |
2229 |
struct sockaddr_un *sockun = (struct sockaddr_un *) sa; |
struct sockaddr_un *sockun = (struct sockaddr_un *) sa; |
2230 |
cp = XSTRING (address)->data; |
cp = SDATA (address); |
2231 |
for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++) |
for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++) |
2232 |
sockun->sun_path[i] = *cp++; |
sockun->sun_path[i] = *cp++; |
2233 |
} |
} |
2292 |
|
|
2293 |
static struct socket_options { |
static struct socket_options { |
2294 |
/* The name of this option. Should be lowercase version of option |
/* The name of this option. Should be lowercase version of option |
2295 |
name without SO_ prefix. */ |
name without SO_ prefix. */ |
2296 |
char *name; |
char *name; |
2297 |
/* Length of name. */ |
/* Length of name. */ |
2298 |
int nlen; |
int nlen; |
2367 |
opt = XCAR (opt); |
opt = XCAR (opt); |
2368 |
} |
} |
2369 |
if (STRINGP (opt)) |
if (STRINGP (opt)) |
2370 |
name = (char *) XSTRING (opt)->data; |
name = (char *) SDATA (opt); |
2371 |
else if (SYMBOLP (opt)) |
else if (SYMBOLP (opt)) |
2372 |
name = (char *) XSTRING (SYMBOL_NAME (opt))->data; |
name = (char *) SDATA (SYMBOL_NAME (opt)); |
2373 |
else { |
else { |
2374 |
error ("Mal-formed option list"); |
error ("Mal-formed option list"); |
2375 |
return 0; |
return 0; |
2435 |
if (NILP (val)) |
if (NILP (val)) |
2436 |
arg = ""; |
arg = ""; |
2437 |
else if (STRINGP (val)) |
else if (STRINGP (val)) |
2438 |
arg = (char *) XSTRING (val)->data; |
arg = (char *) SDATA (val); |
2439 |
else if (XSYMBOL (val)) |
else if (XSYMBOL (val)) |
2440 |
arg = (char *) XSTRING (SYMBOL_NAME (val))->data; |
arg = (char *) SDATA (SYMBOL_NAME (val)); |
2441 |
else |
else |
2442 |
error ("Invalid argument to %s option", name); |
error ("Invalid argument to %s option", name); |
2443 |
} |
} |
2444 |
ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
2445 |
arg, strlen (arg)); |
arg, strlen (arg)); |
2446 |
} |
} |
2447 |
|
|
2448 |
#ifdef SO_LINGER |
#ifdef SO_LINGER |
2449 |
case SOPT_LINGER: |
case SOPT_LINGER: |
2450 |
{ |
{ |
2451 |
struct linger linger; |
struct linger linger; |
2487 |
|
|
2488 |
DEFUN ("set-network-process-options", |
DEFUN ("set-network-process-options", |
2489 |
Fset_network_process_options, Sset_network_process_options, |
Fset_network_process_options, Sset_network_process_options, |
2490 |
1, MANY, 0, |
1, MANY, 0, |
2491 |
doc: /* Set one or more options for network process PROCESS. |
doc: /* Set one or more options for network process PROCESS. |
2492 |
Each option is either a string "OPT=VALUE" or a cons (OPT . VALUE). |
Each option is either a string "OPT=VALUE" or a cons (OPT . VALUE). |
2493 |
A boolean value is false if it either zero or nil, true otherwise. |
A boolean value is false if it either zero or nil, true otherwise. |
2498 |
bindtodevice=NAME -- bind to interface NAME, or remove binding if nil. |
bindtodevice=NAME -- bind to interface NAME, or remove binding if nil. |
2499 |
broadcast=BOOL -- Allow send and receive of datagram broadcasts. |
broadcast=BOOL -- Allow send and receive of datagram broadcasts. |
2500 |
dontroute=BOOL -- Only send to directly connected hosts. |
dontroute=BOOL -- Only send to directly connected hosts. |
2501 |
keepalive=BOOL -- Send keep-alive messages on network stream. |
keepalive=BOOL -- Send keep-alive messages on network stream. |
2502 |
linger=BOOL or TIMEOUT -- Send queued messages before closing. |
linger=BOOL or TIMEOUT -- Send queued messages before closing. |
2503 |
oobinline=BOOL -- Place out-of-band data in receive data stream. |
oobinline=BOOL -- Place out-of-band data in receive data stream. |
2504 |
priority=INT -- Set protocol defined priority for sent packets. |
priority=INT -- Set protocol defined priority for sent packets. |
2505 |
reuseaddr=BOOL -- Allow reusing a recently used address. |
reuseaddr=BOOL -- Allow reusing a recently used address. |
2506 |
|
|
2539 |
connection has no PID; you cannot signal it. All you can do is |
connection has no PID; you cannot signal it. All you can do is |
2540 |
stop/continue it and deactivate/close it via delete-process */ |
stop/continue it and deactivate/close it via delete-process */ |
2541 |
|
|
2542 |
DEFUN ("make-network-process", Fmake_network_process, Smake_network_process, |
DEFUN ("make-network-process", Fmake_network_process, Smake_network_process, |
2543 |
0, MANY, 0, |
0, MANY, 0, |
2544 |
doc: /* Create and return a network server or client process. |
doc: /* Create and return a network server or client process. |
2545 |
|
|
2546 |
In Emacs, network connections are represented by process objects, so |
In Emacs, network connections are represented by process objects, so |
2622 |
|
|
2623 |
:filter FILTER -- Install FILTER as the process filter. |
:filter FILTER -- Install FILTER as the process filter. |
2624 |
|
|
2625 |
|
:filter-multibyte BOOL -- If BOOL is non-nil, strings given to the |
2626 |
|
process filter are multibyte, otherwise they are unibyte. |
2627 |
|
If this keyword is not specified, the strings are multibyte iff |
2628 |
|
`default-enable-multibyte-characters' is non-nil. |
2629 |
|
|
2630 |
:sentinel SENTINEL -- Install SENTINEL as the process sentinel. |
:sentinel SENTINEL -- Install SENTINEL as the process sentinel. |
2631 |
|
|
2632 |
:log LOG -- Install LOG as the server process log function. This |
:log LOG -- Install LOG as the server process log function. This |
2633 |
function is called as when the server accepts a network connection from a |
function is called when the server accepts a network connection from a |
2634 |
client. The arguments are SERVER, CLIENT, and MESSAGE, where SERVER |
client. The arguments are SERVER, CLIENT, and MESSAGE, where SERVER |
2635 |
is the server process, CLIENT is the new process for the connection, |
is the server process, CLIENT is the new process for the connection, |
2636 |
and MESSAGE is a string. |
and MESSAGE is a string. |
2637 |
|
|
2638 |
|
:plist PLIST -- Install PLIST as the new process' initial plist. |
2639 |
|
|
2640 |
:server BOOL -- if BOOL is non-nil, create a server process for the |
:server BOOL -- if BOOL is non-nil, create a server process for the |
2641 |
specified FAMILY, SERVICE, and connection type (stream or datagram). |
specified FAMILY, SERVICE, and connection type (stream or datagram). |
2642 |
Default is a client process. |
Default is a client process. |
2643 |
|
|
2644 |
A server process will listen for and accept connections from |
A server process will listen for and accept connections from |
2645 |
clients. When a client connection is accepted, a new network process |
clients. When a client connection is accepted, a new network process |
2646 |
is created for the connection with the following parameters: |
is created for the connection with the following parameters: |
2647 |
- The client's process name is constructed by concatenating the server |
- The client's process name is constructed by concatenating the server |
2648 |
process' NAME and a client identification string. |
process' NAME and a client identification string. |
2649 |
- If the FILTER argument is non-nil, the client process will not get a |
- If the FILTER argument is non-nil, the client process will not get a |
2650 |
separate process buffer; otherwise, the client's process buffer is a newly |
separate process buffer; otherwise, the client's process buffer is a newly |
2651 |
created buffer named after the server process' BUFFER name or process |
created buffer named after the server process' BUFFER name or process |
2652 |
NAME concatenated with the client identification string. |
NAME concatenated with the client identification string. |
2653 |
- The connection type and the process filter and sentinel parameters are |
- The connection type and the process filter and sentinel parameters are |
2654 |
inherited from the server process' TYPE, FILTER and SENTINEL. |
inherited from the server process' TYPE, FILTER and SENTINEL. |
2655 |
- The client process' contact info is set according to the client's |
- The client process' contact info is set according to the client's |
2656 |
addressing information (typically an IP address and a port number). |
addressing information (typically an IP address and a port number). |
2657 |
|
- The client process' plist is initialized from the server's plist. |
2658 |
|
|
2659 |
Notice that the FILTER and SENTINEL args are never used directly by |
Notice that the FILTER and SENTINEL args are never used directly by |
2660 |
the server process. Also, the BUFFER argument is not used directly by |
the server process. Also, the BUFFER argument is not used directly by |
2661 |
the server process, but via `network-server-log-function' hook, a log |
the server process, but via the optional :log function, accepted (and |
2662 |
of the accepted (and failed) connections may be recorded in the server |
failed) connections may be logged in the server process' buffer. |
2663 |
process' buffer. |
|
2664 |
|
The original argument list, modified with the actual connection |
2665 |
|
information, is available via the `process-contact' function. |
2666 |
|
|
2667 |
usage: (make-network-process &rest ARGS) */) |
usage: (make-network-process &rest ARGS) */) |
2668 |
(nargs, args) |
(nargs, args) |
2697 |
int s = -1, outch, inch; |
int s = -1, outch, inch; |
2698 |
struct gcpro gcpro1; |
struct gcpro gcpro1; |
2699 |
int retry = 0; |
int retry = 0; |
2700 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
2701 |
int count1; |
int count1; |
2702 |
Lisp_Object QCaddress; /* one of QClocal or QCremote */ |
Lisp_Object QCaddress; /* one of QClocal or QCremote */ |
2703 |
Lisp_Object tem; |
Lisp_Object tem; |
2769 |
/* Let's handle TERM before things get complicated ... */ |
/* Let's handle TERM before things get complicated ... */ |
2770 |
host = Fplist_get (contact, QChost); |
host = Fplist_get (contact, QChost); |
2771 |
CHECK_STRING (host); |
CHECK_STRING (host); |
2772 |
|
|
2773 |
service = Fplist_get (contact, QCservice); |
service = Fplist_get (contact, QCservice); |
2774 |
if (INTEGERP (service)) |
if (INTEGERP (service)) |
2775 |
port = htons ((unsigned short) XINT (service)); |
port = htons ((unsigned short) XINT (service)); |
2777 |
{ |
{ |
2778 |
struct servent *svc_info; |
struct servent *svc_info; |
2779 |
CHECK_STRING (service); |
CHECK_STRING (service); |
2780 |
svc_info = getservbyname (XSTRING (service)->data, "tcp"); |
svc_info = getservbyname (SDATA (service), "tcp"); |
2781 |
if (svc_info == 0) |
if (svc_info == 0) |
2782 |
error ("Unknown service: %s", XSTRING (service)->data); |
error ("Unknown service: %s", SDATA (service)); |
2783 |
port = svc_info->s_port; |
port = svc_info->s_port; |
2784 |
} |
} |
2785 |
|
|
2786 |
s = connect_server (0); |
s = connect_server (0); |
2787 |
if (s < 0) |
if (s < 0) |
2788 |
report_file_error ("error creating socket", Fcons (name, Qnil)); |
report_file_error ("error creating socket", Fcons (name, Qnil)); |
2789 |
send_command (s, C_PORT, 0, "%s:%d", XSTRING (host)->data, ntohs (port)); |
send_command (s, C_PORT, 0, "%s:%d", SDATA (host), ntohs (port)); |
2790 |
send_command (s, C_DUMB, 1, 0); |
send_command (s, C_DUMB, 1, 0); |
2791 |
|
|
2792 |
#else /* not TERM */ |
#else /* not TERM */ |
2839 |
CHECK_STRING (service); |
CHECK_STRING (service); |
2840 |
bzero (&address_un, sizeof address_un); |
bzero (&address_un, sizeof address_un); |
2841 |
address_un.sun_family = AF_LOCAL; |
address_un.sun_family = AF_LOCAL; |
2842 |
strncpy (address_un.sun_path, XSTRING (service)->data, sizeof address_un.sun_path); |
strncpy (address_un.sun_path, SDATA (service), sizeof address_un.sun_path); |
2843 |
ai.ai_addr = (struct sockaddr *) &address_un; |
ai.ai_addr = (struct sockaddr *) &address_un; |
2844 |
ai.ai_addrlen = sizeof address_un; |
ai.ai_addrlen = sizeof address_un; |
2845 |
goto open_socket; |
goto open_socket; |
2884 |
else |
else |
2885 |
{ |
{ |
2886 |
CHECK_STRING (service); |
CHECK_STRING (service); |
2887 |
portstring = XSTRING (service)->data; |
portstring = SDATA (service); |
2888 |
} |
} |
2889 |
|
|
2890 |
immediate_quit = 1; |
immediate_quit = 1; |
2894 |
hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family; |
hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family; |
2895 |
hints.ai_socktype = socktype; |
hints.ai_socktype = socktype; |
2896 |
hints.ai_protocol = 0; |
hints.ai_protocol = 0; |
2897 |
ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); |
ret = getaddrinfo (SDATA (host), portstring, &hints, &res); |
2898 |
if (ret) |
if (ret) |
2899 |
#ifdef HAVE_GAI_STRERROR |
#ifdef HAVE_GAI_STRERROR |
2900 |
error ("%s/%s %s", XSTRING (host)->data, portstring, gai_strerror(ret)); |
error ("%s/%s %s", SDATA (host), portstring, gai_strerror(ret)); |
2901 |
#else |
#else |
2902 |
error ("%s/%s getaddrinfo error %d", XSTRING (host)->data, portstring, ret); |
error ("%s/%s getaddrinfo error %d", SDATA (host), portstring, ret); |
2903 |
#endif |
#endif |
2904 |
immediate_quit = 0; |
immediate_quit = 0; |
2905 |
|
|
2918 |
{ |
{ |
2919 |
struct servent *svc_info; |
struct servent *svc_info; |
2920 |
CHECK_STRING (service); |
CHECK_STRING (service); |
2921 |
svc_info = getservbyname (XSTRING (service)->data, |
svc_info = getservbyname (SDATA (service), |
2922 |
(socktype == SOCK_DGRAM ? "udp" : "tcp")); |
(socktype == SOCK_DGRAM ? "udp" : "tcp")); |
2923 |
if (svc_info == 0) |
if (svc_info == 0) |
2924 |
error ("Unknown service: %s", XSTRING (service)->data); |
error ("Unknown service: %s", SDATA (service)); |
2925 |
port = svc_info->s_port; |
port = svc_info->s_port; |
2926 |
} |
} |
2927 |
|
|
2939 |
as it may `hang' emacs for a very long time. */ |
as it may `hang' emacs for a very long time. */ |
2940 |
immediate_quit = 1; |
immediate_quit = 1; |
2941 |
QUIT; |
QUIT; |
2942 |
host_info_ptr = gethostbyname (XSTRING (host)->data); |
host_info_ptr = gethostbyname (SDATA (host)); |
2943 |
immediate_quit = 0; |
immediate_quit = 0; |
2944 |
|
|
2945 |
if (host_info_ptr) |
if (host_info_ptr) |
2946 |
{ |
{ |
2947 |
bcopy (host_info_ptr->h_addr, (char *) &address_in.sin_addr, |
bcopy (host_info_ptr->h_addr, (char *) &address_in.sin_addr, |
2953 |
/* Attempt to interpret host as numeric inet address */ |
/* Attempt to interpret host as numeric inet address */ |
2954 |
{ |
{ |
2955 |
IN_ADDR numeric_addr; |
IN_ADDR numeric_addr; |
2956 |
numeric_addr = inet_addr ((char *) XSTRING (host)->data); |
numeric_addr = inet_addr ((char *) SDATA (host)); |
2957 |
if (NUMERIC_ADDR_ERROR) |
if (NUMERIC_ADDR_ERROR) |
2958 |
error ("Unknown host \"%s\"", XSTRING (host)->data); |
error ("Unknown host \"%s\"", SDATA (host)); |
2959 |
|
|
2960 |
bcopy ((char *)&numeric_addr, (char *) &address_in.sin_addr, |
bcopy ((char *)&numeric_addr, (char *) &address_in.sin_addr, |
2961 |
sizeof (address_in.sin_addr)); |
sizeof (address_in.sin_addr)); |
2988 |
} |
} |
2989 |
|
|
2990 |
/* Do this in case we never enter the for-loop below. */ |
/* Do this in case we never enter the for-loop below. */ |
2991 |
count1 = specpdl_ptr - specpdl; |
count1 = SPECPDL_INDEX (); |
2992 |
s = -1; |
s = -1; |
2993 |
|
|
2994 |
for (lres = res; lres; lres = lres->ai_next) |
for (lres = res; lres; lres = lres->ai_next) |
3022 |
} |
} |
3023 |
} |
} |
3024 |
#endif |
#endif |
3025 |
|
|
3026 |
/* Make us close S if quit. */ |
/* Make us close S if quit. */ |
3027 |
record_unwind_protect (close_file_unwind, make_number (s)); |
record_unwind_protect (close_file_unwind, make_number (s)); |
3028 |
|
|
3037 |
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval)) |
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval)) |
3038 |
report_file_error ("Cannot set reuse option on server socket.", Qnil); |
report_file_error ("Cannot set reuse option on server socket.", Qnil); |
3039 |
} |
} |
3040 |
|
|
3041 |
if (bind (s, lres->ai_addr, lres->ai_addrlen)) |
if (bind (s, lres->ai_addr, lres->ai_addrlen)) |
3042 |
report_file_error ("Cannot bind server socket", Qnil); |
report_file_error ("Cannot bind server socket", Qnil); |
3043 |
|
|
3049 |
if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0) |
if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0) |
3050 |
{ |
{ |
3051 |
((struct sockaddr_in *)(lres->ai_addr))->sin_port = sa1.sin_port; |
((struct sockaddr_in *)(lres->ai_addr))->sin_port = sa1.sin_port; |
3052 |
service = make_number (sa1.sin_port); |
service = make_number (ntohs (sa1.sin_port)); |
3053 |
contact = Fplist_put (contact, QCservice, service); |
contact = Fplist_put (contact, QCservice, service); |
3054 |
} |
} |
3055 |
} |
} |
3072 |
set. |
set. |
3073 |
|
|
3074 |
It'd be nice to be able to control the connect timeout |
It'd be nice to be able to control the connect timeout |
3075 |
though. Would non-blocking connect calls be portable? |
though. Would non-blocking connect calls be portable? |
3076 |
|
|
3077 |
This used to be conditioned by HAVE_GETADDRINFO. Why? */ |
This used to be conditioned by HAVE_GETADDRINFO. Why? */ |
3078 |
|
|
3148 |
bcopy (lres->ai_addr, datagram_address[s].sa, lres->ai_addrlen); |
bcopy (lres->ai_addr, datagram_address[s].sa, lres->ai_addrlen); |
3149 |
} |
} |
3150 |
#endif |
#endif |
3151 |
contact = Fplist_put (contact, QCaddress, |
contact = Fplist_put (contact, QCaddress, |
3152 |
conv_sockaddr_to_lisp (lres->ai_addr, lres->ai_addrlen)); |
conv_sockaddr_to_lisp (lres->ai_addr, lres->ai_addrlen)); |
3153 |
|
#ifdef HAVE_GETSOCKNAME |
3154 |
|
if (!is_server) |
3155 |
|
{ |
3156 |
|
struct sockaddr_in sa1; |
3157 |
|
int len1 = sizeof (sa1); |
3158 |
|
if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0) |
3159 |
|
contact = Fplist_put (contact, QClocal, |
3160 |
|
conv_sockaddr_to_lisp (&sa1, len1)); |
3161 |
|
} |
3162 |
|
#endif |
3163 |
} |
} |
3164 |
|
|
3165 |
#ifdef HAVE_GETADDRINFO |
#ifdef HAVE_GETADDRINFO |
3217 |
p = XPROCESS (proc); |
p = XPROCESS (proc); |
3218 |
|
|
3219 |
p->childp = contact; |
p->childp = contact; |
3220 |
|
p->plist = Fcopy_sequence (Fplist_get (contact, QCplist)); |
3221 |
|
|
3222 |
p->buffer = buffer; |
p->buffer = buffer; |
3223 |
p->sentinel = sentinel; |
p->sentinel = sentinel; |
3224 |
p->filter = filter; |
p->filter = filter; |
3225 |
|
p->filter_multibyte = buffer_defaults.enable_multibyte_characters; |
3226 |
|
/* Override the above only if :filter-multibyte is specified. */ |
3227 |
|
if (! NILP (Fplist_member (contact, QCfilter_multibyte))) |
3228 |
|
p->filter_multibyte = Fplist_get (contact, QCfilter_multibyte); |
3229 |
p->log = Fplist_get (contact, QClog); |
p->log = Fplist_get (contact, QClog); |
3230 |
if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) |
if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) |
3231 |
p->kill_without_query = Qt; |
p->kill_without_query = Qt; |
3288 |
val = Qnil; |
val = Qnil; |
3289 |
else |
else |
3290 |
{ |
{ |
3291 |
args[0] = Qopen_network_stream, args[1] = name, |
if (NILP (host) || NILP (service)) |
3292 |
args[2] = buffer, args[3] = host, args[4] = service; |
coding_systems = Qnil; |
3293 |
GCPRO1 (proc); |
else |
3294 |
coding_systems = Ffind_operation_coding_system (5, args); |
{ |
3295 |
UNGCPRO; |
args[0] = Qopen_network_stream, args[1] = name, |
3296 |
|
args[2] = buffer, args[3] = host, args[4] = service; |
3297 |
|
GCPRO1 (proc); |
3298 |
|
coding_systems = Ffind_operation_coding_system (5, args); |
3299 |
|
UNGCPRO; |
3300 |
|
} |
3301 |
if (CONSP (coding_systems)) |
if (CONSP (coding_systems)) |
3302 |
val = XCAR (coding_systems); |
val = XCAR (coding_systems); |
3303 |
else if (CONSP (Vdefault_process_coding_system)) |
else if (CONSP (Vdefault_process_coding_system)) |
3317 |
{ |
{ |
3318 |
if (EQ (coding_systems, Qt)) |
if (EQ (coding_systems, Qt)) |
3319 |
{ |
{ |
3320 |
args[0] = Qopen_network_stream, args[1] = name, |
if (NILP (host) || NILP (service)) |
3321 |
args[2] = buffer, args[3] = host, args[4] = service; |
coding_systems = Qnil; |
3322 |
GCPRO1 (proc); |
else |
3323 |
coding_systems = Ffind_operation_coding_system (5, args); |
{ |
3324 |
UNGCPRO; |
args[0] = Qopen_network_stream, args[1] = name, |
3325 |
|
args[2] = buffer, args[3] = host, args[4] = service; |
3326 |
|
GCPRO1 (proc); |
3327 |
|
coding_systems = Ffind_operation_coding_system (5, args); |
3328 |
|
UNGCPRO; |
3329 |
|
} |
3330 |
} |
} |
3331 |
if (CONSP (coding_systems)) |
if (CONSP (coding_systems)) |
3332 |
val = XCDR (coding_systems); |
val = XCDR (coding_systems); |
3337 |
} |
} |
3338 |
p->encode_coding_system = val; |
p->encode_coding_system = val; |
3339 |
} |
} |
3340 |
|
setup_process_coding_systems (proc); |
|
if (!proc_decode_coding_system[inch]) |
|
|
proc_decode_coding_system[inch] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (p->decode_coding_system, |
|
|
proc_decode_coding_system[inch]); |
|
|
if (!proc_encode_coding_system[outch]) |
|
|
proc_encode_coding_system[outch] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (p->encode_coding_system, |
|
|
proc_encode_coding_system[outch]); |
|
3341 |
|
|
3342 |
p->decoding_buf = make_uninit_string (0); |
p->decoding_buf = make_uninit_string (0); |
3343 |
p->decoding_carryover = make_number (0); |
p->decoding_carryover = make_number (0); |
3634 |
contact = Fplist_put (contact, QChost, host); |
contact = Fplist_put (contact, QChost, host); |
3635 |
if (!NILP (service)) |
if (!NILP (service)) |
3636 |
contact = Fplist_put (contact, QCservice, service); |
contact = Fplist_put (contact, QCservice, service); |
3637 |
contact = Fplist_put (contact, QCremote, |
contact = Fplist_put (contact, QCremote, |
3638 |
conv_sockaddr_to_lisp (&saddr.sa, len)); |
conv_sockaddr_to_lisp (&saddr.sa, len)); |
3639 |
#ifdef HAVE_GETSOCKNAME |
#ifdef HAVE_GETSOCKNAME |
3640 |
len = sizeof saddr; |
len = sizeof saddr; |
3641 |
if (getsockname (channel, &saddr.sa, &len) == 0) |
if (getsockname (s, &saddr.sa, &len) == 0) |
3642 |
contact = Fplist_put (contact, QClocal, |
contact = Fplist_put (contact, QClocal, |
3643 |
conv_sockaddr_to_lisp (&saddr.sa, len)); |
conv_sockaddr_to_lisp (&saddr.sa, len)); |
3644 |
#endif |
#endif |
3645 |
|
|
3646 |
p->childp = contact; |
p->childp = contact; |
3647 |
|
p->plist = Fcopy_sequence (ps->plist); |
3648 |
|
|
3649 |
p->buffer = buffer; |
p->buffer = buffer; |
3650 |
p->sentinel = ps->sentinel; |
p->sentinel = ps->sentinel; |
3651 |
p->filter = ps->filter; |
p->filter = ps->filter; |
3665 |
if (s > max_process_desc) |
if (s > max_process_desc) |
3666 |
max_process_desc = s; |
max_process_desc = s; |
3667 |
|
|
3668 |
/* Setup coding system for new process based on server process. |
/* Setup coding system for new process based on server process. |
3669 |
This seems to be the proper thing to do, as the coding system |
This seems to be the proper thing to do, as the coding system |
3670 |
of the new process should reflect the settings at the time the |
of the new process should reflect the settings at the time the |
3671 |
server socket was opened; not the current settings. */ |
server socket was opened; not the current settings. */ |
3672 |
|
|
3673 |
p->decode_coding_system = ps->decode_coding_system; |
p->decode_coding_system = ps->decode_coding_system; |
3674 |
p->encode_coding_system = ps->encode_coding_system; |
p->encode_coding_system = ps->encode_coding_system; |
3675 |
|
setup_process_coding_systems (proc); |
|
if (!proc_decode_coding_system[s]) |
|
|
proc_decode_coding_system[s] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (p->decode_coding_system, |
|
|
proc_decode_coding_system[s]); |
|
|
if (!proc_encode_coding_system[s]) |
|
|
proc_encode_coding_system[s] |
|
|
= (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
|
|
setup_coding_system (p->encode_coding_system, |
|
|
proc_encode_coding_system[s]); |
|
3676 |
|
|
3677 |
p->decoding_buf = make_uninit_string (0); |
p->decoding_buf = make_uninit_string (0); |
3678 |
p->decoding_carryover = make_number (0); |
p->decoding_carryover = make_number (0); |
3689 |
build_string ("\n"))); |
build_string ("\n"))); |
3690 |
|
|
3691 |
if (!NILP (p->sentinel)) |
if (!NILP (p->sentinel)) |
3692 |
exec_sentinel (proc, |
exec_sentinel (proc, |
3693 |
concat3 (build_string ("open from "), |
concat3 (build_string ("open from "), |
3694 |
(STRINGP (host) ? host : build_string ("-")), |
(STRINGP (host) ? host : build_string ("-")), |
3695 |
build_string ("\n"))); |
build_string ("\n"))); |
3793 |
EMACS_SET_SECS_USECS (timeout, time_limit, microsecs); |
EMACS_SET_SECS_USECS (timeout, time_limit, microsecs); |
3794 |
EMACS_ADD_TIME (end_time, end_time, timeout); |
EMACS_ADD_TIME (end_time, end_time, timeout); |
3795 |
} |
} |
3796 |
#ifdef hpux |
#ifdef POLL_INTERRUPTED_SYS_CALL |
3797 |
/* AlainF 5-Jul-1996 |
/* AlainF 5-Jul-1996 |
3798 |
HP-UX 10.10 seem to have problems with signals coming in |
HP-UX 10.10 seem to have problems with signals coming in |
3799 |
Causes "poll: interrupted system call" messages when Emacs is run |
Causes "poll: interrupted system call" messages when Emacs is run |
3800 |
in an X window |
in an X window |
3801 |
Turn off periodic alarms (in case they are in use) */ |
Turn off periodic alarms (in case they are in use), |
3802 |
|
and then turn off any other atimers. */ |
3803 |
|
stop_polling (); |
3804 |
turn_on_atimers (0); |
turn_on_atimers (0); |
3805 |
#endif |
#endif /* POLL_INTERRUPTED_SYS_CALL */ |
3806 |
|
|
3807 |
while (1) |
while (1) |
3808 |
{ |
{ |
3852 |
{ |
{ |
3853 |
int old_timers_run = timers_run; |
int old_timers_run = timers_run; |
3854 |
struct buffer *old_buffer = current_buffer; |
struct buffer *old_buffer = current_buffer; |
3855 |
|
|
3856 |
timer_delay = timer_check (1); |
timer_delay = timer_check (1); |
3857 |
|
|
3858 |
/* If a timer has run, this might have changed buffers |
/* If a timer has run, this might have changed buffers |
3861 |
&& old_buffer != current_buffer |
&& old_buffer != current_buffer |
3862 |
&& waiting_for_user_input_p == -1) |
&& waiting_for_user_input_p == -1) |
3863 |
record_asynch_buffer_change (); |
record_asynch_buffer_change (); |
3864 |
|
|
3865 |
if (timers_run != old_timers_run && do_display) |
if (timers_run != old_timers_run && do_display) |
3866 |
/* We must retry, since a timer may have requeued itself |
/* We must retry, since a timer may have requeued itself |
3867 |
and that could alter the time_delay. */ |
and that could alter the time_delay. */ |
3923 |
Ctemp = connect_wait_mask; |
Ctemp = connect_wait_mask; |
3924 |
EMACS_SET_SECS_USECS (timeout, 0, 0); |
EMACS_SET_SECS_USECS (timeout, 0, 0); |
3925 |
if ((select (max (max_process_desc, max_keyboard_desc) + 1, |
if ((select (max (max_process_desc, max_keyboard_desc) + 1, |
3926 |
&Atemp, |
&Atemp, |
3927 |
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), |
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), |
3928 |
(SELECT_TYPE *)0, &timeout) |
(SELECT_TYPE *)0, &timeout) |
3929 |
<= 0)) |
<= 0)) |
3956 |
if (nread == 0) |
if (nread == 0) |
3957 |
break; |
break; |
3958 |
|
|
3959 |
if (0 < nread) |
if (0 < nread) |
3960 |
total_nread += nread; |
total_nread += nread; |
3961 |
#ifdef EIO |
#ifdef EIO |
3962 |
else if (nread == -1 && EIO == errno) |
else if (nread == -1 && EIO == errno) |
4017 |
if (check_connect) |
if (check_connect) |
4018 |
Connecting = connect_wait_mask; |
Connecting = connect_wait_mask; |
4019 |
nfds = select (max (max_process_desc, max_keyboard_desc) + 1, |
nfds = select (max (max_process_desc, max_keyboard_desc) + 1, |
4020 |
&Available, |
&Available, |
4021 |
(check_connect ? &Connecting : (SELECT_TYPE *)0), |
(check_connect ? &Connecting : (SELECT_TYPE *)0), |
4022 |
(SELECT_TYPE *)0, &timeout); |
(SELECT_TYPE *)0, &timeout); |
4023 |
} |
} |
4114 |
int old_timers_run = timers_run; |
int old_timers_run = timers_run; |
4115 |
struct buffer *old_buffer = current_buffer; |
struct buffer *old_buffer = current_buffer; |
4116 |
int leave = 0; |
int leave = 0; |
4117 |
|
|
4118 |
if (detect_input_pending_run_timers (do_display)) |
if (detect_input_pending_run_timers (do_display)) |
4119 |
{ |
{ |
4120 |
swallow_events (do_display); |
swallow_events (do_display); |
4131 |
|
|
4132 |
if (leave) |
if (leave) |
4133 |
break; |
break; |
4134 |
} |
} |
4135 |
|
|
4136 |
/* If there is unread keyboard input, also return. */ |
/* If there is unread keyboard input, also return. */ |
4137 |
if (XINT (read_kbd) != 0 |
if (XINT (read_kbd) != 0 |
4138 |
&& requeued_events_pending_p ()) |
&& requeued_events_pending_p ()) |
4279 |
= Fcons (Qexit, Fcons (make_number (256), Qnil)); |
= Fcons (Qexit, Fcons (make_number (256), Qnil)); |
4280 |
} |
} |
4281 |
} |
} |
4282 |
#ifdef NON_BLOCKING_CONNECT |
#ifdef NON_BLOCKING_CONNECT |
4283 |
if (check_connect && FD_ISSET (channel, &Connecting)) |
if (check_connect && FD_ISSET (channel, &Connecting)) |
4284 |
{ |
{ |
4285 |
struct Lisp_Process *p; |
struct Lisp_Process *p; |
4354 |
clear_input_pending (); |
clear_input_pending (); |
4355 |
QUIT; |
QUIT; |
4356 |
} |
} |
4357 |
#ifdef hpux |
#ifdef POLL_INTERRUPTED_SYS_CALL |
4358 |
/* AlainF 5-Jul-1996 |
/* AlainF 5-Jul-1996 |
4359 |
HP-UX 10.10 seems to have problems with signals coming in |
HP-UX 10.10 seems to have problems with signals coming in |
4360 |
Causes "poll: interrupted system call" messages when Emacs is run |
Causes "poll: interrupted system call" messages when Emacs is run |
4361 |
in an X window |
in an X window |
4362 |
Turn periodic alarms back on */ |
Turn periodic alarms back on */ |
4363 |
start_polling (); |
start_polling (); |
4364 |
#endif |
#endif /* POLL_INTERRUPTED_SYS_CALL */ |
4365 |
|
|
4366 |
return got_some_input; |
return got_some_input; |
4367 |
} |
} |
4438 |
the tail of decoding buffer) should be prepended to the new |
the tail of decoding buffer) should be prepended to the new |
4439 |
data read to decode all together. */ |
data read to decode all together. */ |
4440 |
chars = (char *) alloca (nbytes + carryover); |
chars = (char *) alloca (nbytes + carryover); |
4441 |
bcopy (XSTRING (p->decoding_buf)->data, buf, carryover); |
bcopy (SDATA (p->decoding_buf), buf, carryover); |
4442 |
bcopy (vs->inputBuffer, chars + carryover, nbytes); |
bcopy (vs->inputBuffer, chars + carryover, nbytes); |
4443 |
} |
} |
4444 |
#else /* not VMS */ |
#else /* not VMS */ |
4456 |
chars = (char *) alloca (carryover + readmax); |
chars = (char *) alloca (carryover + readmax); |
4457 |
if (carryover) |
if (carryover) |
4458 |
/* See the comment above. */ |
/* See the comment above. */ |
4459 |
bcopy (XSTRING (p->decoding_buf)->data, chars, carryover); |
bcopy (SDATA (p->decoding_buf), chars, carryover); |
4460 |
|
|
4461 |
#ifdef DATAGRAM_SOCKETS |
#ifdef DATAGRAM_SOCKETS |
4462 |
/* We have a working select, so proc_buffered_char is always -1. */ |
/* We have a working select, so proc_buffered_char is always -1. */ |
4463 |
if (DATAGRAM_CHAN_P (channel)) |
if (DATAGRAM_CHAN_P (channel)) |
4464 |
{ |
{ |
4465 |
int len = datagram_address[channel].len; |
int len = datagram_address[channel].len; |
4466 |
nbytes = recvfrom (channel, chars + carryover, readmax - carryover, |
nbytes = recvfrom (channel, chars + carryover, readmax, |
4467 |
0, datagram_address[channel].sa, &len); |
0, datagram_address[channel].sa, &len); |
4468 |
} |
} |
4469 |
else |
else |
4470 |
#endif |
#endif |
4471 |
if (proc_buffered_char[channel] < 0) |
if (proc_buffered_char[channel] < 0) |
4472 |
nbytes = emacs_read (channel, chars + carryover, readmax - carryover); |
nbytes = emacs_read (channel, chars + carryover, readmax); |
4473 |
else |
else |
4474 |
{ |
{ |
4475 |
chars[carryover] = proc_buffered_char[channel]; |
chars[carryover] = proc_buffered_char[channel]; |
4476 |
proc_buffered_char[channel] = -1; |
proc_buffered_char[channel] = -1; |
4477 |
nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1 - carryover); |
nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1); |
4478 |
if (nbytes < 0) |
if (nbytes < 0) |
4479 |
nbytes = 1; |
nbytes = 1; |
4480 |
else |
else |
4500 |
outstream = p->filter; |
outstream = p->filter; |
4501 |
if (!NILP (outstream)) |
if (!NILP (outstream)) |
4502 |
{ |
{ |
4503 |
/* We inhibit quit here instead of just catching it so that |
/* We inhibit quit here instead of just catching it so that |
4504 |
hitting ^G when a filter happens to be running won't screw |
hitting ^G when a filter happens to be running won't screw |
4505 |
it up. */ |
it up. */ |
4506 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
4507 |
Lisp_Object odeactivate; |
Lisp_Object odeactivate; |
4508 |
Lisp_Object obuffer, okeymap; |
Lisp_Object obuffer, okeymap; |
4509 |
Lisp_Object text; |
Lisp_Object text; |
4538 |
|
|
4539 |
text = decode_coding_string (make_unibyte_string (chars, nbytes), |
text = decode_coding_string (make_unibyte_string (chars, nbytes), |
4540 |
coding, 0); |
coding, 0); |
|
if (NILP (buffer_defaults.enable_multibyte_characters)) |
|
|
/* We had better return unibyte string. */ |
|
|
text = string_make_unibyte (text); |
|
|
|
|
4541 |
Vlast_coding_system_used = coding->symbol; |
Vlast_coding_system_used = coding->symbol; |
4542 |
/* A new coding system might be found. */ |
/* A new coding system might be found. */ |
4543 |
if (!EQ (p->decode_coding_system, coding->symbol)) |
if (!EQ (p->decode_coding_system, coding->symbol)) |
4565 |
} |
} |
4566 |
|
|
4567 |
carryover = nbytes - coding->consumed; |
carryover = nbytes - coding->consumed; |
4568 |
bcopy (chars + coding->consumed, XSTRING (p->decoding_buf)->data, |
bcopy (chars + coding->consumed, SDATA (p->decoding_buf), |
4569 |
carryover); |
carryover); |
4570 |
XSETINT (p->decoding_carryover, carryover); |
XSETINT (p->decoding_carryover, carryover); |
4571 |
nbytes = STRING_BYTES (XSTRING (text)); |
/* Adjust the multibyteness of TEXT to that of the filter. */ |
4572 |
nchars = XSTRING (text)->size; |
if (NILP (p->filter_multibyte) != ! STRING_MULTIBYTE (text)) |
4573 |
|
text = (STRING_MULTIBYTE (text) |
4574 |
|
? Fstring_as_unibyte (text) |
4575 |
|
: Fstring_to_multibyte (text)); |
4576 |
|
nbytes = SBYTES (text); |
4577 |
|
nchars = SCHARS (text); |
4578 |
if (nbytes > 0) |
if (nbytes > 0) |
4579 |
internal_condition_case_1 (read_process_output_call, |
internal_condition_case_1 (read_process_output_call, |
4580 |
Fcons (outstream, |
Fcons (outstream, |
4671 |
} |
} |
4672 |
} |
} |
4673 |
carryover = nbytes - coding->consumed; |
carryover = nbytes - coding->consumed; |
4674 |
bcopy (chars + coding->consumed, XSTRING (p->decoding_buf)->data, |
bcopy (chars + coding->consumed, SDATA (p->decoding_buf), |
4675 |
carryover); |
carryover); |
4676 |
XSETINT (p->decoding_carryover, carryover); |
XSETINT (p->decoding_carryover, carryover); |
4677 |
/* Adjust the multibyteness of TEXT to that of the buffer. */ |
/* Adjust the multibyteness of TEXT to that of the buffer. */ |
4679 |
!= ! STRING_MULTIBYTE (text)) |
!= ! STRING_MULTIBYTE (text)) |
4680 |
text = (STRING_MULTIBYTE (text) |
text = (STRING_MULTIBYTE (text) |
4681 |
? Fstring_as_unibyte (text) |
? Fstring_as_unibyte (text) |
4682 |
: Fstring_as_multibyte (text)); |
: Fstring_to_multibyte (text)); |
4683 |
nbytes = STRING_BYTES (XSTRING (text)); |
nbytes = SBYTES (text); |
4684 |
nchars = XSTRING (text)->size; |
nchars = SCHARS (text); |
4685 |
/* Insert before markers in case we are inserting where |
/* Insert before markers in case we are inserting where |
4686 |
the buffer's mark is, and the user's next command is Meta-y. */ |
the buffer's mark is, and the user's next command is Meta-y. */ |
4687 |
insert_from_string_before_markers (text, 0, 0, nchars, nbytes, 0); |
insert_from_string_before_markers (text, 0, 0, nchars, nbytes, 0); |
4789 |
update_status (XPROCESS (proc)); |
update_status (XPROCESS (proc)); |
4790 |
if (! EQ (XPROCESS (proc)->status, Qrun)) |
if (! EQ (XPROCESS (proc)->status, Qrun)) |
4791 |
error ("Process %s not running", |
error ("Process %s not running", |
4792 |
XSTRING (XPROCESS (proc)->name)->data); |
SDATA (XPROCESS (proc)->name)); |
4793 |
if (XINT (XPROCESS (proc)->outfd) < 0) |
if (XINT (XPROCESS (proc)->outfd) < 0) |
4794 |
error ("Output file descriptor of %s is closed", |
error ("Output file descriptor of %s is closed", |
4795 |
XSTRING (XPROCESS (proc)->name)->data); |
SDATA (XPROCESS (proc)->name)); |
4796 |
|
|
4797 |
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; |
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; |
4798 |
Vlast_coding_system_used = coding->symbol; |
Vlast_coding_system_used = coding->symbol; |
4847 |
} |
} |
4848 |
else if (STRINGP (object)) |
else if (STRINGP (object)) |
4849 |
{ |
{ |
4850 |
from_byte = buf - XSTRING (object)->data; |
from_byte = buf - SDATA (object); |
4851 |
from = string_byte_to_char (object, from_byte); |
from = string_byte_to_char (object, from_byte); |
4852 |
to = string_byte_to_char (object, from_byte + len); |
to = string_byte_to_char (object, from_byte + len); |
4853 |
} |
} |
4860 |
coding->composing = COMPOSITION_DISABLED; |
coding->composing = COMPOSITION_DISABLED; |
4861 |
} |
} |
4862 |
|
|
4863 |
if (STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf)) < require) |
if (SBYTES (XPROCESS (proc)->encoding_buf) < require) |
4864 |
XPROCESS (proc)->encoding_buf = make_uninit_string (require); |
XPROCESS (proc)->encoding_buf = make_uninit_string (require); |
4865 |
|
|
4866 |
if (from_byte >= 0) |
if (from_byte >= 0) |
4867 |
buf = (BUFFERP (object) |
buf = (BUFFERP (object) |
4868 |
? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) |
? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) |
4869 |
: XSTRING (object)->data + from_byte); |
: SDATA (object) + from_byte); |
4870 |
|
|
4871 |
object = XPROCESS (proc)->encoding_buf; |
object = XPROCESS (proc)->encoding_buf; |
4872 |
encode_coding (coding, (char *) buf, XSTRING (object)->data, |
encode_coding (coding, (char *) buf, SDATA (object), |
4873 |
len, STRING_BYTES (XSTRING (object))); |
len, SBYTES (object)); |
4874 |
len = coding->produced; |
len = coding->produced; |
4875 |
buf = XSTRING (object)->data; |
buf = SDATA (object); |
4876 |
if (temp_buf) |
if (temp_buf) |
4877 |
xfree (temp_buf); |
xfree (temp_buf); |
4878 |
} |
} |
4967 |
|| errno == EAGAIN |
|| errno == EAGAIN |
4968 |
#endif |
#endif |
4969 |
) |
) |
4970 |
/* Buffer is full. Wait, accepting input; |
/* Buffer is full. Wait, accepting input; |
4971 |
that may allow the program |
that may allow the program |
4972 |
to finish doing output and read more. */ |
to finish doing output and read more. */ |
4973 |
{ |
{ |
4991 |
the terminal is set up that way which it is |
the terminal is set up that way which it is |
4992 |
here). The same bytes will be seen again in a |
here). The same bytes will be seen again in a |
4993 |
later read(2), without the CRs. */ |
later read(2), without the CRs. */ |
4994 |
|
|
4995 |
if (errno == EAGAIN) |
if (errno == EAGAIN) |
4996 |
{ |
{ |
4997 |
int flags = FWRITE; |
int flags = FWRITE; |
4999 |
&flags); |
&flags); |
5000 |
} |
} |
5001 |
#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ |
5002 |
|
|
5003 |
/* Running filters might relocate buffers or strings. |
/* Running filters might relocate buffers or strings. |
5004 |
Arrange to relocate BUF. */ |
Arrange to relocate BUF. */ |
5005 |
if (BUFFERP (object)) |
if (BUFFERP (object)) |
5006 |
offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); |
offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf); |
5007 |
else if (STRINGP (object)) |
else if (STRINGP (object)) |
5008 |
offset = buf - XSTRING (object)->data; |
offset = buf - SDATA (object); |
5009 |
|
|
5010 |
XSETFASTINT (zero, 0); |
XSETFASTINT (zero, 0); |
5011 |
#ifdef EMACS_HAS_USECS |
#ifdef EMACS_HAS_USECS |
5017 |
if (BUFFERP (object)) |
if (BUFFERP (object)) |
5018 |
buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); |
buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset); |
5019 |
else if (STRINGP (object)) |
else if (STRINGP (object)) |
5020 |
buf = offset + XSTRING (object)->data; |
buf = offset + SDATA (object); |
5021 |
|
|
5022 |
rv = 0; |
rv = 0; |
5023 |
} |
} |
5048 |
XSETINT (XPROCESS (proc)->tick, ++process_tick); |
XSETINT (XPROCESS (proc)->tick, ++process_tick); |
5049 |
deactivate_process (proc); |
deactivate_process (proc); |
5050 |
#ifdef VMS |
#ifdef VMS |
5051 |
error ("Error writing to process %s; closed it", |
error ("Error writing to process %s; closed it", |
5052 |
XSTRING (XPROCESS (proc)->name)->data); |
SDATA (XPROCESS (proc)->name)); |
5053 |
#else |
#else |
5054 |
error ("SIGPIPE raised on process %s; closed it", |
error ("SIGPIPE raised on process %s; closed it", |
5055 |
XSTRING (XPROCESS (proc)->name)->data); |
SDATA (XPROCESS (proc)->name)); |
5056 |
#endif |
#endif |
5057 |
} |
} |
5058 |
|
|
5102 |
Lisp_Object proc; |
Lisp_Object proc; |
5103 |
CHECK_STRING (string); |
CHECK_STRING (string); |
5104 |
proc = get_process (process); |
proc = get_process (process); |
5105 |
send_process (proc, XSTRING (string)->data, |
send_process (proc, SDATA (string), |
5106 |
STRING_BYTES (XSTRING (string)), string); |
SBYTES (string), string); |
5107 |
return Qnil; |
return Qnil; |
5108 |
} |
} |
5109 |
|
|
5110 |
|
/* Return the foreground process group for the tty/pty that |
5111 |
|
the process P uses. */ |
5112 |
|
static int |
5113 |
|
emacs_get_tty_pgrp (p) |
5114 |
|
struct Lisp_Process *p; |
5115 |
|
{ |
5116 |
|
int gid = -1; |
5117 |
|
|
5118 |
|
#ifdef TIOCGPGRP |
5119 |
|
if (ioctl (XINT (p->infd), TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name)) |
5120 |
|
{ |
5121 |
|
int fd; |
5122 |
|
/* Some OS:es (Solaris 8/9) does not allow TIOCGPGRP from the |
5123 |
|
master side. Try the slave side. */ |
5124 |
|
fd = emacs_open (XSTRING (p->tty_name)->data, O_RDONLY, 0); |
5125 |
|
|
5126 |
|
if (fd != -1) |
5127 |
|
{ |
5128 |
|
ioctl (fd, TIOCGPGRP, &gid); |
5129 |
|
emacs_close (fd); |
5130 |
|
} |
5131 |
|
} |
5132 |
|
#endif /* defined (TIOCGPGRP ) */ |
5133 |
|
|
5134 |
|
return gid; |
5135 |
|
} |
5136 |
|
|
5137 |
DEFUN ("process-running-child-p", Fprocess_running_child_p, |
DEFUN ("process-running-child-p", Fprocess_running_child_p, |
5138 |
Sprocess_running_child_p, 0, 1, 0, |
Sprocess_running_child_p, 0, 1, 0, |
5139 |
doc: /* Return t if PROCESS has given the terminal to a child. |
doc: /* Return t if PROCESS has given the terminal to a child. |
5144 |
{ |
{ |
5145 |
/* Initialize in case ioctl doesn't exist or gives an error, |
/* Initialize in case ioctl doesn't exist or gives an error, |
5146 |
in a way that will cause returning t. */ |
in a way that will cause returning t. */ |
5147 |
int gid = 0; |
int gid; |
5148 |
Lisp_Object proc; |
Lisp_Object proc; |
5149 |
struct Lisp_Process *p; |
struct Lisp_Process *p; |
5150 |
|
|
5153 |
|
|
5154 |
if (!EQ (p->childp, Qt)) |
if (!EQ (p->childp, Qt)) |
5155 |
error ("Process %s is not a subprocess", |
error ("Process %s is not a subprocess", |
5156 |
XSTRING (p->name)->data); |
SDATA (p->name)); |
5157 |
if (XINT (p->infd) < 0) |
if (XINT (p->infd) < 0) |
5158 |
error ("Process %s is not active", |
error ("Process %s is not active", |
5159 |
XSTRING (p->name)->data); |
SDATA (p->name)); |
5160 |
|
|
5161 |
#ifdef TIOCGPGRP |
gid = emacs_get_tty_pgrp (p); |
|
if (!NILP (p->subtty)) |
|
|
ioctl (XFASTINT (p->subtty), TIOCGPGRP, &gid); |
|
|
else |
|
|
ioctl (XINT (p->infd), TIOCGPGRP, &gid); |
|
|
#endif /* defined (TIOCGPGRP ) */ |
|
5162 |
|
|
5163 |
if (gid == XFASTINT (p->pid)) |
if (gid == XFASTINT (p->pid)) |
5164 |
return Qnil; |
return Qnil; |
5196 |
|
|
5197 |
if (!EQ (p->childp, Qt)) |
if (!EQ (p->childp, Qt)) |
5198 |
error ("Process %s is not a subprocess", |
error ("Process %s is not a subprocess", |
5199 |
XSTRING (p->name)->data); |
SDATA (p->name)); |
5200 |
if (XINT (p->infd) < 0) |
if (XINT (p->infd) < 0) |
5201 |
error ("Process %s is not active", |
error ("Process %s is not active", |
5202 |
XSTRING (p->name)->data); |
SDATA (p->name)); |
5203 |
|
|
5204 |
if (NILP (p->pty_flag)) |
if (NILP (p->pty_flag)) |
5205 |
current_group = Qnil; |
current_group = Qnil; |
5206 |
|
|
5207 |
/* If we are using pgrps, get a pgrp number and make it negative. */ |
/* If we are using pgrps, get a pgrp number and make it negative. */ |
5208 |
if (!NILP (current_group)) |
if (NILP (current_group)) |
5209 |
|
/* Send the signal to the shell's process group. */ |
5210 |
|
gid = XFASTINT (p->pid); |
5211 |
|
else |
5212 |
{ |
{ |
5213 |
#ifdef SIGNALS_VIA_CHARACTERS |
#ifdef SIGNALS_VIA_CHARACTERS |
5214 |
/* If possible, send signals to the entire pgrp |
/* If possible, send signals to the entire pgrp |
5298 |
#endif /* ! defined (TCGETA) */ |
#endif /* ! defined (TCGETA) */ |
5299 |
#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ |
#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ |
5300 |
#endif /* ! defined HAVE_TERMIOS */ |
#endif /* ! defined HAVE_TERMIOS */ |
5301 |
#endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ |
abort (); |
5302 |
|
/* The code above always returns from the function. */ |
5303 |
|
#endif /* defined (SIGNALS_VIA_CHARACTERS) */ |
5304 |
|
|
5305 |
#ifdef TIOCGPGRP |
#ifdef TIOCGPGRP |
5306 |
/* Get the pgrp using the tty itself, if we have that. |
/* Get the current pgrp using the tty itself, if we have that. |
5307 |
Otherwise, use the pty to get the pgrp. |
Otherwise, use the pty to get the pgrp. |
5308 |
On pfa systems, saka@pfu.fujitsu.co.JP writes: |
On pfa systems, saka@pfu.fujitsu.co.JP writes: |
5309 |
"TIOCGPGRP symbol defined in sys/ioctl.h at E50. |
"TIOCGPGRP symbol defined in sys/ioctl.h at E50. |
5310 |
But, TIOCGPGRP does not work on E50 ;-P works fine on E60" |
But, TIOCGPGRP does not work on E50 ;-P works fine on E60" |
5311 |
His patch indicates that if TIOCGPGRP returns an error, then |
His patch indicates that if TIOCGPGRP returns an error, then |
5312 |
we should just assume that p->pid is also the process group id. */ |
we should just assume that p->pid is also the process group id. */ |
|
{ |
|
|
int err; |
|
|
|
|
|
if (!NILP (p->subtty)) |
|
|
err = ioctl (XFASTINT (p->subtty), TIOCGPGRP, &gid); |
|
|
else |
|
|
err = ioctl (XINT (p->infd), TIOCGPGRP, &gid); |
|
5313 |
|
|
5314 |
#ifdef pfa |
gid = emacs_get_tty_pgrp (p); |
5315 |
if (err == -1) |
|
5316 |
gid = - XFASTINT (p->pid); |
if (gid == -1) |
5317 |
#endif /* ! defined (pfa) */ |
/* If we can't get the information, assume |
5318 |
} |
the shell owns the tty. */ |
5319 |
|
gid = XFASTINT (p->pid); |
5320 |
|
|
5321 |
|
/* It is not clear whether anything really can set GID to -1. |
5322 |
|
Perhaps on some system one of those ioctls can or could do so. |
5323 |
|
Or perhaps this is vestigial. */ |
5324 |
if (gid == -1) |
if (gid == -1) |
5325 |
no_pgrp = 1; |
no_pgrp = 1; |
|
else |
|
|
gid = - gid; |
|
5326 |
#else /* ! defined (TIOCGPGRP ) */ |
#else /* ! defined (TIOCGPGRP ) */ |
5327 |
/* Can't select pgrps on this system, so we know that |
/* Can't select pgrps on this system, so we know that |
5328 |
the child itself heads the pgrp. */ |
the child itself heads the pgrp. */ |
5329 |
gid = - XFASTINT (p->pid); |
gid = XFASTINT (p->pid); |
5330 |
#endif /* ! defined (TIOCGPGRP ) */ |
#endif /* ! defined (TIOCGPGRP ) */ |
5331 |
|
|
5332 |
/* If current_group is lambda, and the shell owns the terminal, |
/* If current_group is lambda, and the shell owns the terminal, |
5333 |
don't send any signal. */ |
don't send any signal. */ |
5334 |
if (EQ (current_group, Qlambda) && gid == - XFASTINT (p->pid)) |
if (EQ (current_group, Qlambda) && gid == XFASTINT (p->pid)) |
5335 |
return; |
return; |
5336 |
} |
} |
|
else |
|
|
gid = - XFASTINT (p->pid); |
|
5337 |
|
|
5338 |
switch (signo) |
switch (signo) |
5339 |
{ |
{ |
5378 |
/* gid may be a pid, or minus a pgrp's number */ |
/* gid may be a pid, or minus a pgrp's number */ |
5379 |
#ifdef TIOCSIGSEND |
#ifdef TIOCSIGSEND |
5380 |
if (!NILP (current_group)) |
if (!NILP (current_group)) |
5381 |
ioctl (XINT (p->infd), TIOCSIGSEND, signo); |
{ |
5382 |
|
if (ioctl (XINT (p->infd), TIOCSIGSEND, signo) == -1) |
5383 |
|
EMACS_KILLPG (gid, signo); |
5384 |
|
} |
5385 |
else |
else |
5386 |
{ |
{ |
5387 |
gid = - XFASTINT (p->pid); |
gid = - XFASTINT (p->pid); |
5388 |
kill (gid, signo); |
kill (gid, signo); |
5389 |
} |
} |
5390 |
#else /* ! defined (TIOCSIGSEND) */ |
#else /* ! defined (TIOCSIGSEND) */ |
5391 |
EMACS_KILLPG (-gid, signo); |
EMACS_KILLPG (gid, signo); |
5392 |
#endif /* ! defined (TIOCSIGSEND) */ |
#endif /* ! defined (TIOCSIGSEND) */ |
5393 |
} |
} |
5394 |
|
|
5433 |
|
|
5434 |
DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0, |
DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0, |
5435 |
doc: /* Stop process PROCESS. May be process or name of one. |
doc: /* Stop process PROCESS. May be process or name of one. |
5436 |
See function `interrupt-process' for more details on usage. |
See function `interrupt-process' for more details on usage. |
5437 |
If PROCESS is a network process, inhibit handling of incoming traffic. */) |
If PROCESS is a network process, inhibit handling of incoming traffic. */) |
5438 |
(process, current_group) |
(process, current_group) |
5439 |
Lisp_Object process, current_group; |
Lisp_Object process, current_group; |
5442 |
if (PROCESSP (process) && NETCONN_P (process)) |
if (PROCESSP (process) && NETCONN_P (process)) |
5443 |
{ |
{ |
5444 |
struct Lisp_Process *p; |
struct Lisp_Process *p; |
5445 |
|
|
5446 |
p = XPROCESS (process); |
p = XPROCESS (process); |
5447 |
if (NILP (p->command) |
if (NILP (p->command) |
5448 |
&& XINT (p->infd) >= 0) |
&& XINT (p->infd) >= 0) |
5464 |
|
|
5465 |
DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0, |
DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0, |
5466 |
doc: /* Continue process PROCESS. May be process or name of one. |
doc: /* Continue process PROCESS. May be process or name of one. |
5467 |
See function `interrupt-process' for more details on usage. |
See function `interrupt-process' for more details on usage. |
5468 |
If PROCESS is a network process, resume handling of incoming traffic. */) |
If PROCESS is a network process, resume handling of incoming traffic. */) |
5469 |
(process, current_group) |
(process, current_group) |
5470 |
Lisp_Object process, current_group; |
Lisp_Object process, current_group; |
5495 |
} |
} |
5496 |
|
|
5497 |
DEFUN ("signal-process", Fsignal_process, Ssignal_process, |
DEFUN ("signal-process", Fsignal_process, Ssignal_process, |
5498 |
2, 2, "nProcess number: \nnSignal code: ", |
2, 2, "sProcess (name or number): \nnSignal code: ", |
5499 |
doc: /* Send the process with process id PID the signal with code SIGCODE. |
doc: /* Send PROCESS the signal with code SIGCODE. |
5500 |
PID must be an integer. The process need not be a child of this Emacs. |
PROCESS may also be an integer specifying the process id of the |
5501 |
|
process to signal; in this case, the process need not be a child of |
5502 |
|
this Emacs. |
5503 |
SIGCODE may be an integer, or a symbol whose name is a signal name. */) |
SIGCODE may be an integer, or a symbol whose name is a signal name. */) |
5504 |
(pid, sigcode) |
(process, sigcode) |
5505 |
Lisp_Object pid, sigcode; |
Lisp_Object process, sigcode; |
5506 |
{ |
{ |
5507 |
CHECK_NUMBER (pid); |
Lisp_Object pid; |
5508 |
|
|
5509 |
|
if (INTEGERP (process)) |
5510 |
|
{ |
5511 |
|
pid = process; |
5512 |
|
goto got_it; |
5513 |
|
} |
5514 |
|
|
5515 |
|
if (STRINGP (process)) |
5516 |
|
{ |
5517 |
|
Lisp_Object tem; |
5518 |
|
if (tem = Fget_process (process), NILP (tem)) |
5519 |
|
{ |
5520 |
|
pid = Fstring_to_number (process, make_number (10)); |
5521 |
|
if (XINT (pid) != 0) |
5522 |
|
goto got_it; |
5523 |
|
} |
5524 |
|
process = tem; |
5525 |
|
} |
5526 |
|
else |
5527 |
|
process = get_process (process); |
5528 |
|
|
5529 |
|
if (NILP (process)) |
5530 |
|
return process; |
5531 |
|
|
5532 |
|
CHECK_PROCESS (process); |
5533 |
|
pid = XPROCESS (process)->pid; |
5534 |
|
if (!INTEGERP (pid) || XINT (pid) <= 0) |
5535 |
|
error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); |
5536 |
|
|
5537 |
|
got_it: |
5538 |
|
|
5539 |
#define handle_signal(NAME, VALUE) \ |
#define handle_signal(NAME, VALUE) \ |
5540 |
else if (!strcmp (name, NAME)) \ |
else if (!strcmp (name, NAME)) \ |
5547 |
unsigned char *name; |
unsigned char *name; |
5548 |
|
|
5549 |
CHECK_SYMBOL (sigcode); |
CHECK_SYMBOL (sigcode); |
5550 |
name = XSTRING (SYMBOL_NAME (sigcode))->data; |
name = SDATA (SYMBOL_NAME (sigcode)); |
5551 |
|
|
5552 |
if (0) |
if (0) |
5553 |
; |
; |
5674 |
if (! NILP (XPROCESS (proc)->raw_status_low)) |
if (! NILP (XPROCESS (proc)->raw_status_low)) |
5675 |
update_status (XPROCESS (proc)); |
update_status (XPROCESS (proc)); |
5676 |
if (! EQ (XPROCESS (proc)->status, Qrun)) |
if (! EQ (XPROCESS (proc)->status, Qrun)) |
5677 |
error ("Process %s not running", XSTRING (XPROCESS (proc)->name)->data); |
error ("Process %s not running", SDATA (XPROCESS (proc)->name)); |
5678 |
|
|
5679 |
if (CODING_REQUIRE_FLUSHING (coding)) |
if (CODING_REQUIRE_FLUSHING (coding)) |
5680 |
{ |
{ |
5749 |
/* On receipt of a signal that a child status has changed, loop asking |
/* On receipt of a signal that a child status has changed, loop asking |
5750 |
about children with changed statuses until the system says there |
about children with changed statuses until the system says there |
5751 |
are no more. |
are no more. |
5752 |
|
|
5753 |
All we do is change the status; we do not run sentinels or print |
All we do is change the status; we do not run sentinels or print |
5754 |
notifications. That is saved for the next time keyboard input is |
notifications. That is saved for the next time keyboard input is |
5755 |
done, in order to avoid timing errors. |
done, in order to avoid timing errors. |
5793 |
#define WUNTRACED 0 |
#define WUNTRACED 0 |
5794 |
#endif /* no WUNTRACED */ |
#endif /* no WUNTRACED */ |
5795 |
/* Keep trying to get a status until we get a definitive result. */ |
/* Keep trying to get a status until we get a definitive result. */ |
5796 |
do |
do |
5797 |
{ |
{ |
5798 |
errno = 0; |
errno = 0; |
5799 |
pid = wait3 (&w, WNOHANG | WUNTRACED, 0); |
pid = wait3 (&w, WNOHANG | WUNTRACED, 0); |
5844 |
break; |
break; |
5845 |
p = 0; |
p = 0; |
5846 |
} |
} |
5847 |
|
|
5848 |
/* Change the status of the process that was found. */ |
/* Change the status of the process that was found. */ |
5849 |
if (p != 0) |
if (p != 0) |
5850 |
{ |
{ |
5851 |
union { int i; WAITTYPE wt; } u; |
union { int i; WAITTYPE wt; } u; |
5852 |
int clear_desc_flag = 0; |
int clear_desc_flag = 0; |
5853 |
|
|
5854 |
XSETINT (p->tick, ++process_tick); |
XSETINT (p->tick, ++process_tick); |
5855 |
u.wt = w; |
u.wt = w; |
5856 |
XSETINT (p->raw_status_low, u.i & 0xffff); |
XSETINT (p->raw_status_low, u.i & 0xffff); |
5857 |
XSETINT (p->raw_status_high, u.i >> 16); |
XSETINT (p->raw_status_high, u.i >> 16); |
5858 |
|
|
5859 |
/* If process has terminated, stop waiting for its output. */ |
/* If process has terminated, stop waiting for its output. */ |
5860 |
if ((WIFSIGNALED (w) || WIFEXITED (w)) |
if ((WIFSIGNALED (w) || WIFEXITED (w)) |
5861 |
&& XINT (p->infd) >= 0) |
&& XINT (p->infd) >= 0) |
5946 |
{ |
{ |
5947 |
Lisp_Object sentinel, obuffer, odeactivate, okeymap; |
Lisp_Object sentinel, obuffer, odeactivate, okeymap; |
5948 |
register struct Lisp_Process *p = XPROCESS (proc); |
register struct Lisp_Process *p = XPROCESS (proc); |
5949 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
5950 |
int outer_running_asynch_code = running_asynch_code; |
int outer_running_asynch_code = running_asynch_code; |
5951 |
int waiting = waiting_for_user_input_p; |
int waiting = waiting_for_user_input_p; |
5952 |
|
|
6156 |
CHECK_PROCESS (proc); |
CHECK_PROCESS (proc); |
6157 |
p = XPROCESS (proc); |
p = XPROCESS (proc); |
6158 |
if (XINT (p->infd) < 0) |
if (XINT (p->infd) < 0) |
6159 |
error ("Input file descriptor of %s closed", XSTRING (p->name)->data); |
error ("Input file descriptor of %s closed", SDATA (p->name)); |
6160 |
if (XINT (p->outfd) < 0) |
if (XINT (p->outfd) < 0) |
6161 |
error ("Output file descriptor of %s closed", XSTRING (p->name)->data); |
error ("Output file descriptor of %s closed", SDATA (p->name)); |
6162 |
|
Fcheck_coding_system (decoding); |
6163 |
p->decode_coding_system = Fcheck_coding_system (decoding); |
Fcheck_coding_system (encoding); |
6164 |
p->encode_coding_system = Fcheck_coding_system (encoding); |
|
6165 |
setup_coding_system (decoding, |
p->decode_coding_system = decoding; |
6166 |
proc_decode_coding_system[XINT (p->infd)]); |
p->encode_coding_system = encoding; |
6167 |
setup_coding_system (encoding, |
setup_process_coding_systems (proc); |
|
proc_encode_coding_system[XINT (p->outfd)]); |
|
6168 |
|
|
6169 |
return Qnil; |
return Qnil; |
6170 |
} |
} |
6179 |
return Fcons (XPROCESS (proc)->decode_coding_system, |
return Fcons (XPROCESS (proc)->decode_coding_system, |
6180 |
XPROCESS (proc)->encode_coding_system); |
XPROCESS (proc)->encode_coding_system); |
6181 |
} |
} |
6182 |
|
|
6183 |
|
DEFUN ("set-process-filter-multibyte", Fset_process_filter_multibyte, |
6184 |
|
Sset_process_filter_multibyte, 2, 2, 0, |
6185 |
|
doc: /* Set multibyteness of the strings given to PROCESS's filter. |
6186 |
|
If FLAG is non-nil, the filter is given multibyte strings. |
6187 |
|
If FLAG is nil, the filter is given unibyte strings. In this case, |
6188 |
|
all character code conversion except for end-of-line conversion is |
6189 |
|
suppressed. */) |
6190 |
|
(proc, flag) |
6191 |
|
Lisp_Object proc, flag; |
6192 |
|
{ |
6193 |
|
register struct Lisp_Process *p; |
6194 |
|
|
6195 |
|
CHECK_PROCESS (proc); |
6196 |
|
p = XPROCESS (proc); |
6197 |
|
p->filter_multibyte = flag; |
6198 |
|
setup_process_coding_systems (proc); |
6199 |
|
|
6200 |
|
return Qnil; |
6201 |
|
} |
6202 |
|
|
6203 |
|
DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p, |
6204 |
|
Sprocess_filter_multibyte_p, 1, 1, 0, |
6205 |
|
doc: /* Return t if a multibyte string is given to PROCESS's filter.*/) |
6206 |
|
(proc) |
6207 |
|
Lisp_Object proc; |
6208 |
|
{ |
6209 |
|
register struct Lisp_Process *p; |
6210 |
|
|
6211 |
|
CHECK_PROCESS (proc); |
6212 |
|
p = XPROCESS (proc); |
6213 |
|
|
6214 |
|
return (NILP (p->filter_multibyte) ? Qnil : Qt); |
6215 |
|
} |
6216 |
|
|
6217 |
|
|
6218 |
|
|
6219 |
/* The first time this is called, assume keyboard input comes from DESC |
/* The first time this is called, assume keyboard input comes from DESC |
6220 |
instead of from where we used to expect it. |
instead of from where we used to expect it. |
6416 |
staticpro (&QCstop); |
staticpro (&QCstop); |
6417 |
QCoptions = intern (":options"); |
QCoptions = intern (":options"); |
6418 |
staticpro (&QCoptions); |
staticpro (&QCoptions); |
6419 |
|
QCplist = intern (":plist"); |
6420 |
|
staticpro (&QCplist); |
6421 |
|
QCfilter_multibyte = intern (":filter-multibyte"); |
6422 |
|
staticpro (&QCfilter_multibyte); |
6423 |
|
|
6424 |
Qlast_nonmenu_event = intern ("last-nonmenu-event"); |
Qlast_nonmenu_event = intern ("last-nonmenu-event"); |
6425 |
staticpro (&Qlast_nonmenu_event); |
staticpro (&Qlast_nonmenu_event); |
6426 |
|
|
6463 |
defsubr (&Sset_process_query_on_exit_flag); |
defsubr (&Sset_process_query_on_exit_flag); |
6464 |
defsubr (&Sprocess_query_on_exit_flag); |
defsubr (&Sprocess_query_on_exit_flag); |
6465 |
defsubr (&Sprocess_contact); |
defsubr (&Sprocess_contact); |
6466 |
|
defsubr (&Sprocess_plist); |
6467 |
|
defsubr (&Sset_process_plist); |
6468 |
defsubr (&Slist_processes); |
defsubr (&Slist_processes); |
6469 |
defsubr (&Sprocess_list); |
defsubr (&Sprocess_list); |
6470 |
defsubr (&Sstart_process); |
defsubr (&Sstart_process); |
6471 |
#ifdef HAVE_SOCKETS |
#ifdef HAVE_SOCKETS |
6472 |
defsubr (&Sset_network_process_options); |
defsubr (&Sset_network_process_options); |
6473 |
defsubr (&Smake_network_process); |
defsubr (&Smake_network_process); |
6474 |
|
defsubr (&Sformat_network_address); |
6475 |
#endif /* HAVE_SOCKETS */ |
#endif /* HAVE_SOCKETS */ |
6476 |
#ifdef DATAGRAM_SOCKETS |
#ifdef DATAGRAM_SOCKETS |
6477 |
defsubr (&Sprocess_datagram_address); |
defsubr (&Sprocess_datagram_address); |
6492 |
/* defsubr (&Sprocess_connection); */ |
/* defsubr (&Sprocess_connection); */ |
6493 |
defsubr (&Sset_process_coding_system); |
defsubr (&Sset_process_coding_system); |
6494 |
defsubr (&Sprocess_coding_system); |
defsubr (&Sprocess_coding_system); |
6495 |
|
defsubr (&Sset_process_filter_multibyte); |
6496 |
|
defsubr (&Sprocess_filter_multibyte_p); |
6497 |
} |
} |
6498 |
|
|
6499 |
|
|
6552 |
int xerrno; |
int xerrno; |
6553 |
/* Either nil or a cons cell, the car of which is of interest and |
/* Either nil or a cons cell, the car of which is of interest and |
6554 |
may be changed outside of this routine. */ |
may be changed outside of this routine. */ |
6555 |
Lisp_Object wait_for_cell = Qnil; |
Lisp_Object wait_for_cell; |
6556 |
|
|
6557 |
|
wait_for_cell = Qnil; |
6558 |
|
|
6559 |
/* If waiting for non-nil in a cell, record where. */ |
/* If waiting for non-nil in a cell, record where. */ |
6560 |
if (CONSP (read_kbd)) |
if (CONSP (read_kbd)) |
6572 |
} |
} |
6573 |
|
|
6574 |
/* Turn off periodic alarms (in case they are in use) |
/* Turn off periodic alarms (in case they are in use) |
6575 |
|
and then turn off any other atimers, |
6576 |
because the select emulator uses alarms. */ |
because the select emulator uses alarms. */ |
6577 |
|
stop_polling (); |
6578 |
turn_on_atimers (0); |
turn_on_atimers (0); |
6579 |
|
|
6580 |
while (1) |
while (1) |