aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorGlenn Morris2008-06-13 08:08:20 +0000
committerGlenn Morris2008-06-13 08:08:20 +0000
commitd888760c951787ccc3a48d7f90bc798ee0996b9b (patch)
tree1aabac1ac803d6d2e8614eef3dcf35874e5841de /src/process.c
parent07d99e7544ffa51339ae1ba1a3785f49247e0c6e (diff)
downloademacs-d888760c951787ccc3a48d7f90bc798ee0996b9b.tar.gz
emacs-d888760c951787ccc3a48d7f90bc798ee0996b9b.zip
Daniel Engeler <engeler at gmail.com>
These changes add serial port access. * process.c: Add HAVE_SERIAL. (Fdelete_process, Fprocess_status, Fset_process_buffer) (Fset_process_filter, Fset_process_sentinel, Fprocess_contact) (list_processes_1, select_wrapper, Fstop_process) (Fcontinue_process, Fprocess_send_eof, kill_buffer_processes) (status_notify): Modify to handle serial processes. [HAVE_SERIAL] (Fserial_process_configure) [HAVE_SERIAL] (make_serial_process_unwind, Fmake_serial_process): New functions. * process.h (struct Lisp_Process): Add `type'. * sysdep.c [HAVE_TERMIOS] (serial_open, serial_configure): New functions. * w32.c (_sys_read_ahead, sys_read, sys_write): Modify to handle serial ports. (serial_open, serial_configure) New functions. * w32.h: Add FILE_SERIAL. (struct _child_process): Add ovl_read, ovl_write.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c496
1 files changed, 459 insertions, 37 deletions
diff --git a/src/process.c b/src/process.c
index 413bd8522b3..1d49f8fc2b4 100644
--- a/src/process.c
+++ b/src/process.c
@@ -136,9 +136,13 @@ Lisp_Object Qprocessp;
136Lisp_Object Qrun, Qstop, Qsignal; 136Lisp_Object Qrun, Qstop, Qsignal;
137Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; 137Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
138Lisp_Object Qlocal, Qipv4, Qdatagram; 138Lisp_Object Qlocal, Qipv4, Qdatagram;
139Lisp_Object Qreal, Qnetwork, Qserial;
139#ifdef AF_INET6 140#ifdef AF_INET6
140Lisp_Object Qipv6; 141Lisp_Object Qipv6;
141#endif 142#endif
143Lisp_Object QCport, QCspeed, QCprocess;
144Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
145Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
142Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; 146Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
143Lisp_Object QClocal, QCremote, QCcoding; 147Lisp_Object QClocal, QCremote, QCcoding;
144Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; 148Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
@@ -155,15 +159,16 @@ extern Lisp_Object QCfamily;
155/* QCfilter is defined in keyboard.c. */ 159/* QCfilter is defined in keyboard.c. */
156extern Lisp_Object QCfilter; 160extern Lisp_Object QCfilter;
157 161
158/* a process object is a network connection when its childp field is neither
159 Qt nor Qnil but is instead a property list (KEY VAL ...). */
160
161#ifdef HAVE_SOCKETS 162#ifdef HAVE_SOCKETS
162#define NETCONN_P(p) (CONSP (XPROCESS (p)->childp)) 163#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
163#define NETCONN1_P(p) (CONSP ((p)->childp)) 164#define NETCONN1_P(p) (EQ ((p)->type, Qnetwork))
165#define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial))
166#define SERIALCONN1_P(p) (EQ ((p)->type, Qserial))
164#else 167#else
165#define NETCONN_P(p) 0 168#define NETCONN_P(p) 0
166#define NETCONN1_P(p) 0 169#define NETCONN1_P(p) 0
170#define SERIALCONN_P(p) 0
171#define SERIALCONN1_P(p) 0
167#endif /* HAVE_SOCKETS */ 172#endif /* HAVE_SOCKETS */
168 173
169/* Define first descriptor number available for subprocesses. */ 174/* Define first descriptor number available for subprocesses. */
@@ -186,6 +191,17 @@ extern Lisp_Object QCfilter;
186 191
187extern char *get_operating_system_release (); 192extern char *get_operating_system_release ();
188 193
194/* Serial processes require termios or Windows. */
195#if defined (HAVE_TERMIOS) || defined (WINDOWSNT)
196#define HAVE_SERIAL
197#endif
198
199#ifdef HAVE_SERIAL
200/* From sysdep.c or w32.c */
201extern int serial_open (char *port);
202extern void serial_configure (struct Lisp_Process *p, Lisp_Object contact);
203#endif
204
189#ifndef USE_CRT_DLL 205#ifndef USE_CRT_DLL
190extern int errno; 206extern int errno;
191#endif 207#endif
@@ -784,7 +800,7 @@ nil, indicating the current buffer's process. */)
784 p = XPROCESS (process); 800 p = XPROCESS (process);
785 801
786 p->raw_status_new = 0; 802 p->raw_status_new = 0;
787 if (NETCONN1_P (p)) 803 if (NETCONN1_P (p) || SERIALCONN1_P (p))
788 { 804 {
789 p->status = Fcons (Qexit, Fcons (make_number (0), Qnil)); 805 p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
790 p->tick = ++process_tick; 806 p->tick = ++process_tick;
@@ -861,7 +877,7 @@ nil, indicating the current buffer's process. */)
861 status = p->status; 877 status = p->status;
862 if (CONSP (status)) 878 if (CONSP (status))
863 status = XCAR (status); 879 status = XCAR (status);
864 if (NETCONN1_P (p)) 880 if (NETCONN1_P (p) || SERIALCONN1_P (p))
865 { 881 {
866 if (EQ (status, Qexit)) 882 if (EQ (status, Qexit))
867 status = Qclosed; 883 status = Qclosed;
@@ -919,7 +935,8 @@ DEFUN ("process-command", Fprocess_command, Sprocess_command, 1, 1, 0,
919 doc: /* Return the command that was executed to start PROCESS. 935 doc: /* Return the command that was executed to start PROCESS.
920This is a list of strings, the first string being the program executed 936This is a list of strings, the first string being the program executed
921and the rest of the strings being the arguments given to it. 937and the rest of the strings being the arguments given to it.
922For a non-child channel, this is nil. */) 938For a network or serial process, this is nil (process is running) or t
939\(process is stopped). */)
923 (process) 940 (process)
924 register Lisp_Object process; 941 register Lisp_Object process;
925{ 942{
@@ -951,7 +968,7 @@ DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer,
951 CHECK_BUFFER (buffer); 968 CHECK_BUFFER (buffer);
952 p = XPROCESS (process); 969 p = XPROCESS (process);
953 p->buffer = buffer; 970 p->buffer = buffer;
954 if (NETCONN1_P (p)) 971 if (NETCONN1_P (p) || SERIALCONN1_P (p))
955 p->childp = Fplist_put (p->childp, QCbuffer, buffer); 972 p->childp = Fplist_put (p->childp, QCbuffer, buffer);
956 setup_process_coding_systems (process); 973 setup_process_coding_systems (process);
957 return buffer; 974 return buffer;
@@ -1018,7 +1035,8 @@ The string argument is normally a multibyte string, except:
1018 FD_CLR (p->infd, &non_keyboard_wait_mask); 1035 FD_CLR (p->infd, &non_keyboard_wait_mask);
1019 } 1036 }
1020 else if (EQ (p->filter, Qt) 1037 else if (EQ (p->filter, Qt)
1021 && !EQ (p->command, Qt)) /* Network process not stopped. */ 1038 /* Network or serial process not stopped: */
1039 && !EQ (p->command, Qt))
1022 { 1040 {
1023 FD_SET (p->infd, &input_wait_mask); 1041 FD_SET (p->infd, &input_wait_mask);
1024 FD_SET (p->infd, &non_keyboard_wait_mask); 1042 FD_SET (p->infd, &non_keyboard_wait_mask);
@@ -1026,7 +1044,7 @@ The string argument is normally a multibyte string, except:
1026 } 1044 }
1027 1045
1028 p->filter = filter; 1046 p->filter = filter;
1029 if (NETCONN1_P (p)) 1047 if (NETCONN1_P (p) || SERIALCONN1_P (p))
1030 p->childp = Fplist_put (p->childp, QCfilter, filter); 1048 p->childp = Fplist_put (p->childp, QCfilter, filter);
1031 setup_process_coding_systems (process); 1049 setup_process_coding_systems (process);
1032 return filter; 1050 return filter;
@@ -1057,7 +1075,7 @@ It gets two arguments: the process, and a string describing the change. */)
1057 p = XPROCESS (process); 1075 p = XPROCESS (process);
1058 1076
1059 p->sentinel = sentinel; 1077 p->sentinel = sentinel;
1060 if (NETCONN1_P (p)) 1078 if (NETCONN1_P (p) || SERIALCONN1_P (p))
1061 p->childp = Fplist_put (p->childp, QCsentinel, sentinel); 1079 p->childp = Fplist_put (p->childp, QCsentinel, sentinel);
1062 return sentinel; 1080 return sentinel;
1063} 1081}
@@ -1162,11 +1180,13 @@ Lisp_Object Fprocess_datagram_address ();
1162DEFUN ("process-contact", Fprocess_contact, Sprocess_contact, 1180DEFUN ("process-contact", Fprocess_contact, Sprocess_contact,
1163 1, 2, 0, 1181 1, 2, 0,
1164 doc: /* Return the contact info of PROCESS; t for a real child. 1182 doc: /* Return the contact info of PROCESS; t for a real child.
1165For a net connection, the value depends on the optional KEY arg. 1183For a network or serial connection, the value depends on the optional
1166If KEY is nil, value is a cons cell of the form (HOST SERVICE), 1184KEY arg. If KEY is nil, value is a cons cell of the form (HOST
1167if KEY is t, the complete contact information for the connection is 1185SERVICE) for a network connection or (PORT SPEED) for a serial
1168returned, else the specific value for the keyword KEY is returned. 1186connection. If KEY is t, the complete contact information for the
1169See `make-network-process' for a list of keywords. */) 1187connection is returned, else the specific value for the keyword KEY is
1188returned. See `make-network-process' or `make-serial-process' for a
1189list of keywords. */)
1170 (process, key) 1190 (process, key)
1171 register Lisp_Object process, key; 1191 register Lisp_Object process, key;
1172{ 1192{
@@ -1182,11 +1202,14 @@ See `make-network-process' for a list of keywords. */)
1182 Fprocess_datagram_address (process)); 1202 Fprocess_datagram_address (process));
1183#endif 1203#endif
1184 1204
1185 if (!NETCONN_P (process) || EQ (key, Qt)) 1205 if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt))
1186 return contact; 1206 return contact;
1187 if (NILP (key)) 1207 if (NILP (key) && NETCONN_P (process))
1188 return Fcons (Fplist_get (contact, QChost), 1208 return Fcons (Fplist_get (contact, QChost),
1189 Fcons (Fplist_get (contact, QCservice), Qnil)); 1209 Fcons (Fplist_get (contact, QCservice), Qnil));
1210 if (NILP (key) && SERIALCONN_P (process))
1211 return Fcons (Fplist_get (contact, QCport),
1212 Fcons (Fplist_get (contact, QCspeed), Qnil));
1190 return Fplist_get (contact, key); 1213 return Fplist_get (contact, key);
1191} 1214}
1192 1215
@@ -1225,6 +1248,19 @@ a socket connection. */)
1225 return XPROCESS (process)->type; 1248 return XPROCESS (process)->type;
1226} 1249}
1227#endif 1250#endif
1251
1252DEFUN ("process-type", Fprocess_type, Sprocess_type, 1, 1, 0,
1253 doc: /* Return the connection type of PROCESS.
1254The value is either the symbol `real', `network', or `serial'.
1255PROCESS may be a process, a buffer, the name of a process or buffer, or
1256nil, indicating the current buffer's process. */)
1257 (process)
1258 Lisp_Object process;
1259{
1260 Lisp_Object proc;
1261 proc = get_process (process);
1262 return XPROCESS (proc)->type;
1263}
1228 1264
1229#ifdef HAVE_SOCKETS 1265#ifdef HAVE_SOCKETS
1230DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, 1266DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address,
@@ -1325,7 +1361,7 @@ list_processes_1 (query_only)
1325 1361
1326 proc = Fcdr (XCAR (tail)); 1362 proc = Fcdr (XCAR (tail));
1327 p = XPROCESS (proc); 1363 p = XPROCESS (proc);
1328 if (NILP (p->childp)) 1364 if (NILP (p->type))
1329 continue; 1365 continue;
1330 if (!NILP (query_only) && p->kill_without_query) 1366 if (!NILP (query_only) && p->kill_without_query)
1331 continue; 1367 continue;
@@ -1393,7 +1429,7 @@ list_processes_1 (query_only)
1393 1429
1394 proc = Fcdr (XCAR (tail)); 1430 proc = Fcdr (XCAR (tail));
1395 p = XPROCESS (proc); 1431 p = XPROCESS (proc);
1396 if (NILP (p->childp)) 1432 if (NILP (p->type))
1397 continue; 1433 continue;
1398 if (!NILP (query_only) && p->kill_without_query) 1434 if (!NILP (query_only) && p->kill_without_query)
1399 continue; 1435 continue;
@@ -1418,7 +1454,7 @@ list_processes_1 (query_only)
1418#endif 1454#endif
1419 Fprinc (symbol, Qnil); 1455 Fprinc (symbol, Qnil);
1420 } 1456 }
1421 else if (NETCONN1_P (p)) 1457 else if (NETCONN1_P (p) || SERIALCONN1_P (p))
1422 { 1458 {
1423 if (EQ (symbol, Qexit)) 1459 if (EQ (symbol, Qexit))
1424 write_string ("closed", -1); 1460 write_string ("closed", -1);
@@ -1429,6 +1465,10 @@ list_processes_1 (query_only)
1429 else 1465 else
1430 Fprinc (symbol, Qnil); 1466 Fprinc (symbol, Qnil);
1431 } 1467 }
1468 else if (SERIALCONN1_P (p))
1469 {
1470 write_string ("running", -1);
1471 }
1432 else 1472 else
1433 Fprinc (symbol, Qnil); 1473 Fprinc (symbol, Qnil);
1434 1474
@@ -1493,6 +1533,22 @@ list_processes_1 (query_only)
1493 (STRINGP (host) ? (char *)SDATA (host) : "?")); 1533 (STRINGP (host) ? (char *)SDATA (host) : "?"));
1494 insert_string (tembuf); 1534 insert_string (tembuf);
1495 } 1535 }
1536 else if (SERIALCONN1_P (p))
1537 {
1538 Lisp_Object port = Fplist_get (p->childp, QCport);
1539 Lisp_Object speed = Fplist_get (p->childp, QCspeed);
1540 insert_string ("(serial port ");
1541 if (STRINGP (port))
1542 insert_string (SDATA (port));
1543 else
1544 insert_string ("?");
1545 if (INTEGERP (speed))
1546 {
1547 sprintf (tembuf, " at %d b/s", XINT (speed));
1548 insert_string (tembuf);
1549 }
1550 insert_string (")\n");
1551 }
1496 else 1552 else
1497 { 1553 {
1498 tem = p->command; 1554 tem = p->command;
@@ -1619,6 +1675,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1619 1675
1620 XPROCESS (proc)->childp = Qt; 1676 XPROCESS (proc)->childp = Qt;
1621 XPROCESS (proc)->plist = Qnil; 1677 XPROCESS (proc)->plist = Qnil;
1678 XPROCESS (proc)->type = Qreal;
1622 XPROCESS (proc)->buffer = buffer; 1679 XPROCESS (proc)->buffer = buffer;
1623 XPROCESS (proc)->sentinel = Qnil; 1680 XPROCESS (proc)->sentinel = Qnil;
1624 XPROCESS (proc)->filter = Qnil; 1681 XPROCESS (proc)->filter = Qnil;
@@ -2656,6 +2713,312 @@ unwind_request_sigio (dummy)
2656} 2713}
2657#endif 2714#endif
2658 2715
2716#ifdef HAVE_SERIAL
2717DEFUN ("serial-process-configure",
2718 Fserial_process_configure,
2719 Sserial_process_configure,
2720 0, MANY, 0,
2721 doc: /* Configure speed, bytesize, etc. of a serial process.
2722
2723Arguments are specified as keyword/argument pairs. Attributes that
2724are not given are re-initialized from the process's current
2725configuration (available via the function `process-contact') or set to
2726reasonable default values. The following arguments are defined:
2727
2728:process PROCESS
2729:name NAME
2730:buffer BUFFER
2731:port PORT
2732-- Any of these arguments can be given to identify the process that is
2733to be configured. If none of these arguments is given, the current
2734buffer's process is used.
2735
2736:speed SPEED -- SPEED is the speed of the serial port in bits per
2737second, also called baud rate. Any value can be given for SPEED, but
2738most serial ports work only at a few defined values between 1200 and
2739115200, with 9600 being the most common value. If SPEED is nil, the
2740serial port is not configured any further, i.e., all other arguments
2741are ignored. This may be useful for special serial ports such as
2742Bluetooth-to-serial converters which can only be configured through AT
2743commands. A value of nil for SPEED can be used only when passed
2744through `make-serial-process' or `serial-term'.
2745
2746:bytesize BYTESIZE -- BYTESIZE is the number of bits per byte, which
2747can be 7 or 8. If BYTESIZE is not given or nil, a value of 8 is used.
2748
2749:parity PARITY -- PARITY can be nil (don't use parity), the symbol
2750`odd' (use odd parity), or the symbol `even' (use even parity). If
2751PARITY is not given, no parity is used.
2752
2753:stopbits STOPBITS -- STOPBITS is the number of stopbits used to
2754terminate a byte transmission. STOPBITS can be 1 or 2. If STOPBITS
2755is not given or nil, 1 stopbit is used.
2756
2757:flowcontrol FLOWCONTROL -- FLOWCONTROL determines the type of
2758flowcontrol to be used, which is either nil (don't use flowcontrol),
2759the symbol `hw' (use RTS/CTS hardware flowcontrol), or the symbol `sw'
2760\(use XON/XOFF software flowcontrol). If FLOWCONTROL is not given, no
2761flowcontrol is used.
2762
2763`serial-process-configure' is called by `make-serial-process' for the
2764initial configuration of the serial port.
2765
2766Examples:
2767
2768\(serial-process-configure :process "/dev/ttyS0" :speed 1200)
2769
2770\(serial-process-configure
2771 :buffer "COM1" :stopbits 1 :parity 'odd :flowcontrol 'hw)
2772
2773\(serial-process-configure :port "\\\\.\\COM13" :bytesize 7)
2774
2775usage: (serial-process-configure &rest ARGS) */)
2776 (nargs, args)
2777 int nargs;
2778 Lisp_Object *args;
2779{
2780 struct Lisp_Process *p;
2781 Lisp_Object contact = Qnil;
2782 Lisp_Object proc = Qnil;
2783 struct gcpro gcpro1;
2784
2785 contact = Flist (nargs, args);
2786 GCPRO1 (contact);
2787
2788 proc = Fplist_get (contact, QCprocess);
2789 if (NILP (proc))
2790 proc = Fplist_get (contact, QCname);
2791 if (NILP (proc))
2792 proc = Fplist_get (contact, QCbuffer);
2793 if (NILP (proc))
2794 proc = Fplist_get (contact, QCport);
2795 proc = get_process (proc);
2796 p = XPROCESS (proc);
2797 if (p->type != Qserial)
2798 error ("Not a serial process");
2799
2800 if (NILP (Fplist_get (p->childp, QCspeed)))
2801 {
2802 UNGCPRO;
2803 return Qnil;
2804 }
2805
2806 serial_configure (p, contact);
2807
2808 UNGCPRO;
2809 return Qnil;
2810}
2811#endif /* HAVE_SERIAL */
2812
2813#ifdef HAVE_SERIAL
2814/* Used by make-serial-process to recover from errors. */
2815Lisp_Object make_serial_process_unwind (Lisp_Object proc)
2816{
2817 if (!PROCESSP (proc))
2818 abort ();
2819 remove_process (proc);
2820 return Qnil;
2821}
2822#endif /* HAVE_SERIAL */
2823
2824#ifdef HAVE_SERIAL
2825DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
2826 0, MANY, 0,
2827 doc: /* Create and return a serial port process.
2828
2829In Emacs, serial port connections are represented by process objects,
2830so input and output work as for subprocesses, and `delete-process'
2831closes a serial port connection. However, a serial process has no
2832process id, it cannot be signaled, and the status codes are different
2833from normal processes.
2834
2835`make-serial-process' creates a process and a buffer, on which you
2836probably want to use `process-send-string'. Try \\[serial-term] for
2837an interactive terminal. See below for examples.
2838
2839Arguments are specified as keyword/argument pairs. The following
2840arguments are defined:
2841
2842:port PORT -- (mandatory) PORT is the path or name of the serial port.
2843For example, this could be "/dev/ttyS0" on Unix. On Windows, this
2844could be "COM1", or "\\\\.\\COM10" for ports higher than COM9 (double
2845the backslashes in strings).
2846
2847:speed SPEED -- (mandatory) is handled by `serial-process-configure',
2848which is called by `make-serial-process'.
2849
2850:name NAME -- NAME is the name of the process. If NAME is not given,
2851the value of PORT is used.
2852
2853:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
2854with the process. Process output goes at the end of that buffer,
2855unless you specify an output stream or filter function to handle the
2856output. If BUFFER is not given, the value of NAME is used.
2857
2858:coding CODING -- If CODING is a symbol, it specifies the coding
2859system used for both reading and writing for this process. If CODING
2860is a cons (DECODING . ENCODING), DECODING is used for reading, and
2861ENCODING is used for writing.
2862
2863:noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and
2864the process is running. If BOOL is not given, query before exiting.
2865
2866:stop BOOL -- Start process in the `stopped' state if BOOL is non-nil.
2867In the stopped state, a serial process does not accept incoming data,
2868but you can send outgoing data. The stopped state is cleared by
2869`continue-process' and set by `stop-process'.
2870
2871:filter FILTER -- Install FILTER as the process filter.
2872
2873:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
2874
2875:plist PLIST -- Install PLIST as the initial plist of the process.
2876
2877:speed
2878:bytesize
2879:parity
2880:stopbits
2881:flowcontrol
2882-- These arguments are handled by `serial-process-configure', which is
2883called by `make-serial-process'.
2884
2885The original argument list, possibly modified by later configuration,
2886is available via the function `process-contact'.
2887
2888Examples:
2889
2890\(make-serial-process :port "/dev/ttyS0" :speed 9600)
2891
2892\(make-serial-process :port "COM1" :speed 115200 :stopbits 2)
2893
2894\(make-serial-process :port "\\\\.\\COM13" :speed 1200 :bytesize 7 :parity 'odd)
2895
2896\(make-serial-process :port "/dev/tty.BlueConsole-SPP-1" :speed nil)
2897
2898usage: (make-serial-process &rest ARGS) */)
2899 (nargs, args)
2900 int nargs;
2901 Lisp_Object *args;
2902{
2903 int fd = -1;
2904 Lisp_Object proc, contact, port;
2905 struct Lisp_Process *p;
2906 struct gcpro gcpro1;
2907 Lisp_Object name, buffer;
2908 Lisp_Object tem, val;
2909 int specpdl_count = -1;
2910
2911 if (nargs == 0)
2912 return Qnil;
2913
2914 contact = Flist (nargs, args);
2915 GCPRO1 (contact);
2916
2917 port = Fplist_get (contact, QCport);
2918 if (NILP (port))
2919 error ("No port specified");
2920 CHECK_STRING (port);
2921
2922 if (NILP (Fplist_member (contact, QCspeed)))
2923 error (":speed not specified");
2924 if (!NILP (Fplist_get (contact, QCspeed)))
2925 CHECK_NUMBER (Fplist_get (contact, QCspeed));
2926
2927 name = Fplist_get (contact, QCname);
2928 if (NILP (name))
2929 name = port;
2930 CHECK_STRING (name);
2931 proc = make_process (name);
2932 specpdl_count = SPECPDL_INDEX ();
2933 record_unwind_protect (make_serial_process_unwind, proc);
2934 p = XPROCESS (proc);
2935
2936 fd = serial_open ((char*) SDATA (port));
2937 p->infd = fd;
2938 p->outfd = fd;
2939 if (fd > max_process_desc)
2940 max_process_desc = fd;
2941 chan_process[fd] = proc;
2942
2943 buffer = Fplist_get (contact, QCbuffer);
2944 if (NILP (buffer))
2945 buffer = name;
2946 buffer = Fget_buffer_create (buffer);
2947 p->buffer = buffer;
2948
2949 p->childp = contact;
2950 p->plist = Fcopy_sequence (Fplist_get (contact, QCplist));
2951 p->type = Qserial;
2952 p->sentinel = Fplist_get (contact, QCsentinel);
2953 p->filter = Fplist_get (contact, QCfilter);
2954 p->log = Qnil;
2955 if (tem = Fplist_get (contact, QCnoquery), !NILP (tem))
2956 p->kill_without_query = 1;
2957 if (tem = Fplist_get (contact, QCstop), !NILP (tem))
2958 p->command = Qt;
2959 p->pty_flag = 0;
2960
2961 if (!EQ (p->command, Qt))
2962 {
2963 FD_SET (fd, &input_wait_mask);
2964 FD_SET (fd, &non_keyboard_wait_mask);
2965 }
2966
2967 if (BUFFERP (buffer))
2968 {
2969 set_marker_both (p->mark, buffer,
2970 BUF_ZV (XBUFFER (buffer)),
2971 BUF_ZV_BYTE (XBUFFER (buffer)));
2972 }
2973
2974 tem = Fplist_member (contact, QCcoding);
2975 if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
2976 tem = Qnil;
2977
2978 val = Qnil;
2979 if (!NILP (tem))
2980 {
2981 val = XCAR (XCDR (tem));
2982 if (CONSP (val))
2983 val = XCAR (val);
2984 }
2985 else if (!NILP (Vcoding_system_for_read))
2986 val = Vcoding_system_for_read;
2987 else if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters))
2988 || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)))
2989 val = Qnil;
2990 p->decode_coding_system = val;
2991
2992 val = Qnil;
2993 if (!NILP (tem))
2994 {
2995 val = XCAR (XCDR (tem));
2996 if (CONSP (val))
2997 val = XCDR (val);
2998 }
2999 else if (!NILP (Vcoding_system_for_write))
3000 val = Vcoding_system_for_write;
3001 else if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters))
3002 || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)))
3003 val = Qnil;
3004 p->encode_coding_system = val;
3005
3006 setup_process_coding_systems (proc);
3007 p->decoding_buf = make_uninit_string (0);
3008 p->decoding_carryover = 0;
3009 p->encoding_buf = make_uninit_string (0);
3010 p->inherit_coding_system_flag
3011 = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
3012
3013 Fserial_process_configure(nargs, args);
3014
3015 specpdl_ptr = specpdl + specpdl_count;
3016
3017 UNGCPRO;
3018 return proc;
3019}
3020#endif /* HAVE_SERIAL */
3021
2659/* Create a network stream/datagram client/server process. Treated 3022/* Create a network stream/datagram client/server process. Treated
2660 exactly like a normal process when reading and writing. Primary 3023 exactly like a normal process when reading and writing. Primary
2661 differences are in status display and process deletion. A network 3024 differences are in status display and process deletion. A network
@@ -3395,6 +3758,7 @@ usage: (make-network-process &rest ARGS) */)
3395 3758
3396 p->childp = contact; 3759 p->childp = contact;
3397 p->plist = Fcopy_sequence (Fplist_get (contact, QCplist)); 3760 p->plist = Fcopy_sequence (Fplist_get (contact, QCplist));
3761 p->type = Qnetwork;
3398 3762
3399 p->buffer = buffer; 3763 p->buffer = buffer;
3400 p->sentinel = sentinel; 3764 p->sentinel = sentinel;
@@ -4113,6 +4477,7 @@ server_accept_connection (server, channel)
4113 4477
4114 p->childp = contact; 4478 p->childp = contact;
4115 p->plist = Fcopy_sequence (ps->plist); 4479 p->plist = Fcopy_sequence (ps->plist);
4480 p->type = Qnetwork;
4116 4481
4117 p->buffer = buffer; 4482 p->buffer = buffer;
4118 p->sentinel = ps->sentinel; 4483 p->sentinel = ps->sentinel;
@@ -4811,7 +5176,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4811 available now and a closed pipe. 5176 available now and a closed pipe.
4812 With luck, a closed pipe will be accompanied by 5177 With luck, a closed pipe will be accompanied by
4813 subprocess termination and SIGCHLD. */ 5178 subprocess termination and SIGCHLD. */
4814 else if (nread == 0 && !NETCONN_P (proc)) 5179 else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc))
4815 ; 5180 ;
4816#endif /* O_NDELAY */ 5181#endif /* O_NDELAY */
4817#endif /* O_NONBLOCK */ 5182#endif /* O_NONBLOCK */
@@ -4839,7 +5204,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4839 /* If we can detect process termination, don't consider the process 5204 /* If we can detect process termination, don't consider the process
4840 gone just because its pipe is closed. */ 5205 gone just because its pipe is closed. */
4841#ifdef SIGCHLD 5206#ifdef SIGCHLD
4842 else if (nread == 0 && !NETCONN_P (proc)) 5207 else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc))
4843 ; 5208 ;
4844#endif 5209#endif
4845 else 5210 else
@@ -5628,7 +5993,7 @@ send_process (proc, buf, len, object)
5628 this -= rv; 5993 this -= rv;
5629 } 5994 }
5630 5995
5631 /* If we sent just part of the string, put in an EOF 5996 /* If we sent just part of the string, put in an EOF (C-d)
5632 to force it through, before we send the rest. */ 5997 to force it through, before we send the rest. */
5633 if (len > 0) 5998 if (len > 0)
5634 Fprocess_send_eof (proc); 5999 Fprocess_send_eof (proc);
@@ -5748,7 +6113,7 @@ return t unconditionally. */)
5748 proc = get_process (process); 6113 proc = get_process (process);
5749 p = XPROCESS (proc); 6114 p = XPROCESS (proc);
5750 6115
5751 if (!EQ (p->childp, Qt)) 6116 if (!EQ (p->type, Qreal))
5752 error ("Process %s is not a subprocess", 6117 error ("Process %s is not a subprocess",
5753 SDATA (p->name)); 6118 SDATA (p->name));
5754 if (p->infd < 0) 6119 if (p->infd < 0)
@@ -5791,7 +6156,7 @@ process_send_signal (process, signo, current_group, nomsg)
5791 proc = get_process (process); 6156 proc = get_process (process);
5792 p = XPROCESS (proc); 6157 p = XPROCESS (proc);
5793 6158
5794 if (!EQ (p->childp, Qt)) 6159 if (!EQ (p->type, Qreal))
5795 error ("Process %s is not a subprocess", 6160 error ("Process %s is not a subprocess",
5796 SDATA (p->name)); 6161 SDATA (p->name));
5797 if (p->infd < 0) 6162 if (p->infd < 0)
@@ -6040,12 +6405,13 @@ See function `interrupt-process' for more details on usage. */)
6040DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0, 6405DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0,
6041 doc: /* Stop process PROCESS. May be process or name of one. 6406 doc: /* Stop process PROCESS. May be process or name of one.
6042See function `interrupt-process' for more details on usage. 6407See function `interrupt-process' for more details on usage.
6043If PROCESS is a network process, inhibit handling of incoming traffic. */) 6408If PROCESS is a network or serial process, inhibit handling of incoming
6409traffic. */)
6044 (process, current_group) 6410 (process, current_group)
6045 Lisp_Object process, current_group; 6411 Lisp_Object process, current_group;
6046{ 6412{
6047#ifdef HAVE_SOCKETS 6413#ifdef HAVE_SOCKETS
6048 if (PROCESSP (process) && NETCONN_P (process)) 6414 if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process)))
6049 { 6415 {
6050 struct Lisp_Process *p; 6416 struct Lisp_Process *p;
6051 6417
@@ -6071,12 +6437,13 @@ If PROCESS is a network process, inhibit handling of incoming traffic. */)
6071DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0, 6437DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0,
6072 doc: /* Continue process PROCESS. May be process or name of one. 6438 doc: /* Continue process PROCESS. May be process or name of one.
6073See function `interrupt-process' for more details on usage. 6439See function `interrupt-process' for more details on usage.
6074If PROCESS is a network process, resume handling of incoming traffic. */) 6440If PROCESS is a network or serial process, resume handling of incoming
6441traffic. */)
6075 (process, current_group) 6442 (process, current_group)
6076 Lisp_Object process, current_group; 6443 Lisp_Object process, current_group;
6077{ 6444{
6078#ifdef HAVE_SOCKETS 6445#ifdef HAVE_SOCKETS
6079 if (PROCESSP (process) && NETCONN_P (process)) 6446 if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process)))
6080 { 6447 {
6081 struct Lisp_Process *p; 6448 struct Lisp_Process *p;
6082 6449
@@ -6087,6 +6454,13 @@ If PROCESS is a network process, resume handling of incoming traffic. */)
6087 { 6454 {
6088 FD_SET (p->infd, &input_wait_mask); 6455 FD_SET (p->infd, &input_wait_mask);
6089 FD_SET (p->infd, &non_keyboard_wait_mask); 6456 FD_SET (p->infd, &non_keyboard_wait_mask);
6457#ifdef WINDOWSNT
6458 if (fd_info[ p->infd ].flags & FILE_SERIAL)
6459 PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR);
6460#endif
6461#ifdef HAVE_TERMIOS
6462 tcflush (p->infd, TCIFLUSH);
6463#endif
6090 } 6464 }
6091 p->command = Qnil; 6465 p->command = Qnil;
6092 return process; 6466 return process;
@@ -6272,7 +6646,9 @@ PROCESS may be a process, a buffer, the name of a process or buffer, or
6272nil, indicating the current buffer's process. 6646nil, indicating the current buffer's process.
6273If PROCESS is a network connection, or is a process communicating 6647If PROCESS is a network connection, or is a process communicating
6274through a pipe (as opposed to a pty), then you cannot send any more 6648through a pipe (as opposed to a pty), then you cannot send any more
6275text to PROCESS after you call this function. */) 6649text to PROCESS after you call this function.
6650If PROCESS is a serial process, wait until all output written to the
6651process has been transmitted to the serial port. */)
6276 (process) 6652 (process)
6277 Lisp_Object process; 6653 Lisp_Object process;
6278{ 6654{
@@ -6302,6 +6678,14 @@ text to PROCESS after you call this function. */)
6302#else 6678#else
6303 if (XPROCESS (proc)->pty_flag) 6679 if (XPROCESS (proc)->pty_flag)
6304 send_process (proc, "\004", 1, Qnil); 6680 send_process (proc, "\004", 1, Qnil);
6681 else if (XPROCESS (proc)->type == Qserial)
6682 {
6683#ifdef HAVE_TERMIOS
6684 if (tcdrain (XPROCESS (proc)->outfd) != 0)
6685 error ("tcdrain() failed: %s", emacs_strerror (errno));
6686#endif
6687 /* Do nothing on Windows because writes are blocking. */
6688 }
6305 else 6689 else
6306 { 6690 {
6307 int old_outfd, new_outfd; 6691 int old_outfd, new_outfd;
@@ -6311,7 +6695,7 @@ text to PROCESS after you call this function. */)
6311 for communication with the subprocess, call shutdown to cause EOF. 6695 for communication with the subprocess, call shutdown to cause EOF.
6312 (In some old system, shutdown to socketpair doesn't work. 6696 (In some old system, shutdown to socketpair doesn't work.
6313 Then we just can't win.) */ 6697 Then we just can't win.) */
6314 if (XPROCESS (proc)->pid == 0 6698 if (XPROCESS (proc)->type == Qnetwork
6315 || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) 6699 || XPROCESS (proc)->outfd == XPROCESS (proc)->infd)
6316 shutdown (XPROCESS (proc)->outfd, 1); 6700 shutdown (XPROCESS (proc)->outfd, 1);
6317 /* In case of socketpair, outfd == infd, so don't close it. */ 6701 /* In case of socketpair, outfd == infd, so don't close it. */
@@ -6355,7 +6739,7 @@ kill_buffer_processes (buffer)
6355 if (PROCESSP (proc) 6739 if (PROCESSP (proc)
6356 && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) 6740 && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
6357 { 6741 {
6358 if (NETCONN_P (proc)) 6742 if (NETCONN_P (proc) || SERIALCONN_P (proc))
6359 Fdelete_process (proc); 6743 Fdelete_process (proc);
6360 else if (XPROCESS (proc)->infd >= 0) 6744 else if (XPROCESS (proc)->infd >= 0)
6361 process_send_signal (proc, SIGHUP, Qnil, 1); 6745 process_send_signal (proc, SIGHUP, Qnil, 1);
@@ -6464,7 +6848,7 @@ sigchld_handler (signo)
6464 { 6848 {
6465 proc = XCDR (XCAR (tail)); 6849 proc = XCDR (XCAR (tail));
6466 p = XPROCESS (proc); 6850 p = XPROCESS (proc);
6467 if (EQ (p->childp, Qt) && p->pid == pid) 6851 if (EQ (p->type, Qreal) && p->pid == pid)
6468 break; 6852 break;
6469 p = 0; 6853 p = 0;
6470 } 6854 }
@@ -6686,7 +7070,8 @@ status_notify (deleting_process)
6686 while (! EQ (p->filter, Qt) 7070 while (! EQ (p->filter, Qt)
6687 && ! EQ (p->status, Qconnect) 7071 && ! EQ (p->status, Qconnect)
6688 && ! EQ (p->status, Qlisten) 7072 && ! EQ (p->status, Qlisten)
6689 && ! EQ (p->command, Qt) /* Network process not stopped. */ 7073 /* Network or serial process not stopped: */
7074 && ! EQ (p->command, Qt)
6690 && p->infd >= 0 7075 && p->infd >= 0
6691 && p != deleting_process 7076 && p != deleting_process
6692 && read_process_output (proc, p->infd) > 0); 7077 && read_process_output (proc, p->infd) > 0);
@@ -7073,6 +7458,39 @@ syms_of_process ()
7073 Qdatagram = intern ("datagram"); 7458 Qdatagram = intern ("datagram");
7074 staticpro (&Qdatagram); 7459 staticpro (&Qdatagram);
7075 7460
7461 QCport = intern (":port");
7462 staticpro (&QCport);
7463 QCspeed = intern (":speed");
7464 staticpro (&QCspeed);
7465 QCprocess = intern (":process");
7466 staticpro (&QCprocess);
7467
7468 QCbytesize = intern (":bytesize");
7469 staticpro (&QCbytesize);
7470 QCstopbits = intern (":stopbits");
7471 staticpro (&QCstopbits);
7472 QCparity = intern (":parity");
7473 staticpro (&QCparity);
7474 Qodd = intern ("odd");
7475 staticpro (&Qodd);
7476 Qeven = intern ("even");
7477 staticpro (&Qeven);
7478 QCflowcontrol = intern (":flowcontrol");
7479 staticpro (&QCflowcontrol);
7480 Qhw = intern ("hw");
7481 staticpro (&Qhw);
7482 Qsw = intern ("sw");
7483 staticpro (&Qsw);
7484 QCsummary = intern (":summary");
7485 staticpro (&QCsummary);
7486
7487 Qreal = intern ("real");
7488 staticpro (&Qreal);
7489 Qnetwork = intern ("network");
7490 staticpro (&Qnetwork);
7491 Qserial = intern ("serial");
7492 staticpro (&Qserial);
7493
7076 QCname = intern (":name"); 7494 QCname = intern (":name");
7077 staticpro (&QCname); 7495 staticpro (&QCname);
7078 QCbuffer = intern (":buffer"); 7496 QCbuffer = intern (":buffer");
@@ -7170,6 +7588,10 @@ The variable takes effect when `start-process' is called. */);
7170 defsubr (&Slist_processes); 7588 defsubr (&Slist_processes);
7171 defsubr (&Sprocess_list); 7589 defsubr (&Sprocess_list);
7172 defsubr (&Sstart_process); 7590 defsubr (&Sstart_process);
7591#ifdef HAVE_SERIAL
7592 defsubr (&Sserial_process_configure);
7593 defsubr (&Smake_serial_process);
7594#endif /* HAVE_SERIAL */
7173#ifdef HAVE_SOCKETS 7595#ifdef HAVE_SOCKETS
7174 defsubr (&Sset_network_process_option); 7596 defsubr (&Sset_network_process_option);
7175 defsubr (&Smake_network_process); 7597 defsubr (&Smake_network_process);
@@ -7199,7 +7621,7 @@ The variable takes effect when `start-process' is called. */);
7199 defsubr (&Sprocess_send_eof); 7621 defsubr (&Sprocess_send_eof);
7200 defsubr (&Ssignal_process); 7622 defsubr (&Ssignal_process);
7201 defsubr (&Swaiting_for_user_input_p); 7623 defsubr (&Swaiting_for_user_input_p);
7202/* defsubr (&Sprocess_connection); */ 7624 defsubr (&Sprocess_type);
7203 defsubr (&Sset_process_coding_system); 7625 defsubr (&Sset_process_coding_system);
7204 defsubr (&Sprocess_coding_system); 7626 defsubr (&Sprocess_coding_system);
7205 defsubr (&Sset_process_filter_multibyte); 7627 defsubr (&Sset_process_filter_multibyte);