/* Asynchronous subprocess control for GNU Emacs.
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1996, 1998, 1999, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#include <fcntl.h>
/* Only MS-DOS does not define `subprocesses'. */
#endif
#endif
-#if defined(HAVE_SYS_IOCTL_H)
#include <sys/ioctl.h>
#if defined(HAVE_NET_IF_H)
#include <net/if.h>
#endif /* HAVE_NET_IF_H */
-#endif /* HAVE_SYS_IOCTL_H */
#ifdef NEED_BSDTTY
#include <bsdtty.h>
#endif
-#ifdef HAVE_SYS_WAIT
-#include <sys/wait.h>
-#endif
-
#ifdef HAVE_RES_INIT
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <util.h>
#endif
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#endif
+
#endif /* subprocesses */
#include "lisp.h"
#ifdef HAVE_NS
#include "nsterm.h"
#endif
-extern int timers_run;
Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
static int kbd_is_on_hold;
-/* Nonzero means delete a process right away if it exits. */
-static int delete_exited_processes;
-
/* Nonzero means don't run process sentinels. This is used
when exiting. */
int inhibit_sentinels;
/* Define first descriptor number available for subprocesses. */
#define FIRST_PROC_DESC 3
-/* Define SIGCHLD as an alias for SIGCLD. There are many conditionals
- testing SIGCHLD. */
-
-#if !defined (SIGCHLD) && defined (SIGCLD)
-#define SIGCHLD SIGCLD
-#endif /* SIGCLD */
-
extern const char *get_operating_system_release (void);
/* From sysdep.c or w32.c */
extern int h_errno;
#endif
-/* t means use pty, nil means use a pipe,
- maybe other values to come. */
-static Lisp_Object Vprocess_connection_type;
-
/* These next two vars are non-static since sysdep.c uses them in the
emulation of `select'. */
/* Number of events of change of status of a process. */
/* Define NON_BLOCKING_CONNECT if we can support non-blocking connects. */
+/* Only W32 has this, it really means that select can't take write mask. */
#ifdef BROKEN_NON_BLOCKING_CONNECT
#undef NON_BLOCKING_CONNECT
+#define SELECT_CANT_DO_WRITE_MASK
#else
#ifndef NON_BLOCKING_CONNECT
#ifdef HAVE_SELECT
static int process_output_skip;
-/* Non-nil means to delay reading process output to improve buffering.
- A value of t means that delay is reset after each send, any other
- non-nil value does not reset the delay. A value of nil disables
- adaptive read buffering completely. */
-static Lisp_Object Vprocess_adaptive_read_buffering;
#else
#define process_output_delay_count 0
#endif
/* Maximum number of bytes to send to a pty without an eof. */
static int pty_max_bytes;
-#ifdef HAVE_PTYS
-#ifdef HAVE_PTY_H
-#include <pty.h>
-#endif
-/* The file name of the pty opened by allocate_pty. */
-
-static char pty_name[24];
-#endif
\f
struct fd_callback_data
max_input_desc = fd;
break;
}
-
+
}
}
if (! NILP (Vlocale_coding_system))
string = (code_convert_string_norecord
(string, Vlocale_coding_system, 0));
- c1 = STRING_CHAR ((char *) SDATA (string));
+ c1 = STRING_CHAR (SSDATA (string));
c2 = DOWNCASE (c1);
if (c1 != c2)
Faset (string, make_number (0), make_number (c2));
\f
#ifdef HAVE_PTYS
+/* The file name of the pty opened by allocate_pty. */
+static char pty_name[24];
+
/* Open an available pty, returning a file descriptor.
Return -1 on failure.
The file name of the terminal corresponding to the pty
#ifdef HAVE_GNUTLS
p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
+ p->gnutls_log_level = 0;
+ p->gnutls_p = 0;
#endif
/* If name is already in use, modify it until it is unused. */
port = Fformat_network_address (Fplist_get (p->childp, QClocal), Qnil);
sprintf (tembuf, "(network %s server on %s)\n",
(DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
- (STRINGP (port) ? (char *)SDATA (port) : "?"));
+ (STRINGP (port) ? SSDATA (port) : "?"));
insert_string (tembuf);
}
else if (NETCONN1_P (p))
host = Fformat_network_address (Fplist_get (p->childp, QCremote), Qnil);
sprintf (tembuf, "(network %s connection to %s)\n",
(DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
- (STRINGP (host) ? (char *)SDATA (host) : "?"));
+ (STRINGP (host) ? SSDATA (host) : "?"));
insert_string (tembuf);
}
else if (SERIALCONN1_P (p))
val = XCDR (Vdefault_process_coding_system);
}
XPROCESS (proc)->encode_coding_system = val;
+ /* Note: At this momemnt, the above coding system may leave
+ text-conversion or eol-conversion unspecified. They will be
+ decided after we read output from the process and decode it by
+ some coding system, or just before we actually send a text to
+ the process. */
}
tem = Fsubstring (tem, make_number (2), Qnil);
{
+ Lisp_Object arg_encoding = Qnil;
struct gcpro gcpro1;
GCPRO1 (tem);
tem = Fcons (args[i], tem);
CHECK_STRING (XCAR (tem));
if (STRING_MULTIBYTE (XCAR (tem)))
- XSETCAR (tem,
- code_convert_string_norecord
- (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
+ {
+ if (NILP (arg_encoding))
+ arg_encoding = (complement_process_encoding_system
+ (XPROCESS (proc)->encode_coding_system));
+ XSETCAR (tem,
+ code_convert_string_norecord
+ (XCAR (tem), arg_encoding, 1));
+ }
}
UNGCPRO;
}
#endif
-#if 0
- /* Replaced by close_process_descs */
- set_exclusive_use (inchannel);
- set_exclusive_use (outchannel);
-#endif
-
#ifdef O_NONBLOCK
fcntl (inchannel, F_SETFL, O_NONBLOCK);
fcntl (outchannel, F_SETFL, O_NONBLOCK);
CHECK_SYMBOL (opt);
- name = (char *) SDATA (SYMBOL_NAME (opt));
+ name = SSDATA (SYMBOL_NAME (opt));
for (sopt = socket_options; sopt->name; sopt++)
if (strcmp (name, sopt->name) == 0)
break;
memset (devname, 0, sizeof devname);
if (STRINGP (val))
{
- char *arg = (char *) SDATA (val);
+ char *arg = SSDATA (val);
int len = min (strlen (arg), IFNAMSIZ);
memcpy (devname, arg, len);
}
record_unwind_protect (make_serial_process_unwind, proc);
p = XPROCESS (proc);
- fd = serial_open ((char*) SDATA (port));
+ fd = serial_open (SSDATA (port));
p->infd = fd;
p->outfd = fd;
if (fd > max_process_desc)
/* Attempt to interpret host as numeric inet address */
{
unsigned long numeric_addr;
- numeric_addr = inet_addr ((char *) SDATA (host));
+ numeric_addr = inet_addr (SSDATA (host));
if (numeric_addr == -1)
error ("Unknown host \"%s\"", SDATA (host));
}
\f
-#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_NET_IF_H)
#ifdef SIOCGIFCONF
DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0,
return any ? res : Qnil;
}
#endif
-#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
+#endif /* defined(HAVE_NET_IF_H) */
/* Turn off input and output for process PROC. */
else
Available = input_wait_mask;
Writeok = write_mask;
+#ifdef SELECT_CANT_DO_WRITE_MASK
+ check_write = 0;
+#else
check_write = 1;
+#endif
check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
}
struct Lisp_Process *p;
FD_CLR (channel, &connect_wait_mask);
+ FD_CLR (channel, &write_mask);
if (--num_pending_connects < 0)
abort ();
if (proc_buffered_char[channel] < 0)
{
#ifdef HAVE_GNUTLS
- if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
- nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state,
+ if (XPROCESS (proc)->gnutls_p)
+ nbytes = emacs_gnutls_read (channel, XPROCESS (proc),
chars + carryover, readmax);
else
#endif
chars[carryover] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
#ifdef HAVE_GNUTLS
- if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
- nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state,
+ if (XPROCESS (proc)->gnutls_p)
+ nbytes = emacs_gnutls_read (channel, XPROCESS (proc),
chars + carryover + 1, readmax - 1);
else
#endif
&& !NILP (XBUFFER (object)->enable_multibyte_characters))
|| EQ (object, Qt))
{
+ p->encode_coding_system
+ = complement_process_encoding_system (p->encode_coding_system);
if (!EQ (Vlast_coding_system_used, p->encode_coding_system))
- /* The coding system for encoding was changed to raw-text
- because we sent a unibyte text previously. Now we are
- sending a multibyte text, thus we must encode it by the
- original coding system specified for the current process. */
- setup_coding_system (p->encode_coding_system, coding);
+ {
+ /* The coding system for encoding was changed to raw-text
+ because we sent a unibyte text previously. Now we are
+ sending a multibyte text, thus we must encode it by the
+ original coding system specified for the current process.
+
+ Another reason we comming here is that the coding system
+ was just complemented and new one was returned by
+ complement_process_encoding_system. */
+ setup_coding_system (p->encode_coding_system, coding);
+ Vlast_coding_system_used = p->encode_coding_system;
+ }
coding->src_multibyte = 1;
}
else
#endif
{
#ifdef HAVE_GNUTLS
- if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
+ if (XPROCESS (proc)->gnutls_p)
rv = emacs_gnutls_write (outfd,
- XPROCESS (proc)->gnutls_state,
+ XPROCESS (proc),
(char *) buf, this);
else
#endif
void
add_keyboard_wait_descriptor (int desc)
{
+#ifdef subprocesses /* actually means "not MSDOS" */
FD_SET (desc, &input_wait_mask);
FD_SET (desc, &non_process_wait_mask);
if (desc > max_input_desc)
max_input_desc = desc;
+#endif
}
/* From now on, do not expect DESC to give keyboard input. */
void
delete_keyboard_wait_descriptor (int desc)
{
+#ifdef subprocesses
int fd;
int lim = max_input_desc;
for (fd = 0; fd < lim; fd++)
if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
max_input_desc = fd;
+#endif
}
/* Setup coding systems of PROCESS. */
Qargs = intern_c_string ("args");
staticpro (&Qargs);
- DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
+ DEFVAR_BOOL ("delete-exited-processes", delete_exited_processes,
doc: /* *Non-nil means delete processes immediately when they exit.
A value of nil means don't delete them until `list-processes' is run. */);
delete_exited_processes = 1;
#ifdef subprocesses
- DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type,
+ DEFVAR_LISP ("process-connection-type", Vprocess_connection_type,
doc: /* Control type of device used to communicate with subprocesses.
Values are nil to use a pipe, or t or `pty' to use a pty.
The value has no effect if the system has no ptys or if all ptys are busy:
Vprocess_connection_type = Qt;
#ifdef ADAPTIVE_READ_BUFFERING
- DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
+ DEFVAR_LISP ("process-adaptive-read-buffering", Vprocess_adaptive_read_buffering,
doc: /* If non-nil, improve receive buffering by delaying after short reads.
On some systems, when Emacs reads the output from a subprocess, the output data
is read in very small blocks, potentially resulting in very poor performance.
defsubr (&Sset_network_process_option);
defsubr (&Smake_network_process);
defsubr (&Sformat_network_address);
-#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_NET_IF_H)
#ifdef SIOCGIFCONF
defsubr (&Snetwork_interface_list);
#endif
#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
defsubr (&Snetwork_interface_info);
#endif
-#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
+#endif /* defined(HAVE_NET_IF_H) */
#ifdef DATAGRAM_SOCKETS
defsubr (&Sprocess_datagram_address);
defsubr (&Sset_process_datagram_address);
defsubr (&Slist_system_processes);
defsubr (&Sprocess_attributes);
}
-
-/* arch-tag: 3706c011-7b9a-4117-bd4f-59e7f701a4c4
- (do not change this comment) */