summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/alloc.c6
-rw-r--r--src/callproc.c287
-rw-r--r--src/dispnew.c9
-rw-r--r--src/fileio.c3
-rw-r--r--src/fns.c79
-rw-r--r--src/gtkutil.c7
-rw-r--r--src/image.c8
-rw-r--r--src/lisp.h8
-rw-r--r--src/process.c157
-rw-r--r--src/sysdep.c26
-rw-r--r--src/w32.h2
-rw-r--r--src/w32proc.c4
13 files changed, 323 insertions, 275 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index bd38b016fa6..c2641740bcc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -343,7 +343,7 @@ HAVE_PDUMPER = @HAVE_PDUMPER@
## ARM Macs require that all code have a valid signature. Since pump
## invalidates the signature, we must re-sign to fix it.
-DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@)
+DO_CODESIGN=$(patsubst arm-apple-darwin%,yes,@configuration@)
# 'make' verbosity.
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
diff --git a/src/alloc.c b/src/alloc.c
index 25153621298..754b8f2aef8 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -732,7 +732,11 @@ static void
malloc_unblock_input (void)
{
if (block_input_in_memory_allocators)
- unblock_input ();
+ {
+ int err = errno;
+ unblock_input ();
+ errno = err;
+ }
}
# define MALLOC_BLOCK_INPUT malloc_block_input ()
# define MALLOC_UNBLOCK_INPUT malloc_unblock_input ()
diff --git a/src/callproc.c b/src/callproc.c
index c7f560ac3da..3ecd6880274 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -100,6 +100,15 @@ enum
};
static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t);
+
+#ifdef DOS_NT
+# define CHILD_SETUP_TYPE int
+#else
+# define CHILD_SETUP_TYPE _Noreturn void
+#endif
+
+static CHILD_SETUP_TYPE child_setup (int, int, int, char **, char **,
+ const char *);
/* Return the current buffer's working directory, or the home
directory if it's unreachable, as a string suitable for a system call.
@@ -300,8 +309,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
char *tempfile = NULL;
#else
- sigset_t oldset;
- pid_t pid;
+ pid_t pid = -1;
#endif
int child_errno;
int fd_output, fd_error;
@@ -541,7 +549,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
callproc_fd[CALLPROC_STDERR] = fd_error;
}
- char *const *env = make_environment_block (current_dir);
+ char **env = make_environment_block (current_dir);
#ifdef MSDOS /* MW, July 1993 */
status = child_setup (filefd, fd_output, fd_error, new_argv, env,
@@ -588,77 +596,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
#ifndef MSDOS
- block_input ();
- block_child_signal (&oldset);
-
-#ifdef WINDOWSNT
- pid = child_setup (filefd, fd_output, fd_error, new_argv, env,
- SSDATA (current_dir));
-#else /* not WINDOWSNT */
-
- /* vfork, and prevent local vars from being clobbered by the vfork. */
- {
- Lisp_Object volatile buffer_volatile = buffer;
- Lisp_Object volatile coding_systems_volatile = coding_systems;
- Lisp_Object volatile current_dir_volatile = current_dir;
- bool volatile display_p_volatile = display_p;
- int volatile fd_error_volatile = fd_error;
- int volatile filefd_volatile = filefd;
- ptrdiff_t volatile count_volatile = count;
- ptrdiff_t volatile sa_avail_volatile = sa_avail;
- ptrdiff_t volatile sa_count_volatile = sa_count;
- char **volatile new_argv_volatile = new_argv;
- char *const *volatile env_volatile = env;
- int volatile callproc_fd_volatile[CALLPROC_FDS];
- for (i = 0; i < CALLPROC_FDS; i++)
- callproc_fd_volatile[i] = callproc_fd[i];
-
- pid = vfork ();
-
- buffer = buffer_volatile;
- coding_systems = coding_systems_volatile;
- current_dir = current_dir_volatile;
- display_p = display_p_volatile;
- fd_error = fd_error_volatile;
- filefd = filefd_volatile;
- count = count_volatile;
- sa_avail = sa_avail_volatile;
- sa_count = sa_count_volatile;
- new_argv = new_argv_volatile;
- env = env_volatile;
-
- for (i = 0; i < CALLPROC_FDS; i++)
- callproc_fd[i] = callproc_fd_volatile[i];
- fd_output = callproc_fd[CALLPROC_STDOUT];
- }
-
- if (pid == 0)
- {
-#ifdef DARWIN_OS
- /* Work around a macOS bug, where SIGCHLD is apparently
- delivered to a vforked child instead of to its parent. See:
- https://lists.gnu.org/r/emacs-devel/2017-05/msg00342.html
- */
- signal (SIGCHLD, SIG_DFL);
-#endif
-
- unblock_child_signal (&oldset);
- dissociate_controlling_tty ();
-
- /* Emacs ignores SIGPIPE, but the child should not. */
- signal (SIGPIPE, SIG_DFL);
- /* Likewise for SIGPROF. */
-#ifdef SIGPROF
- signal (SIGPROF, SIG_DFL);
-#endif
-
- child_setup (filefd, fd_output, fd_error, new_argv, env,
- SSDATA (current_dir));
- }
-
-#endif /* not WINDOWSNT */
-
- child_errno = errno;
+ child_errno
+ = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env,
+ SSDATA (current_dir), NULL);
+ eassert ((child_errno == 0) == (0 < pid));
if (pid > 0)
{
@@ -678,9 +619,6 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
}
}
- unblock_child_signal (&oldset);
- unblock_input ();
-
if (pid < 0)
report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno);
@@ -1194,16 +1132,6 @@ exec_failed (char const *name, int err)
_exit (err == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
}
-#else
-
-/* Do nothing. There is no need to fail, as DOS_NT platforms do not
- fork and exec, and handle alloca exhaustion in a different way. */
-
-static void
-exec_failed (char const *name, int err)
-{
-}
-
#endif
/* This is the last thing run in a newly forked inferior
@@ -1221,9 +1149,9 @@ exec_failed (char const *name, int err)
On MS-Windows, either return a pid or return -1 and set errno.
On MS-DOS, either return an exit status or signal an error. */
-CHILD_SETUP_TYPE
-child_setup (int in, int out, int err, char *const *new_argv,
- char *const *env, const char *current_dir)
+static CHILD_SETUP_TYPE
+child_setup (int in, int out, int err, char **new_argv, char **env,
+ const char *current_dir)
{
#ifdef WINDOWSNT
int cpid;
@@ -1287,6 +1215,183 @@ child_setup (int in, int out, int err, char *const *new_argv,
#endif /* not WINDOWSNT */
}
+/* Start a new asynchronous subprocess. If successful, return zero
+ and store the process identifier of the new process in *NEWPID.
+ Use STDIN, STDOUT, and STDERR as standard streams for the new
+ process. Use ARGV as argument vector for the new process; use
+ process image file ARGV[0]. Use ENVP for the environment block for
+ the new process. Use CWD as working directory for the new process.
+ If PTY is not NULL, it must be a pseudoterminal device. If PTY is
+ NULL, don't perform any terminal setup. */
+
+int
+emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
+ char **argv, char **envp, const char *cwd, const char *pty)
+{
+ sigset_t oldset;
+ int pid;
+
+ block_input ();
+ block_child_signal (&oldset);
+
+#ifndef WINDOWSNT
+ /* vfork, and prevent local vars from being clobbered by the vfork. */
+ pid_t *volatile newpid_volatile = newpid;
+ const char *volatile cwd_volatile = cwd;
+ const char *volatile pty_volatile = pty;
+ char **volatile argv_volatile = argv;
+ int volatile stdin_volatile = std_in;
+ int volatile stdout_volatile = std_out;
+ int volatile stderr_volatile = std_err;
+ char **volatile envp_volatile = envp;
+
+#ifdef DARWIN_OS
+ /* Darwin doesn't let us run setsid after a vfork, so use fork when
+ necessary. Below, we reset SIGCHLD handling after a vfork, as
+ apparently macOS can mistakenly deliver SIGCHLD to the child. */
+ if (pty != NULL)
+ pid = fork ();
+ else
+ pid = vfork ();
+#else
+ pid = vfork ();
+#endif
+
+ newpid = newpid_volatile;
+ cwd = cwd_volatile;
+ pty = pty_volatile;
+ argv = argv_volatile;
+ std_in = stdin_volatile;
+ std_out = stdout_volatile;
+ std_err = stderr_volatile;
+ envp = envp_volatile;
+
+ if (pid == 0)
+#endif /* not WINDOWSNT */
+ {
+ bool pty_flag = pty != NULL;
+ /* Make the pty be the controlling terminal of the process. */
+#ifdef HAVE_PTYS
+ dissociate_controlling_tty ();
+
+ /* Make the pty's terminal the controlling terminal. */
+ if (pty_flag && std_in >= 0)
+ {
+#ifdef TIOCSCTTY
+ /* We ignore the return value
+ because faith@cs.unc.edu says that is necessary on Linux. */
+ ioctl (std_in, TIOCSCTTY, 0);
+#endif
+ }
+#if defined (LDISC1)
+ if (pty_flag && std_in >= 0)
+ {
+ struct termios t;
+ tcgetattr (std_in, &t);
+ t.c_lflag = LDISC1;
+ if (tcsetattr (std_in, TCSANOW, &t) < 0)
+ emacs_perror ("create_process/tcsetattr LDISC1");
+ }
+#else
+#if defined (NTTYDISC) && defined (TIOCSETD)
+ if (pty_flag && std_in >= 0)
+ {
+ /* Use new line discipline. */
+ int ldisc = NTTYDISC;
+ ioctl (std_in, TIOCSETD, &ldisc);
+ }
+#endif
+#endif
+
+#if !defined (DONT_REOPEN_PTY)
+/*** There is a suggestion that this ought to be a
+ conditional on TIOCSPGRP, or !defined TIOCSCTTY.
+ Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
+ that system does seem to need this code, even though
+ both TIOCSCTTY is defined. */
+ /* Now close the pty (if we had it open) and reopen it.
+ This makes the pty the controlling terminal of the subprocess. */
+ if (pty_flag)
+ {
+
+ /* I wonder if emacs_close (emacs_open (pty, ...))
+ would work? */
+ if (std_in >= 0)
+ emacs_close (std_in);
+ std_out = std_in = emacs_open (pty, O_RDWR, 0);
+
+ if (std_in < 0)
+ {
+ emacs_perror (pty);
+ _exit (EXIT_CANCELED);
+ }
+
+ }
+#endif /* not DONT_REOPEN_PTY */
+
+#ifdef SETUP_SLAVE_PTY
+ if (pty_flag)
+ {
+ SETUP_SLAVE_PTY;
+ }
+#endif /* SETUP_SLAVE_PTY */
+#endif /* HAVE_PTYS */
+
+#ifdef DARWIN_OS
+ /* Work around a macOS bug, where SIGCHLD is apparently
+ delivered to a vforked child instead of to its parent. See:
+ https://lists.gnu.org/r/emacs-devel/2017-05/msg00342.html
+ */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+
+ signal (SIGINT, SIG_DFL);
+ signal (SIGQUIT, SIG_DFL);
+#ifdef SIGPROF
+ signal (SIGPROF, SIG_DFL);
+#endif
+
+ /* Emacs ignores SIGPIPE, but the child should not. */
+ signal (SIGPIPE, SIG_DFL);
+ /* Likewise for SIGPROF. */
+#ifdef SIGPROF
+ signal (SIGPROF, SIG_DFL);
+#endif
+
+ /* Stop blocking SIGCHLD in the child. */
+ unblock_child_signal (&oldset);
+
+ if (pty_flag)
+ child_setup_tty (std_out);
+
+ if (std_err < 0)
+ std_err = std_out;
+#ifdef WINDOWSNT
+ pid = child_setup (std_in, std_out, std_err, argv, envp, cwd);
+#else /* not WINDOWSNT */
+ child_setup (std_in, std_out, std_err, argv, envp, cwd);
+#endif /* not WINDOWSNT */
+ }
+
+ /* Back in the parent process. */
+
+ int vfork_error = pid < 0 ? errno : 0;
+
+ /* Stop blocking in the parent. */
+ unblock_child_signal (&oldset);
+ unblock_input ();
+
+ if (pid < 0)
+ {
+ eassert (0 < vfork_error);
+ return vfork_error;
+ }
+
+ eassert (0 < pid);
+ *newpid = pid;
+ return 0;
+}
+
static bool
getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value,
ptrdiff_t *valuelen, Lisp_Object env)
@@ -1415,7 +1520,7 @@ egetenv_internal (const char *var, ptrdiff_t len)
objects. Don't call any Lisp code or the garbage collector while
the block is active. */
-char *const *
+char **
make_environment_block (Lisp_Object current_dir)
{
char **env;
diff --git a/src/dispnew.c b/src/dispnew.c
index 89dd32ad0fb..e0a64761904 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6057,6 +6057,8 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
intmax_t sec;
int nsec;
bool do_display = display_option > 0;
+ bool curbuf_eq_winbuf
+ = (current_buffer == XBUFFER (XWINDOW (selected_window)->contents));
swallow_events (do_display);
@@ -6111,6 +6113,13 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
Qnil, NULL, 0);
+ if (reading && curbuf_eq_winbuf)
+ /* Timers and process filters/sentinels may have changed the selected
+ window (e.g. in response to a connection from emacsclient), in which
+ case we should follow it (unless we weren't in the selected-window's
+ buffer to start with). */
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
+
return detect_input_pending () ? Qnil : Qt;
}
diff --git a/src/fileio.c b/src/fileio.c
index 651e765fca4..23b4523c944 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3050,7 +3050,6 @@ file_accessible_directory_p (Lisp_Object file)
ptrdiff_t len = SBYTES (file);
char const *dir;
bool ok;
- int saved_errno;
USE_SAFE_ALLOCA;
/* Normally a file "FOO" is an accessible directory if "FOO/." exists.
@@ -3075,9 +3074,7 @@ file_accessible_directory_p (Lisp_Object file)
}
ok = file_access_p (dir, F_OK);
- saved_errno = errno;
SAFE_FREE ();
- errno = saved_errno;
return ok;
#endif /* !DOS_NT */
}
diff --git a/src/fns.c b/src/fns.c
index 646c3ed0834..2de1d26dd31 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -105,9 +105,14 @@ list_length (Lisp_Object list)
DEFUN ("length", Flength, Slength, 1, 1, 0,
doc: /* Return the length of vector, list or string SEQUENCE.
A byte-code function object is also allowed.
+
If the string contains multibyte characters, this is not necessarily
the number of bytes in the string; it is the number of characters.
-To get the number of bytes, use `string-bytes'. */)
+To get the number of bytes, use `string-bytes'.
+
+If the length of a list is being computed to compare to a (small)
+number, the `length<', `length>' and `length=' functions may be more
+efficient. */)
(Lisp_Object sequence)
{
EMACS_INT val;
@@ -145,6 +150,75 @@ least the number of distinct elements. */)
return make_fixnum (len);
}
+static inline
+EMACS_INT length_internal (Lisp_Object sequence, int len)
+{
+ /* If LENGTH is short (arbitrarily chosen cut-off point), use a
+ fast loop that doesn't care about whether SEQUENCE is
+ circular or not. */
+ if (len < 0xffff)
+ while (CONSP (sequence))
+ {
+ if (--len <= 0)
+ return -1;
+ sequence = XCDR (sequence);
+ }
+ /* Signal an error on circular lists. */
+ else
+ FOR_EACH_TAIL (sequence)
+ if (--len <= 0)
+ return -1;
+ return len;
+}
+
+DEFUN ("length<", Flength_less, Slength_less, 2, 2, 0,
+ doc: /* Return non-nil if SEQUENCE is shorter than LENGTH.
+See `length' for allowed values of SEQUENCE and how elements are
+counted. */)
+ (Lisp_Object sequence, Lisp_Object length)
+{
+ CHECK_FIXNUM (length);
+ EMACS_INT len = XFIXNUM (length);
+
+ if (CONSP (sequence))
+ return length_internal (sequence, len) == -1? Qnil: Qt;
+ else
+ return XFIXNUM (Flength (sequence)) < len? Qt: Qnil;
+}
+
+DEFUN ("length>", Flength_greater, Slength_greater, 2, 2, 0,
+ doc: /* Return non-nil if SEQUENCE is longer than LENGTH.
+See `length' for allowed values of SEQUENCE and how elements are
+counted. */)
+ (Lisp_Object sequence, Lisp_Object length)
+{
+ CHECK_FIXNUM (length);
+ EMACS_INT len = XFIXNUM (length);
+
+ if (CONSP (sequence))
+ return length_internal (sequence, len + 1) == -1? Qt: Qnil;
+ else
+ return XFIXNUM (Flength (sequence)) > len? Qt: Qnil;
+}
+
+DEFUN ("length=", Flength_equal, Slength_equal, 2, 2, 0,
+ doc: /* Return non-nil if SEQUENCE has length equal to LENGTH.
+See `length' for allowed values of SEQUENCE and how elements are
+counted. */)
+ (Lisp_Object sequence, Lisp_Object length)
+{
+ CHECK_FIXNUM (length);
+ EMACS_INT len = XFIXNUM (length);
+
+ if (len < 0)
+ return Qnil;
+
+ if (CONSP (sequence))
+ return length_internal (sequence, len + 1) == 1? Qt: Qnil;
+ else
+ return XFIXNUM (Flength (sequence)) == len? Qt: Qnil;
+}
+
DEFUN ("proper-list-p", Fproper_list_p, Sproper_list_p, 1, 1, 0,
doc: /* Return OBJECT's length if it is a proper list, nil otherwise.
A proper list is neither circular nor dotted (i.e., its last cdr is nil). */
@@ -5721,6 +5795,9 @@ this variable. */);
defsubr (&Srandom);
defsubr (&Slength);
defsubr (&Ssafe_length);
+ defsubr (&Slength_less);
+ defsubr (&Slength_greater);
+ defsubr (&Slength_equal);
defsubr (&Sproper_list_p);
defsubr (&Sstring_bytes);
defsubr (&Sstring_distance);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index fafd94c0f71..807ee17fa30 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -2944,14 +2944,11 @@ xg_get_menu_item_label (GtkMenuItem *witem)
static bool
xg_item_label_same_p (GtkMenuItem *witem, const char *label)
{
- bool is_same = 0;
char *utf8_label = get_utf8_string (label);
const char *old_label = witem ? xg_get_menu_item_label (witem) : 0;
- if (! old_label && ! utf8_label)
- is_same = 1;
- else if (old_label && utf8_label)
- is_same = strcmp (utf8_label, old_label) == 0;
+ bool is_same = (!old_label == !utf8_label
+ && (!old_label || strcmp (utf8_label, old_label) == 0));
if (utf8_label) g_free (utf8_label);
diff --git a/src/image.c b/src/image.c
index 29cd189f177..e99ba09f515 100644
--- a/src/image.c
+++ b/src/image.c
@@ -9803,8 +9803,9 @@ svg_load (struct frame *f, struct image *img)
}
/* If the file was slurped into memory properly, parse it. */
if (!STRINGP (base_uri))
- base_uri = ENCODE_FILE (file);
- success_p = svg_load_image (f, img, contents, size, SSDATA (base_uri));
+ base_uri = file;
+ success_p = svg_load_image (f, img, contents, size,
+ SSDATA (ENCODE_FILE (base_uri)));
xfree (contents);
}
/* Else it's not a file, it's a Lisp object. Load the image from a
@@ -9822,7 +9823,8 @@ svg_load (struct frame *f, struct image *img)
if (!STRINGP (base_uri))
base_uri = BVAR (current_buffer, filename);
success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
- (NILP (base_uri) ? NULL : SSDATA (base_uri)));
+ (STRINGP (base_uri) ?
+ SSDATA (ENCODE_FILE (base_uri)) : NULL));
}
return success_p;
diff --git a/src/lisp.h b/src/lisp.h
index 103ed079559..efbb7a45242 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4515,16 +4515,14 @@ extern void setup_process_coding_systems (Lisp_Object);
/* Defined in callproc.c. */
#ifdef DOS_NT
-# define CHILD_SETUP_TYPE int
# define CHILD_SETUP_ERROR_DESC "Spawning child process"
#else
-# define CHILD_SETUP_TYPE _Noreturn void
# define CHILD_SETUP_ERROR_DESC "Doing vfork"
#endif
-extern CHILD_SETUP_TYPE child_setup (int, int, int, char *const *,
- char *const *, const char *);
-extern char *const *make_environment_block (Lisp_Object);
+extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *,
+ const char *);
+extern char **make_environment_block (Lisp_Object);
extern void init_callproc_1 (void);
extern void init_callproc (void);
extern void set_initial_environment (void);
diff --git a/src/process.c b/src/process.c
index 15b4a23784e..28ab15c9038 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2047,13 +2047,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
{
struct Lisp_Process *p = XPROCESS (process);
int inchannel, outchannel;
- pid_t pid;
+ pid_t pid = -1;
int vfork_errno;
int forkin, forkout, forkerr = -1;
bool pty_flag = 0;
char pty_name[PTY_NAME_SIZE];
Lisp_Object lisp_pty_name = Qnil;
- sigset_t oldset;
inchannel = outchannel = -1;
@@ -2128,156 +2127,22 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
/* This may signal an error. */
setup_process_coding_systems (process);
- char *const *env = make_environment_block (current_dir);
-
- block_input ();
- block_child_signal (&oldset);
-
-#ifndef WINDOWSNT
- /* vfork, and prevent local vars from being clobbered by the vfork. */
- Lisp_Object volatile current_dir_volatile = current_dir;
- Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name;
- char **volatile new_argv_volatile = new_argv;
- int volatile forkin_volatile = forkin;
- int volatile forkout_volatile = forkout;
- int volatile forkerr_volatile = forkerr;
- struct Lisp_Process *p_volatile = p;
- char *const *volatile env_volatile = env;
-
-#ifdef DARWIN_OS
- /* Darwin doesn't let us run setsid after a vfork, so use fork when
- necessary. Also, reset SIGCHLD handling after a vfork, as
- apparently macOS can mistakenly deliver SIGCHLD to the child. */
- if (pty_flag)
- pid = fork ();
- else
- {
- pid = vfork ();
- if (pid == 0)
- signal (SIGCHLD, SIG_DFL);
- }
-#else
- pid = vfork ();
-#endif
-
- current_dir = current_dir_volatile;
- lisp_pty_name = lisp_pty_name_volatile;
- new_argv = new_argv_volatile;
- forkin = forkin_volatile;
- forkout = forkout_volatile;
- forkerr = forkerr_volatile;
- p = p_volatile;
- env = env_volatile;
+ char **env = make_environment_block (current_dir);
pty_flag = p->pty_flag;
+ eassert (pty_flag == ! NILP (lisp_pty_name));
- if (pid == 0)
-#endif /* not WINDOWSNT */
- {
- /* Make the pty be the controlling terminal of the process. */
-#ifdef HAVE_PTYS
- dissociate_controlling_tty ();
-
- /* Make the pty's terminal the controlling terminal. */
- if (pty_flag && forkin >= 0)
- {
-#ifdef TIOCSCTTY
- /* We ignore the return value
- because faith@cs.unc.edu says that is necessary on Linux. */
- ioctl (forkin, TIOCSCTTY, 0);
-#endif
- }
-#if defined (LDISC1)
- if (pty_flag && forkin >= 0)
- {
- struct termios t;
- tcgetattr (forkin, &t);
- t.c_lflag = LDISC1;
- if (tcsetattr (forkin, TCSANOW, &t) < 0)
- emacs_perror ("create_process/tcsetattr LDISC1");
- }
-#else
-#if defined (NTTYDISC) && defined (TIOCSETD)
- if (pty_flag && forkin >= 0)
- {
- /* Use new line discipline. */
- int ldisc = NTTYDISC;
- ioctl (forkin, TIOCSETD, &ldisc);
- }
-#endif
-#endif
-
-#if !defined (DONT_REOPEN_PTY)
-/*** There is a suggestion that this ought to be a
- conditional on TIOCSPGRP, or !defined TIOCSCTTY.
- Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
- that system does seem to need this code, even though
- both TIOCSCTTY is defined. */
- /* Now close the pty (if we had it open) and reopen it.
- This makes the pty the controlling terminal of the subprocess. */
- if (pty_flag)
- {
+ vfork_errno
+ = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env,
+ SSDATA (current_dir),
+ pty_flag ? SSDATA (lisp_pty_name) : NULL);
- /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...))
- would work? */
- if (forkin >= 0)
- emacs_close (forkin);
- forkout = forkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0);
+ eassert ((vfork_errno == 0) == (0 < pid));
- if (forkin < 0)
- {
- emacs_perror (SSDATA (lisp_pty_name));
- _exit (EXIT_CANCELED);
- }
-
- }
-#endif /* not DONT_REOPEN_PTY */
-
-#ifdef SETUP_SLAVE_PTY
- if (pty_flag)
- {
- SETUP_SLAVE_PTY;
- }
-#endif /* SETUP_SLAVE_PTY */
-#endif /* HAVE_PTYS */
-
- signal (SIGINT, SIG_DFL);
- signal (SIGQUIT, SIG_DFL);
-#ifdef SIGPROF
- signal (SIGPROF, SIG_DFL);
-#endif
-
- /* Emacs ignores SIGPIPE, but the child should not. */
- signal (SIGPIPE, SIG_DFL);
-
- /* Stop blocking SIGCHLD in the child. */
- unblock_child_signal (&oldset);
-
- if (pty_flag)
- child_setup_tty (forkout);
-
- if (forkerr < 0)
- forkerr = forkout;
-#ifdef WINDOWSNT
- pid = child_setup (forkin, forkout, forkerr, new_argv, env,
- SSDATA (current_dir));
-#else /* not WINDOWSNT */
- child_setup (forkin, forkout, forkerr, new_argv, env,
- SSDATA (current_dir));
-#endif /* not WINDOWSNT */
- }
-
- /* Back in the parent process. */
-
- vfork_errno = errno;
p->pid = pid;
if (pid >= 0)
p->alive = 1;
- /* Stop blocking in the parent. */
- unblock_child_signal (&oldset);
- unblock_input ();
-
/* Environment block no longer needed. */
unbind_to (count, Qnil);
@@ -4647,6 +4512,12 @@ network_lookup_address_info_1 (Lisp_Object host, const char *service,
if (STRING_MULTIBYTE (host) && SBYTES (host) != SCHARS (host))
error ("Non-ASCII hostname %s detected, please use puny-encode-domain",
SSDATA (host));
+
+#ifdef WINDOWSNT
+ /* Ensure socket support is loaded if available. */
+ init_winsock (TRUE);
+#endif
+
ret = getaddrinfo (SSDATA (host), service, hints, res);
if (ret)
{
diff --git a/src/sysdep.c b/src/sysdep.c
index 29c88f5308e..eeb9d184940 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -314,33 +314,21 @@ get_current_dir_name_or_unreachable (void)
&& emacs_fstatat (AT_FDCWD, ".", &dotstat, 0) == 0
&& dotstat.st_ino == pwdstat.st_ino
&& dotstat.st_dev == pwdstat.st_dev)
- {
- char *buf = malloc (pwdlen + 1);
- if (!buf)
- return NULL;
- return memcpy (buf, pwd, pwdlen + 1);
- }
+ return strdup (pwd);
else
{
ptrdiff_t buf_size = min (bufsize_max, 1024);
- char *buf = malloc (buf_size);
- if (!buf)
- return NULL;
for (;;)
{
+ char *buf = malloc (buf_size);
+ if (!buf)
+ return NULL;
if (getcwd (buf, buf_size) == buf)
return buf;
- int getcwd_errno = errno;
- if (getcwd_errno != ERANGE || buf_size == bufsize_max)
- {
- free (buf);
- errno = getcwd_errno;
- return NULL;
- }
+ free (buf);
+ if (errno != ERANGE || buf_size == bufsize_max)
+ return NULL;
buf_size = buf_size <= bufsize_max / 2 ? 2 * buf_size : bufsize_max;
- buf = realloc (buf, buf_size);
- if (!buf)
- return NULL;
}
}
}
diff --git a/src/w32.h b/src/w32.h
index 1afb8ad0873..e23ea6a675d 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -216,7 +216,7 @@ extern int sys_rename_replace (char const *, char const *, BOOL);
extern int pipe2 (int *, int);
extern void register_aux_fd (int);
-extern void set_process_dir (char *);
+extern void set_process_dir (const char *);
extern int sys_spawnve (int, char *, char **, char **);
extern void register_child (pid_t, int);
diff --git a/src/w32proc.c b/src/w32proc.c
index 0cf82013065..66cdf7de461 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -3019,9 +3019,9 @@ reset_standard_handles (int in, int out, int err, HANDLE handles[3])
}
void
-set_process_dir (char * dir)
+set_process_dir (const char * dir)
{
- process_dir = dir;
+ process_dir = (char *) dir;
}
/* To avoid problems with winsock implementations that work over dial-up