]> code.delx.au - gnu-emacs/commitdiff
Merge from origin/emacs-25
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 May 2016 17:59:29 +0000 (10:59 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 May 2016 17:59:29 +0000 (10:59 -0700)
3b47898 Fix doc string in `insert'
b479dea * doc/misc/emacs-mime.texi (time-date): Document now-builtins...
cd27f73 Say 'All results processed' at the end
4ffec91 Document automatic adjustment of process' logical window dime...
dc66271 ; Fix typos and stylistic glitches in NEWS

1  2 
doc/lispref/processes.texi
doc/misc/emacs-mime.texi
etc/NEWS
src/editfns.c
src/process.c

index e8a9ad05c22b3c9713759375f19f56552e4d5874,03ae1f04349ed8883533f37f7944b2552c33b053..e3346aa3a5bd01ccdbbbea8c1c2ad0a5c9a14e5f
@@@ -1381,6 -1381,58 +1381,58 @@@ Killing the process's buffer deletes th
  subprocess with a @code{SIGHUP} signal (@pxref{Signals to Processes}).
  @end defun
  
+ If the process's buffer is displayed in a window, your Lisp program
+ may wish telling the process the dimensions of that window, so that
+ the process could adapt its output to those dimensions, much as it
+ adapts to the screen dimensions.  The following functions allow to
+ communicate this kind of information to processes; however, not all
+ systems support the underlying functionality, so it is best to provide
+ fallbacks, e.g., via command-line arguments or environment variables.
+ @defun set-process-window-size process height width
+ Tell @var{process} that its logical window size has dimensions
+ @var{width} by @var{height}, in character units.  If this function
+ succeeds in communicating this information to the process, it returns
+ @code{t}; otherwise it returns @code{nil}.
+ @end defun
+ When windows that display buffers associated with process change their
+ dimensions, the affected processes should be told about these changes.
+ By default, when the window configuration changes, Emacs will
+ automatically call @code{set-process-window-size} on behalf of every
+ process whose buffer is displayed in a window, passing it the smallest
+ dimensions of all the windows displaying the process's buffer.  This
+ works via @code{window-configuration-change-hook} (@pxref{Window
+ Hooks}), which is told to invoke the function that is the value of
+ the variable @code{window-adjust-process-window-size-function} for
+ each process whose buffer is displayed in at least one window.  You
+ can customize this behavior by setting the value of that variable.
+ @defopt window-adjust-process-window-size-function
+ The value of this variable should be a function of two arguments: a
+ process and the list of windows displaying the process's buffer.  When
+ the function is called, the process's buffer is the current buffer.
+ The function should return a cons cell @w{@code{(@var{width}
+ . @var{height})}} that describes the dimensions of the logical process
+ window to be passed via a call to @code{set-process-window-size}.  The
+ function can also return @code{nil}, in which case Emacs will not call
+ @code{set-process-window-size} for this process.
+ Emacs supplies two predefined values for this variable:
+ @code{window-adjust-process-window-size-smallest}, which returns the
+ smallest of all the dimensions of the windows that display a process's
+ buffer; and @code{window-adjust-process-window-size-largest}, which
+ returns the largest dimensions.  For more complex strategies, write
+ your own function.
+ This variable can be buffer-local.
+ @end defopt
+ If the process has the @code{adjust-window-size-function} property
+ (@pxref{Process Information}), its value overrides the global and
+ buffer-local values of
+ @code{window-adjust-process-window-size-function}.
  @node Filter Functions
  @subsection Process Filter Functions
  @cindex filter function
@@@ -2128,8 -2180,7 +2180,8 @@@ associated with any buffer
  
  The arguments @var{host} and @var{service} specify where to connect to;
  @var{host} is the host name (a string), and @var{service} is the name of
 -a defined network service (a string) or a port number (an integer).
 +a defined network service (a string) or a port number (an integer like
 +@code{80} or an integer string like @code{"80"}).
  
  The remaining arguments @var{parameters} are keyword/argument pairs
  that are mainly relevant to encrypted connections:
@@@ -2353,9 -2404,8 +2405,9 @@@ connecting to that address will be acce
  
  @item :service @var{service}
  @var{service} specifies a port number to connect to; or, for a server,
 -the port number to listen on.  It should be a service name that
 -translates to a port number, or an integer specifying the port number
 +the port number to listen on.  It should be a service name like
 +@samp{"http"} that translates to a port number, or an integer like @samp{80}
 +or an integer string like @samp{"80"} that specifies the port number
  directly.  For a server, it can also be @code{t}, which means to let
  the system select an unused port number.
  
@@@ -2367,12 -2417,6 +2419,12 @@@ automatically for the given @var{host} 
  ignored.  @code{ipv4} and @code{ipv6} specify to use IPv4 and IPv6,
  respectively.
  
 +@item :use-external-socket @var{use-external-socket}
 +If @var{use-external-socket} is non-@code{nil} use any sockets passed
 +to Emacs on invocation instead of allocating one.  This is used by the
 +Emacs server code to allow on-demand socket activation.  If Emacs
 +wasn't passed a socket, this option is silently ignored.
 +
  @item :local @var{local-address}
  For a server process, @var{local-address} is the address to listen on.
  It overrides @var{family}, @var{host} and @var{service}, so you
@@@ -2423,33 -2467,8 +2475,33 @@@ without waiting for the connection to c
  succeeds or fails, Emacs will call the sentinel function, with a
  second argument matching @code{"open"} (if successful) or
  @code{"failed"}.  The default is to block, so that
 -@code{make-network-process} does not return until the connection
 -has succeeded or failed.
 +@code{make-network-process} does not return until the connection has
 +succeeded or failed.
 +
 +If you're setting up an asynchronous TLS connection, you have to also
 +provide the @code{:tls-parameters} parameter (see below).
 +
 +Depending on the capabilities of Emacs, how asynchronous
 +@code{:nowait} is may vary.  The three elements that may (or may not)
 +be done asynchronously are domain name resolution, socket setup, and
 +(for TLS connections) TLS negotiation.
 +
 +Many functions that interact with process objects, (for instance,
 +@code{process-datagram-address}) rely on them at least having a socket
 +before they can return a useful value.  These functions will block
 +until the socket has achieved the desired status.  The recommended way
 +of interacting with asynchronous sockets is to place a sentinel on the
 +process, and not try to interact with it before it has changed status
 +to @samp{"run"}.  That way, none of these functions will block.
 +
 +@item :tls-parameters
 +When opening a TLS connection, this should be where the first element
 +is the TLS type (which should either be @code{gnutls-x509pki} or
 +@code{gnutls-anon}, and the remaining elements should form a keyword
 +list acceptable for @code{gnutls-boot}.  (This keyword list can be
 +obtained from the @code{gnutls-boot-parameters} function.)  The TLS
 +connection will then be negotiated after completing the connection to
 +the host.
  
  @item :stop @var{stopped}
  If @var{stopped} is non-@code{nil}, start the network connection or
diff --combined doc/misc/emacs-mime.texi
index 2b3bba39ad985698644d8c623a14446b8a1f2983,4d68246bba4bbe7ec5bb4a695024c5be4721389b..2b935870dae73c8e156ae2f42f1efb9e65d048ae
@@@ -1554,7 -1554,7 +1554,7 @@@ Here's a bunch of time/date/second/day 
  (time-less-p '(13818 19266) '(13818 19145))
  @result{} nil
  
- (subtract-time '(13818 19266) '(13818 19145))
+ (time-subtract '(13818 19266) '(13818 19145))
  @result{} (0 121)
  
  (days-between "Sat Sep 12 12:21:54 1998 +0200"
@@@ -1632,14 -1632,14 +1632,14 @@@ return a ``zero'' time
  
  @item time-less-p
  Take two times and say whether the first time is less (i.e., earlier)
- than the second time.
+ than the second time.  (This is a built-in function.)
  
  @item time-since
  Take a time and return a time saying how long it was since that time.
  
- @item subtract-time
+ @item time-subtract
  Take two times and subtract the second from the first.  I.e., return
- the time between the two times.
+ the time between the two times.  (This is a built-in function.)
  
  @item days-between
  Take two days and return the number of days between those two days.
@@@ -1826,11 -1826,6 +1826,11 @@@ matching types
  @vindex mailcap-mime-data
  This variable is an alist of alists containing backup viewing rules.
  
 +@item mailcap-user-mime-data
 +@vindex mailcap-user-mime-data
 +A customizable list of viewers that take preference over
 +@code{mailcap-mime-data}.
 +
  @end table
  
  Interface functions:
diff --combined etc/NEWS
index 22eb2eabc3706f243ed0db4b71bbe3cbf4f773c2,785d14bf2ffcb10b85eb5be66808f3c9360b97c9..b4407a661adc8a83157b61fdd14d95943ffd69db
+++ b/etc/NEWS
@@@ -22,464 -22,6 +22,464 @@@ Temporary note
  When you add a new item, use the appropriate mark if you are sure it applies,
  otherwise leave it unmarked.
  
 +\f
 +* Installation Changes in Emacs 25.2
 +
 +** The new option 'configure --enable-gcc-warnings=warn-only' causes
 +GCC to issue warnings without stopping the build.  This behavior is
 +now the default in developer builds.  As before, use
 +'--disable-gcc-warnings' to suppress GCC's warnings, and
 +'--enable-gcc-warnings' to stop the build if GCC issues warnings.
 +
 ++++
 +** The Emacs server now has socket-launching support.  This allows
 +socket based activation, where an external process like systemd can
 +invoke the Emacs server process upon a socket connection event and
 +hand the socket over to Emacs.  Emacs uses this socket to service
 +emacsclient commands.  This new functionality can be disabled with the
 +configure option '--disable-libsystemd'.
 +
 +** New configure option '--disable-build-details' attempts to build an
 +Emacs that is more likely to be reproducible; that is, if you build
 +and install Emacs twice, the second Emacs is a copy of the first.
 +Deterministic builds omit the build date from the output of the
 +emacs-version and erc-cmd-SV functions, and the leave the following
 +variables nil: emacs-build-system, emacs-build-time,
 +erc-emacs-build-time.
 +
 +** Emacs no longer works on IRIX.  We expect that Emacs users are not
 +affected by this, as SGI stopped supporting IRIX in December 2013.
 +
 +\f
 +* Startup Changes in Emacs 25.2
 +
 +\f
 +* Changes in Emacs 25.2
 +
 +---
 +** 'find-library-name' will now fall back on looking at 'load-history'
 +to try to locate libraries that have been loaded with an explicit path
 +outside 'load-path'.
 +
 ++++
 +** Faces in 'minibuffer-prompt-properties' no longer overwrite properties
 +in the text in functions like 'read-from-minibuffer', but instead are
 +added to the end of the face list.  This allows users to say things
 +like '(read-from-minibuffer (propertize "Enter something: " 'face 'bold))'.
 +
 ++++
 +** The new variable 'extended-command-suggest-shorter' has been added
 +to control whether to suggest shorter 'M-x' commands or not.
 +
 +---
 +** icomplete now respects 'completion-ignored-extensions'.
 +
 ++++
 +** Non-breaking hyphens are now displayed with the 'nobreak-hyphen'
 +face instead of the 'escape-glyph' face.
 +
 +---
 +** 'C-x h' ('mark-whole-buffer') will now avoid marking the prompt
 +part of minibuffers.
 +
 +---
 +** 'find-library' now takes a prefix argument to pop to a different
 +window.
 +
 +** 'find-library', 'help-function-def' and 'help-variable-def' now run
 +'find-function-after-hook'.
 +
 +---
 +** 'process-attributes' on Darwin systems now returns more information.
 +
 ++++
 +** Several accessors for the value returned by 'file-attributes'
 +have been added.  They are: 'file-attribute-type',
 +'file-attribute-link-number', 'file-attribute-user-id',
 +'file-attribute-group-id', 'file-attribute-access-time',
 +'file-attribute-modification-time',
 +'file-attribute-status-change-time', 'file-attribute-size',
 +'file-attribute-modes', 'file-attribute-inode-number', and
 +'file-attribute-device-number'.
 +
 ++++
 +** The new function 'buffer-hash' computes compute a fast, non-consing
 +hash of a buffer's contents.
 +
 +---
 +** 'fill-paragraph' no longer marks the buffer as changed unless it
 +actually changed something.
 +
 +---
 +** The locale language name 'ca' is now mapped to the language
 +environment 'Catalan', which has been added.
 +
 +---
 +** 'align-regexp' has a separate history for its interactive argument.
 +'align-regexp' no longer shares its history with all other
 +history-less functions that use 'read-string'.
 +
 ++++
 +** The networking code has been reworked so that it's more
 +asynchronous than it was (when specifying :nowait t in
 +'make-network-process').  How asynchronous it is varies based on the
 +capabilities of the system, but on a typical GNU/Linux system the DNS
 +resolution, the connection, and (for TLS streams) the TLS negotiation
 +are all done without blocking the main Emacs thread.  To get
 +asynchronous TLS, the TLS boot parameters have to be passed in (see
 +the manual for details).
 +
 +Certain process oriented functions (like 'process-datagram-address')
 +will block until socket setup has been performed.  The recommended way
 +to deal with asynchronous sockets is to avoid interacting with them
 +until they have changed status to "run".  This is most easily done
 +from a process sentinel.
 +
 +** 'make-network-process' and 'open-network-stream' sometimes allowed
 +:service to be an integer string (e.g., :service "993") and sometimes
 +required an integer (e.g., :service 993).  This difference has been
 +eliminated, and integer strings work everywhere.
 +
 +** It is possible to disable attempted recovery on fatal signals.
 +
 +Two new variables support disabling attempts to recover from stack
 +overflow and to avoid automatic auto-save when Emacs is delivered a
 +fatal signal.  'attempt-stack-overflow-recovery', if set to 'nil',
 +will disable attempts to recover from C stack overflows; Emacs will
 +then crash as with any other fatal signal.
 +'attempt-orderly-shutdown-on-fatal-signal', if set to 'nil', will
 +disable attempts to auto-save the session and shut down in an orderly
 +fashion when Emacs receives a fatal signal; instead, Emacs will
 +terminate immediately.  Both variables are non-'nil' by default.
 +These variables are for users who would like to avoid the small
 +probability of data corruption due to techniques Emacs uses to recover
 +in these situations.
 +
 ++++
 +** File local and directory local variables are now initialized each
 +time the major mode is set, not just when the file is first visited.
 +These local variables will thus not vanish on setting a major mode.
 +
 ++++
 +** A second dir-local file (.dir-locals-2.el) is now accepted.
 +See the variable 'dir-locals-file-2' for more information.
 +
 +---
 +** International domain names (IDNA) are now encoded via the new
 +puny.el library, so that one can visit web sites with non-ASCII URLs.
 +
 ++++
 +** The new 'timer-list' command lists all active timers in a buffer,
 +where you can cancel them with the 'c' command.
 +
 ++++
 +** The new function 'read-multiple-choice' prompts for multiple-choice
 +questions, with a handy way to display help texts.
 +
 +\f
 +* Editing Changes in Emacs 25.2
 +
 ++++
 +** New bindings for 'query-replace-map'.
 +'undo', undo the last replacement; bound to 'u'.
 +'undo-all', undo all replacements; bound to 'U'.
 +
 +\f
 +* Changes in Specialized Modes and Packages in Emacs 25.2
 +
 +** Compilation mode
 +
 +---
 +*** Messages from CMake are now recognized.
 +
 +** Dired
 +
 ++++
 +*** In wdired, when editing files to contain slash characters,
 +the resulting directories are automatically created.  Whether to do
 +this is controlled by the 'wdired-create-parent-directories' variable.
 +
 ++++
 +*** 'W' is now bound to 'browse-url-of-dired-file', and is useful for
 +viewing HTML files and the like.
 +
 +** Ediff
 +
 +*** Ediff can be prevented from pausing 1 second after reaching a
 +breakpoint (e.g. with "f" and "o") by customizing the new option
 +`edebug-sit-on-break'.
 +
 +** eww
 +
 ++++
 +*** A new 's' command for switching to another eww buffer via the minibuffer.
 +
 +---
 +*** The 'o' command ('shr-save-contents') has moved to 'O' to avoid collision
 +with the 'o' command from 'image-map'.
 +
 ++++
 +*** A new command 'C' ('eww-toggle-colors') can be used to toggle
 +whether to use the HTML-specified colors or not.  The user can also
 +customize the 'shr-use-colors' variable.
 +
 +---
 +*** Images that are being loaded are now marked with gray
 +"placeholder" images of the size specified by the HTML.  They are then
 +replaced by the real images asynchronously, which will also now
 +respect width/height HTML specs (unless they specify widths/heights
 +bigger than the current window).
 +
 +** Images
 +
 ++++
 +*** Images are automatically scaled before displaying based on the
 +'image-scaling-factor' variable (if Emacs supports scaling the images
 +in question).
 +
 ++++
 +*** Images inserted with 'insert-image' and related functions get a
 +keymap put into the text properties (or overlays) that span the
 +image.  This keymap binds keystrokes for manipulating size and
 +rotation, as well as saving the image to a file.  These commands are
 +also available in 'image-mode'.
 +
 ++++
 +*** A new library for creating and manipulating SVG images has been
 +added.  See the "SVG Images" section in the lispref manual for
 +details.
 +
 ++++
 +*** New setf-able function to access and set image parameters is
 +provided: 'image-property'.
 +
 ++++
 +** The commands that add ChangeLog entries now prefer a VCS root directory
 +for the ChangeLog file, if none already exists.  Customize
 +'change-log-directory-files' to nil for the old behavior.
 +
 +---
 +** Support for non-string values of 'time-stamp-format' has been removed.
 +
 +** Message
 +
 +---
 +*** 'message-use-idna' now defaults to t (because Emacs comes with
 +built-in IDNA support now).
 +
 +---
 +*** The 'message-valid-fqdn-regexp' variable has been removed, since
 +there are now top-level domains added all the time.  Message will no
 +longer warn about sending emails to top-level domains it hasn't heard
 +about.
 +
 +*** 'message-beginning-of-line' (bound to C-a) understands folded headers.
 +In 'visual-line-mode' it will look for the true beginning of a header
 +while in non-'visual-line-mode' it will move the point to the indented
 +header's value.
 +
 +** Tramp
 +
 ++++
 +*** New connection method "sg", which supports editing files under a
 +different group ID.
 +
 ++++
 +*** New connection method "doas" for OpenBSD hosts.
 +
 +---
 +** 'auto-revert-use-notify' is set back to t in 'global-auto-revert-mode'.
 +
 +** CSS mode
 +
 +---
 +*** Support for completing attribute values, at-rules, bang-rules, and
 +HTML tags using the 'completion-at-point' command.
 +
 ++++
 +** Emacs now supports character name escape sequences in character and
 +string literals.  The syntax variants \N{character name} and
 +\N{U+code} are supported.
 +
 ++++
 +** Prog mode has some support for multi-mode indentation.
 +This allows better indentation support in modes that support multiple
 +programming languages in the same buffer, like literate programming
 +environments or ANTLR programs with embedded Python code.
 +
 +A major mode can provide indentation context for a sub-mode through
 +the 'prog-indentation-context' variable.  To support this, modes that
 +provide indentation should use 'prog-widen' instead of 'widen' and
 +'prog-first-column' instead of a literal zero.  See the node
 +"Mode-Specific Indent" in the ELisp manual for more details.
 +
 +** ERC
 +
 +*** New variable 'erc-default-port-tls' used to connect to TLS IRC
 +servers.
 +
 +** URL
 +
 ++++
 +*** The new function 'url-cookie-delete-cookie' can be used to
 +programmatically delete all cookies, or cookies from a specific
 +domain.
 +
 ++++
 +*** 'url-retrieve-synchronously' now takes an optional timeout parameter.
 +
 +---
 +*** The URL package now support HTTPS over proxies supporting CONNECT.
 +
 ++++
 +*** 'url-user-agent' now defaults to 'default', and the User-Agent
 +string is computed dynamically based on 'url-privacy-level'.
 +
 +** VC and related modes
 +
 +---
 +*** The VC state indicator in the mode line now defaults to more
 +colorful faces to make it more obvious to the user what the state is.
 +See the 'vc-faces' customization group.
 +
 +\f
 +* New Modes and Packages in Emacs 25.2
 +
 +\f
 +* Incompatible Lisp Changes in Emacs 25.2
 +
 ++++
 +** Resizing a frame no longer runs 'window-configuration-change-hook'.
 +Put your function on 'window-size-change-functions' instead.
 +
 +** 'C-up', 'C-down', 'C-left' and 'C-right' are now defined in term
 +mode to send the same escape sequences that xterm does.  This makes
 +things like forward-word in readline work.
 +
 +---
 +** hideshow mode got four key bindings that are analogous to outline
 +mode bindings: 'C-c @ C-a', 'C-c @ C-t', 'C-c @ C-d', and 'C-c @ C-e.'
 +
 +** The grep/rgrep/lgrep functions will now ask about saving files
 +before running.  This is controlled by the 'grep-save-buffers'
 +variable.
 +
 +\f
 +* Lisp Changes in Emacs 25.2
 +
 +** New var syntax-ppss-table to control the syntax-table used in syntax-ppss.
 +
 ++++
 +** `define-derived-mode' can now specify an :after-hook form, which
 +gets evaluated after the new mode's hook has run.  This can be used to
 +incorporate configuration changes made in the mode hook into the
 +mode's setup.
 +
 +** Autoload files can be generated without timestamps,
 +by setting 'autoload-timestamps' to nil.
 +FIXME As an experiment, nil is the current default.
 +If no insurmountable problems before next release, it can stay that way.
 +
 +** 'ert-with-function-mocked' of 'ert-x package allows mocking of functions
 +in unit tests.
 +
 +---
 +** 'gnutls-boot' now takes a parameter :complete-negotiation that says
 +that negotiation should complete even on non-blocking sockets.
 +
 ++++
 +** New functions 'window-pixel-width-before-size-change' and
 +'window-pixel-height-before-size-change' support detecting which
 +window changed size when 'window-size-change-functions' are run.
 +
 ++++
 +** New function 'display-buffer-reuse-mode-window' is an action function
 +suitable for use in 'display-buffer-alist'. For example, to avoid creating
 +a new window when opening man pages when there's already one, use
 +(add-to-list 'display-buffer-alist
 +     '("\\`\\*Man .*\\*\\'" .
 +       (display-buffer-reuse-mode-window
 +        (inhibit-same-window . nil)
 +        (mode . Man-mode))))
 +
 +---
 +** There is now a new variable 'flyspell-sort-corrections-function'
 +that allows changing the way corrections are sorted.
 +
 +---
 +** The new command 'fortune-message' has been added, which displays
 +fortunes in the echo area.
 +
 ++++
 +** New function 'func-arity' returns information about the argument list
 +of an arbitrary function.  This generalizes 'subr-arity' for functions
 +that are not built-in primitives.  We recommend using this new
 +function instead of 'subr-arity'.
 +
 ++++
 +** 'parse-partial-sexp' state has a new element.  Element 10 is
 +non-nil when the last character scanned might be the first character
 +of a two character construct, i.e., a comment delimiter or escaped
 +character.  Its value is the syntax of that last character.
 +
 ++++
 +** 'parse-partial-sexp''s state, element 9, has now been confirmed as
 +permanent and documented, and may be used by Lisp programs.  Its value
 +is a list of currently open parenthesis positions, starting with the
 +outermost parenthesis.
 +
 +---
 +** 'read-color' will now display the color names using the color itself
 +as the background color.
 +
 +** The function 'redirect-debugging-output' now works on platforms
 +other than GNU/Linux.
 +
 ++++
 +** The new function 'string-version-lessp' compares strings by
 +interpreting consecutive runs of numerical characters as numbers, and
 +compares their numerical values.  According to this predicate,
 +"foo2.png" is smaller than "foo12.png".
 +
 ++++
 +** The new function 'char-from-name' converts a Unicode name string
 +to the corresponding character code.
 +
 ++++
 +** New functions 'sxhash-eq' and 'sxhash-eql' return hash codes of a
 +Lisp object suitable for use with 'eq' and 'eql' correspondingly.  If
 +two objects are 'eq' ('eql'), then the result of 'sxhash-eq'
 +('sxhash-eql') on them will be the same.
 +
 ++++
 +** Function 'sxhash' has been renamed to 'sxhash-equal' for
 +consistency with the new functions.  For compatibility, 'sxhash'
 +remains as an alias to 'sxhash-equal'.
 +
 ++++
 +** Time conversion functions that accept a time zone rule argument now
 +allow it to be OFFSET or a list (OFFSET ABBR), where the integer
 +OFFSET is a count of seconds east of Universal Time, and the string
 +ABBR is a time zone abbreviation.  The affected functions are
 +'current-time-string', 'current-time-zone', 'decode-time',
 +'format-time-string', and 'set-time-zone-rule'.
 +
 +\f
 +* Changes in Emacs 25.2 on Non-Free Operating Systems
 +
 +** Intercepting hotkeys on Windows 7 and later now works better.
 +The new keyboard hooking code properly grabs system hotkeys such as
 +Win-* and Alt-TAB, in a way that Emacs can get at them before the
 +system.  This makes the 'w32-register-hot-key' functionality work
 +again on all versions of MS-Windows starting with Windows 7.  On
 +Windows NT and later you can now register any hotkey combination.  (On
 +Windows 9X, the previous limitations, spelled out in the Emacs manual,
 +still apply.)
 +
 +** 'convert-standard-filename' no longer mirrors slashes on MS-Windows.
 +Previously, on MS-Windows this function converted slash characters in
 +file names into backslashes.  It no longer does that.
 +
  \f
  * Installation Changes in Emacs 25.1
  
@@@ -547,7 -89,7 +547,7 @@@ build with 'make V=1'
  ---
  ** The configure option '--with-gameuser' now allows you to specify a
  group instead of a user if its argument is prefixed by ':' (a colon).
- This will cause the game score files in ${localstatedir}/games/emacs
+ This will cause the game score files in "${localstatedir}/games/emacs"
  to be owned by that group, and the helper program for updating them to
  be installed setgid.  The option now defaults to the 'games' group.
  
@@@ -574,7 -116,7 +574,7 @@@ tests which take more time to perform
  'initial-buffer-choice' is non-nil, display both the file and
  'initial-buffer-choice'.  When Emacs is given more than one file and
  'initial-buffer-choice' is non-nil, show 'initial-buffer-choice'
- and *Buffer List*.  This makes Emacs convenient to use from the
+ and '*Buffer List*'.  This makes Emacs convenient to use from the
  command line when 'initial-buffer-choice' is non-nil.
  
  +++
@@@ -650,14 -192,14 +650,14 @@@ added via the new Network Security Mana
  the 'network-security-level' variable.
  
  +++
- ** C-h l now also lists the commands that were run.
+ ** 'C-h l' now also lists the commands that were run.
  
  +++
- ** x-select-enable-clipboard is renamed select-enable-clipboard
- and x-select-enable-primary is renamed select-enable-primary.
+ ** 'x-select-enable-clipboard' is renamed 'select-enable-clipboard'
+ and 'x-select-enable-primary' is renamed 'select-enable-primary'.
  Additionally they both now apply to all systems (OSX, GNUstep, Windows, you
  name it), with the proviso that on some systems (e.g. Windows)
select-enable-primary is ineffective since the system doesn't
'select-enable-primary' is ineffective since the system doesn't
  have the equivalent of a primary selection.
  
  +++
@@@ -670,7 -212,7 +670,7 @@@ selected window is strongly dedicated t
  'even-window-sizes' and now handles window widths as well.
  
  +++
- ** terpri gets an optional arg ENSURE to conditionally output a newline.
+ ** 'terpri' gets an optional arg ENSURE to conditionally output a newline.
  
  +++
  ** 'insert-register' now leaves point after the inserted text
@@@ -693,9 -235,9 +693,9 @@@ variable 'read-hide-char'
  
  +++
  ** The Emacs pseudo-random number generator can be securely seeded.
- On system where Emacs can access the system entropy or some other
+ On systems where Emacs can access the system entropy or some other
  cryptographically secure random stream, it now uses that when 'random'
- is called with its argument 't'.  This allows cryptographically strong
+ is called with its argument t.  This allows cryptographically strong
  random values; in particular, the Emacs server now uses this facility
  to produce its authentication key.
  
  * Editing Changes in Emacs 25.1
  
  +++
- ** M-x suggests shorthands and ignores obsolete commands for completion.
+ ** 'M-x' suggests shorthands and ignores obsolete commands for completion.
  
  ** Changes in undo
  
@@@ -728,19 -270,20 +728,20 @@@ affected by the command
  ** New and improved facilities for inserting Unicode characters
  
  ---
- *** Unicode names entered via C-x 8 RET now use substring completion by default.
+ *** Unicode names entered via 'C-x 8 RET' now use substring completion
+ by default.
  
  +++
- *** C-x 8 now has shorthands for several chars, such as U+2010
+ *** 'C-x 8' now has shorthands for several chars, such as U+2010
  (HYPHEN), U+2011 (NON-BREAKING HYPHEN), and U+2012 (FIGURE DASH).  As
- before, you can type C-x 8 C-h to list shorthands.
+ before, you can type 'C-x 8 C-h' to list shorthands.
  
  +++
- *** New minor mode electric-quote-mode for using curved quotes as you
+ *** New minor mode 'electric-quote-mode' for using curved quotes as you
  type.  See also the new variable 'text-quoting-style'.
  
  ---
- ** New minor mode global-eldoc-mode is enabled by default.
+ ** New minor mode 'global-eldoc-mode' is enabled by default.
  
  ---
  ** Emacs now uses "bracketed paste mode" on text terminals that support it.
@@@ -765,7 -308,7 +766,7 @@@ Bidirectional Parentheses Algorithm (BP
  standards.
  
  +++
- ** You can access 'mouse-buffer-menu' (C-down-mouse-1) using C-f10.
+ ** You can access 'mouse-buffer-menu' ('C-down-mouse-1') using 'C-f10'.
  
  +++
  ** New buffer-local 'electric-pair-local-mode'.
  +++
  ** New variable 'fast-but-imprecise-scrolling' inhibits
  fontification during full screen scrolling operations, giving less
- hesitant operation during auto-repeat of C-v, M-v at the cost of
+ hesitant operation during auto-repeat of 'C-v', 'M-v' at the cost of
  possible inaccuracies in the end position.
  
  +++
@@@ -787,8 -330,8 +788,8 @@@ unsaved customizations and prompts use
  is intended for adding to 'kill-emacs-query-functions'.
  
  +++
- ** The old 'C-x w' bindings in hi-lock-mode are officially deprecated
- in favor of the global 'M-s h' bindings introduced in Emacs-23.1.
+ ** The old 'C-x w' bindings in 'hi-lock-mode' are officially deprecated
+ in favor of the global 'M-s h' bindings introduced in Emacs 23.1.
  They'll disappear soon.
  
  \f
@@@ -813,13 -356,13 +814,13 @@@ emacs -batch --eval "(checkdoc-file \"s
  *** The desktop format version has been upgraded from 206 to 208.
  Although Emacs 25.1 can read a version 206 desktop, earlier Emacsen
  cannot read a version 208 desktop.  To upgrade your desktop file, you
- must explicitly request the upgrade, by C-u M-x desktop-save.  You are
+ must explicitly request the upgrade, by 'C-u M-x desktop-save'.  You are
  recommended to do this as soon as you have firmly upgraded to Emacs
  25.1 (or later).  Should you ever need to downgrade your desktop file
- to version 206, you can do this with C-u C-u M-x desktop-save.
+ to version 206, you can do this with 'C-u C-u M-x desktop-save'.
  
  +++
- ** New function 'bookmark-set-no-overwrite' bound to C-x r M.
+ ** New function 'bookmark-set-no-overwrite' bound to 'C-x r M'.
  It raises an error if a bookmark of that name already exists,
  unlike 'bookmark-set' which silently updates an existing bookmark.
  
@@@ -926,10 -469,10 +927,10 @@@ being made case-sensitive in Emacs 24.2
  **** New play/pause command 'mpc-toggle-play' bound to 's'
  
  **** 'g' bound to new command 'mpc-seek-current' will navigate current
     track.
+ track.
  
  **** New commands 'mpc-toggle-{consume,repeat,single,shuffle}' for
     toggling playback modes.
+ toggling playback modes.
  
  ---
  *** Now supports connecting to a UNIX domain socket.
@@@ -1022,10 -565,10 +1023,10 @@@ installed strictly as dependencies but 
  +++
  ** Shell
  
- When you invoke 'shell' interactively, the *shell* buffer will now
+ When you invoke 'shell' interactively, the '*shell*' buffer will now
  display in a new window.  However, you can customize this behavior via
  the 'display-buffer-alist' variable.  For example, to get
- the old behavior -- *shell* buffer displays in current window -- use
+ the old behavior -- '*shell*' buffer displays in current window -- use
  (add-to-list 'display-buffer-alist
       '("^\\*shell\\*$" . (display-buffer-same-window))).
  
@@@ -1046,13 -589,14 +1047,14 @@@ If you need your objects to be named, d
  Use the equivalent facilities from cl-generic.el instead.
  +++
  *** 'constructor' is now an obsolete alias for 'make-instance'.
- --- 'pcase' accepts a new UPattern 'eieio'.
+ ---
+ *** 'pcase' accepts a new UPattern 'eieio'.
  
  ** ido
  
  +++
- *** New command 'ido-bury-buffer-at-head' bound to C-S-b
- Bury the buffer at the head of 'ido-matches', analogous to how C-k
+ *** New command 'ido-bury-buffer-at-head' bound to 'C-S-b'.
+ Bury the buffer at the head of 'ido-matches', analogous to how 'C-k'
  kills the buffer at head.
  
  ---
@@@ -1108,13 -652,13 +1110,13 @@@ by searching commands to produce a rege
  character-folds into STRING.
  
  +++
- *** The new M-s M-w key binding uses eww to search the web for the
+ *** The new 'M-s M-w' key binding uses eww to search the web for the
  text in the region.  The search engine to use for this is specified by
  the customizable variable 'eww-search-prefix'.
  
  +++
- *** Query-replace history is enhanced.
- When query-replace reads the FROM string from the minibuffer, typing
+ *** 'query-replace' history is enhanced.
+ When 'query-replace' reads the FROM string from the minibuffer, typing
  'M-p' will now show previous replacements as "FROM SEP TO", where FROM
  and TO are the original text and its replacement, and SEP is an arrow
  string defined by the new variable 'query-replace-from-to-separator'.
@@@ -1128,19 -672,19 +1130,19 @@@ typing RET
  result of the calculation into the current buffer.
  
  +++
- ** In Edebug, you can now set the initial mode with C-x C-a C-m.  With
- this you can tell Edebug not to stop at the start of the first
+ ** In Edebug, you can now set the initial mode with 'C-x C-a C-m'.
With this you can tell Edebug not to stop at the start of the first
  instrumented function.
  
  ** ElDoc
  
  +++
- *** New minor mode 'global-eldoc-mode'
+ *** New minor mode 'global-eldoc-mode'.
  It is turned on by default, and affects '*scratch*' and other buffers
  whose major mode supports Emacs Lisp.
  
  ---
- *** 'eldoc-documentation-function' now defaults to 'ignore'
+ *** 'eldoc-documentation-function' now defaults to 'ignore'.
  
  ---
  *** 'describe-char-eldoc' displays information about character at point,
@@@ -1232,7 -776,7 +1234,7 @@@ CLOS class and slot documentation
  *** Rectangle Mark mode can have corners past EOL or in the middle of a TAB.
  
  +++
- *** C-x C-x in rectangle-mark-mode now cycles through the four corners.
+ *** 'C-x C-x' in 'rectangle-mark-mode' now cycles through the four corners.
  *** 'string-rectangle' provides on-the-fly preview of the result.
  
  +++
@@@ -1258,7 -802,7 +1260,7 @@@ prepending it
  ** Calendar and diary
  
  +++
- *** The default 'diary-file' is now located in .emacs.d.
+ *** The default 'diary-file' is now located in "~/.emacs.d".
  
  +++
  *** New commands to insert diary entries with Chinese dates:
@@@ -1335,7 -879,7 +1337,7 @@@ to delete or undelete multiple messages
  libxml2 or if you have the Lynx browser installed.  By default, Rmail
  will display the HTML version of a mail message that has both HTML and
  plain text parts, if display of HTML email is possible; customize the
- 'rmail-mime-prefer-html' option to 'nil' if you don't want that.
+ 'rmail-mime-prefer-html' option to nil if you don't want that.
  
  +++
  *** In the commands that make summaries by subject, recipients, or senders,
@@@ -1388,7 -932,7 +1390,7 @@@ variable, meaning you can bind it aroun
  
  ---
  *** If URL is used with a https connection, the first callback argument
plist will contain a :peer element that has the output of
PLIST will contain a :peer element that has the output of
  'gnutls-peer-status' (if Emacs is built with GnuTLS support).
  
  ** Tramp
@@@ -1429,10 -973,10 +1431,10 @@@ comments
  +++
  *** Basic push support, via 'vc-push', bound to 'C-x v P'.
  Implemented for Bzr, Git, Hg.  As part of this change, the pre-existing
- (undocumented) command vc-hg-push now behaves slightly differently.
+ (undocumented) command 'vc-hg-push' now behaves slightly differently.
  
  +++
- *** The new command vc-region-history shows the log+diff of the active region.
+ *** The new command 'vc-region-history' shows the log+diff of the active region.
  
  +++
  *** You can refresh the VC state of a file buffer with 'M-x vc-refresh-state'.
@@@ -1517,7 -1061,7 +1519,7 @@@ file name patterns.  Defaults to files 
  *** New custom variable 'hide-ifdef-expand-reinclusion-protection' to prevent
  reinclusion protected (a.k.a. "idempotent") header files from being hidden.
  (This could happen when an idempotent header file is visited again,
- when its guard symbol is already defined.)  Defaults to 't'.
+ when its guard symbol is already defined.)  Defaults to t.
  
  ---
  *** New custom variable 'hide-ifdef-exclude-define-regexp' to define symbol
@@@ -1550,7 -1094,7 +1552,7 @@@ New options 'tildify-space-string', 'ti
  helper functions) obsolete.
  
  +++
- ** New package Xref replaces Etags's front-end and UI
+ ** New package Xref replaces Etags's front-end and UI.
  
  The new package Xref provides a generic framework and new commands to
  find and move to definitions of functions, macros, data structures
@@@ -1662,7 -1206,8 +1664,8 @@@ EUDC's PH backend (eudcb-ph.el) is obso
  
  +++
  *** The new built-in command 'clear' can scroll window contents out of sight.
- If provided with an optional non-nil argument, the scrollback contents will be cleared.
+ If provided with an optional non-nil argument, the scrollback contents
+ will be cleared.
  
  +++
  *** New buffer syntax '#<buffer-name>', which is equivalent to
@@@ -1692,7 -1237,7 +1695,7 @@@ make the new option 'eshell-destroy-buf
  *** Support for several ancient browsers is now officially obsolete.
  
  +++
- ** tar-mode: new 'tar-new-entry' command, allowing for new members to
+ ** 'tar-mode': new 'tar-new-entry' command, allowing for new members to
  be added to the archive.
  
  ** Autorevert
@@@ -1721,11 -1266,11 +1724,11 @@@ notification descriptor still correspon
  ** Dired
  
  +++
- *** The command 'dired-do-compress' bound to 'Z' now can compress
+ *** The command 'dired-do-compress', bound to 'Z', now can compress
  directories and decompress zip files.
  
  +++
- *** New command 'dired-do-compress-to' bound to 'c' can be used to
+ *** New command 'dired-do-compress-to', bound to 'c', can be used to
  compress many marked files into a single named archive.  The
  compression command is determined from the new
  'dired-compress-files-alist' variable.
@@@ -1750,7 -1295,7 +1753,7 @@@ call 'tabulated-list-init-header', in w
  header.
  
  +++
- *** 'tabulated-list-print' takes a second optional argument, update,
+ *** 'tabulated-list-print' takes a second optional argument, UPDATE,
  which specifies an alternative printing method which is faster when
  few or no entries have changed.
  
@@@ -1780,11 -1325,11 +1783,11 @@@ The main entry points are 'cl-defgeneri
  node "Generic Functions" in the Emacs Lisp manual for more details.
  
  ---
- ** scss-mode (a minor variant of css-mode) is a major mode for editing
+ ** 'scss-mode' (a minor variant of 'css-mode') is a major mode for editing
  SCSS (Sassy CSS) files.
  
  ---
- ** let-alist is a new macro (and a package) that allows one to easily
+ ** 'let-alist' is a new macro (and a package) that allows one to easily
  let-bind the values stored in an alist.
  
  ---
@@@ -1810,7 -1355,7 +1813,7 @@@ alists, hash-table and arrays.  All fun
  evaluation of forms.
  
  ---
- ** js-jsx-mode (a minor variant of js-mode) provides indentation
+ ** 'js-jsx-mode' (a minor variant of 'js-mode') provides indentation
  support for JSX, an XML-like syntax extension to ECMAScript.
  
  \f
@@@ -1824,8 -1369,8 +1827,8 @@@ eliminated
  
  +++
  ** 'syntax-begin-function' is declared obsolete.
- Removed font-lock-beginning-of-syntax-function and the SYNTAX-BEGIN
- slot in font-lock-defaults.
+ Removed 'font-lock-beginning-of-syntax-function' and the SYNTAX-BEGIN
+ slot in 'font-lock-defaults'.
  
  +++
  ** The new implementation of Subword mode affects word movement everywhere.
@@@ -1857,24 -1402,24 +1860,24 @@@ pointer shape during dragging, should b
  to the special value 'dragging' in the body of the form.
  
  ---
- ** The optional 'predicate' argument of 'lisp-complete-symbol' no longer
+ ** The optional PREDICATE argument of 'lisp-complete-symbol' no longer
  has any effect.  (This change was made in Emacs 24.4 but was not
  advertised at the time.)
  
  +++
  ** 'indirect-function' does not signal 'void-function' any more.
  This is mostly a bug-fix, since this change was missed back in 24.4 when
symbol-function was changed not to signal 'void-function' any more.
'symbol-function' was changed not to signal 'void-function' any more.
  
  +++
  *** As a consequence, the second arg of 'indirect-function' is now obsolete.
  
  +++
- ** M-x shell and M-x compile no longer set the EMACS environment variable.
+ ** 'M-x shell' and 'M-x compile' no longer set the EMACS environment variable.
  This avoids clashing when other programs use the variable for other purposes.
- Although M-x term still sets EMACS for compatibility with Bash 4.3 and earlier,
- this is deprecated and will be phased out when Bash 4.4 or later takes over.
- Use the INSIDE_EMACS environment variable instead.
+ Although 'M-x term' still sets EMACS for compatibility with Bash 4.3
+ and earlier, this is deprecated and will be phased out when Bash 4.4
or later takes over.  Use the INSIDE_EMACS environment variable instead.
  
  +++
  ** 'save-excursion' does not save&restore the mark any more.
@@@ -1882,31 -1427,31 +1885,31 @@@ Use 'save-mark-and-excursion' if you wa
  
  +++
  ** 'read-buffer' and 'read-buffer-function' can now be called with a 4th
- argument ('predicate').
+ argument (PREDICATE).
  
  +++
  ** 'completion-table-dynamic' by default stays in the minibuffer.
  The minibuffer will be the current buffer when the function is called.
  If you want the old behavior of calling the function in the buffer
  from which the minibuffer was entered, use the new argument
'switch-buffer' to 'completion-table-dynamic'.
SWITCH-BUFFER to 'completion-table-dynamic'.
  
  ---
  ** window-configurations no longer record the buffers' marks.
  
  ---
- ** inhibit-modification-hooks now also inhibits lock-file checks, as well as
- active region handling.
+ ** 'inhibit-modification-hooks' now also inhibits lock-file checks, as
well as active region handling.
  
  +++
- ** deactivate-mark is now buffer-local.
+ ** 'deactivate-mark' is now buffer-local.
  
  +++
  ** 'cl-the' now asserts that its argument is of the given type.
  
  +++
  ** 'process-running-child-p' may now return a numeric process
- group ID instead of 't'.
+ group ID instead of t.
  
  +++
  ** Mouse click events on mode line or header line no longer include
@@@ -1916,7 -1461,7 +1919,7 @@@ position list returned for such events 
  ---
  ** Menu items in keymaps do not support the "key shortcut cache" any more.
  These slots used to hold key-shortcut data, but have been obsolete since
- Emacs-21.
+ Emacs 21.
  
  ---
  ** Emacs no longer downcases the first letter of a system diagnostic
@@@ -1942,7 -1487,7 +1945,7 @@@ not affected by 'text-quoting-style', e
  "...." foo bar)).
  
  +++
- ** substitute-command-keys now replaces quotes.
+ ** 'substitute-command-keys' now replaces quotes.
  That is, it converts documentation strings' quoting style as per the
  value of 'text-quoting-style'.  Doc strings in source code can use
  either curved single quotes or grave accents and apostrophes.  As
@@@ -1986,7 -1531,7 +1989,7 @@@ that happen, 'unhandled-file-name-direc
  \f
  * Lisp Changes in Emacs 25.1
  
- ** pcase
+ ** 'pcase'
  +++
  *** New UPatterns 'quote', 'app'.
  +++
  *** New vector QPattern.
  
  ---
- ** syntax-propertize is now automatically called on-demand during forward
+ ** 'syntax-propertize' is now automatically called on-demand during forward
  parsing functions like 'forward-sexp'.
  
  +++
@@@ -2010,7 -1555,7 +2013,7 @@@ file byte offsets, given the file's enc
  
  +++
  ** The default value of 'load-read-function' is now 'read'.
- Previously, the default value of 'nil' implied using 'read'.
+ Previously, the default value of nil implied using 'read'.
  
  +++
  ** New hook 'pre-redisplay-functions'.
@@@ -2027,13 -1572,13 +2030,13 @@@ implemented by the new 'cursor-intangib
  'cursor-sensor-mode' minor modes.
  
  +++
- ** 'inhibit-point-motion-hooks' now defaults to 't' and is obsolete.
+ ** 'inhibit-point-motion-hooks' now defaults to t and is obsolete.
  Use the new minor modes 'cursor-intangible-mode' and
  'cursor-sensor-mode' instead.
  
  +++
  ** New process type 'pipe', which can be used in combination with the
- ':stderr' keyword of make-process to handle standard error output
+ ':stderr' keyword of 'make-process' to handle standard error output
  of subprocess.
  
  +++
  process filter, sentinel, etc., through keyword arguments (similar to
  'make-network-process').
  
+ +++
+ ** Subprocesses are automatically told about changes in window dimensions
+ The new option 'window-adjust-process-window-size-function' controls
+ how subprocesses are told to adapt their logical window sizes to
+ changes in the Emacs window configuration.  Its default value calls
+ 'set-process-window-size' with the smallest dimensions of all the
+ windows that display the subprocess's buffer.
  +++
  ** A new function 'directory-files-recursively' returns all matching
  files (recursively) under a directory.
  +++
  ** New variable 'inhibit-message', when bound to non-nil, inhibits
  'message' and related functions from displaying messages in the echo
- area.  The output is still logged to the *Messages* buffer.
+ area.  The output is still logged to the '*Messages*' buffer.
  
  +++
  ** A new text property 'inhibit-read-only' can be used in read-only
@@@ -2057,8 -1610,8 +2068,8 @@@ buffers to allow certain parts of the t
  
  +++
  ** A new variable 'comment-end-can-be-escaped' is useful in languages
   such as C and C++ where line comments with escaped newlines are
   continued to the next line.
+ such as C and C++ where line comments with escaped newlines are
+ continued to the next line.
  
  +++
  ** New macro 'define-advice'.
@@@ -2073,24 -1626,24 +2084,24 @@@ See the "Finalizer Type" subsection in 
  details.
  
  ---
- ** lexical closures can use (:documentation FORM) to build their docstring.
+ ** Lexical closures can use '(:documentation FORM)' to build their docstring.
  It should be placed right where the docstring would be, and FORM is then
  evaluated (and should return a string) when the closure is built.
  
  +++
- ** define-inline provides a new way to define inlinable functions.
+ ** 'define-inline' provides a new way to define inlinable functions.
  
  +++
  ** New function 'macroexpand-1' to perform a single step of macro expansion.
  
  +++
  ** Some "x-*" functions were obsoleted and/or renamed:
- *** x-select-text is renamed gui-select-text.
- *** x-selection-value is renamed gui-selection-value.
- *** x-get-selection is renamed gui-get-selection.
- *** x-get-clipboard and x-clipboard-yank are marked obsolete.
- *** x-get-selection-value is renamed to gui-get-primary-selection.
- *** x-set-selection is renamed to gui-set-selection
+ *** 'x-select-text' is renamed 'gui-select-text'.
+ *** 'x-selection-value' is renamed 'gui-selection-value'.
+ *** 'x-get-selection' is renamed 'gui-get-selection'.
+ *** 'x-get-clipboard' and 'x-clipboard-yank' are marked obsolete.
+ *** 'x-get-selection-value' is renamed to 'gui-get-primary-selection'.
+ *** 'x-set-selection' is renamed to 'gui-set-selection'.
  
  +++
  ** New function 'string-greaterp', which return the opposite result of
@@@ -2149,9 -1702,9 +2160,9 @@@ text and directional control characters
  
  +++
  ** New properties that can be specified with 'declare':
- *** (interactive-only INSTEAD), says to use INSTEAD for non-interactive use.
- *** (pure VAL), if VAL is non-nil, indicates the function is pure.
- *** (side-effect-free VAL), if VAL is non-nil, indicates the function does not
+ *** '(interactive-only INSTEAD)', says to use INSTEAD for non-interactive use.
+ *** '(pure VAL)', if VAL is non-nil, indicates the function is pure.
+ *** '(side-effect-free VAL)', if VAL is non-nil, indicates the function does not
  have side effects.
  
  +++
@@@ -2210,10 -1763,12 +2221,12 @@@ font, and (iii) the specified window
  
  ---
  ** New utilities in subr-x.el:
  *** New macros 'if-let' and 'when-let' allow defining bindings and to
-     execute code depending whether all values are true.
+ execute code depending whether all values are true.
  *** New macros 'thread-first' and 'thread-last' allow threading a form
    as the first or last argument of subsequent forms.
+ as the first or last argument of subsequent forms.
  
  +++
  ** Documentation strings now support quoting with curved single quotes
@@@ -2232,7 -1787,7 +2245,7 @@@ curved single quotes, grave accents an
  'text-quoting-style'.
  
  +++
- ** show-help-function's arg is converted via substitute-command-keys
+ ** 'show-help-function's arg is converted via 'substitute-command-keys'
  before being passed to the function.  Help strings, help-echo
  properties, etc. can therefore contain command key escapes and
  quotation marks.
@@@ -2282,12 -1837,12 +2295,12 @@@ the name is a directory separator chara
  Unix systems, forward- or backslash on MS-Windows and MS-DOS).
  
  ---
- ** ASCII approximations to curved quotes are put in standard-display-table
+ ** ASCII approximations to curved quotes are put in 'standard-display-table'
  if the terminal cannot display curved quotes.
  
  +++
  ** Standard output and error streams now transliterate characters via
standard-display-table, and encode output using locale-coding-system.
'standard-display-table', and encode output using 'locale-coding-system'.
  To force a specific encoding, bind 'coding-system-for-write' to the
  coding-system of your choice when invoking functions like 'prin1' and
  'message'.
@@@ -2314,30 -1869,30 +2327,30 @@@ provide toolkit scroll bars, namely Gtk
  Horizontal scroll bars are turned off by default.
  
  **** New function 'horizontal-scroll-bars-available-p' telling whether
    horizontal scroll bars are available on the underlying system.
+ horizontal scroll bars are available on the underlying system.
  
  **** New mode 'horizontal-scroll-bar-mode' to toggle horizontal scroll
    bars on all existing and future frames.
+ bars on all existing and future frames.
  
  **** New function 'toggle-horizontal-scroll-bar' to toggle horizontal
    scroll bars on the selected frame.
+ scroll bars on the selected frame.
  
  **** New frame parameters 'horizontal-scroll-bars' and
    'scroll-bar-height' to set horizontal scroll bars and their height
    for individual frames and in 'default-frame-alist'.
+ 'scroll-bar-height' to set horizontal scroll bars and their height
+ for individual frames and in 'default-frame-alist'.
  
  **** New functions 'frame-scroll-bar-height' and
    'window-scroll-bar-height' return the height of horizontal scroll
    bars on a specific frame or window.
+ 'window-scroll-bar-height' return the height of horizontal scroll
+ bars on a specific frame or window.
  
  **** 'set-window-scroll-bars' now accepts five parameters where the last
    two specify height and type of the window's horizontal scroll bar.
+ two specify height and type of the window's horizontal scroll bar.
  
  **** 'window-scroll-bars' now returns type and sizes of horizontal scroll
    bars too.
+ bars too.
  
  **** New buffer-local variables 'horizontal-scroll-bar' and
    'scroll-bar-height'.
+ 'scroll-bar-height'.
  
  +++
  *** New functions 'frame-geometry' and 'frame-edges' give access to a
@@@ -2376,10 -1931,11 +2389,11 @@@ they display when setting default font
  scroll bars.  In particular, maximized and fullscreen frames are
  conceptually never resized if such settings change.  For fullheight and
  fullwidth frames, the behavior may depend on the toolkit used.
  **** New option 'frame-inhibit-implied-resize' if non-nil, means that
   setting default font, menu bar, fringe width, or scroll bars of a
   specific frame does not resize that frame in order to preserve the
   number of columns or lines it displays.
+ setting default font, menu bar, fringe width, or scroll bars of a
+ specific frame does not resize that frame in order to preserve the
+ number of columns or lines it displays.
  
  +++
  *** New function 'window-preserve-size' allows you to preserve the size of
@@@ -2449,7 -2005,7 +2463,7 @@@ whitespace at line beginning
  * Changes in Emacs 25.1 on Non-Free Operating Systems
  
  ---
- ** MS-Windows specific Emacs build scripts are no longer in the distribution
+ ** MS-Windows specific Emacs build scripts are no longer in the distribution.
  This includes the makefile.w32-in files in various subdirectories, and
  the support files.  The file nt/configure.bat now just tells the user
  to use the procedure described in nt/INSTALL, by running the Posix
diff --combined src/editfns.c
index 0e1a6e3415ffc304a11055389dd6ffc613f6992c,360ec12ba98426fcd6a72cccaaf21d4e10699c89..afcf1cab72b3201c175c3eb3a5a420e8882bb512
@@@ -146,6 -146,8 +146,6 @@@ xtzfree (timezone_t tz
  static timezone_t
  tzlookup (Lisp_Object zone, bool settz)
  {
 -  static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
 -  char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
    char const *zone_string;
    timezone_t new_tz;
  
      }
    else
      {
 +      static char const tzbuf_format[] = "<%+.*"pI"d>%s%"pI"d:%02d:%02d";
 +      char const *trailing_tzbuf_format = tzbuf_format + sizeof "<%+.*"pI"d" - 1;
 +      char tzbuf[sizeof tzbuf_format + 2 * INT_STRLEN_BOUND (EMACS_INT)];
 +      bool plain_integer = INTEGERP (zone);
 +
        if (EQ (zone, Qwall))
        zone_string = 0;
        else if (STRINGP (zone))
 -      zone_string = SSDATA (zone);
 -      else if (INTEGERP (zone))
 +      zone_string = SSDATA (ENCODE_SYSTEM (zone));
 +      else if (plain_integer || (CONSP (zone) && INTEGERP (XCAR (zone))
 +                               && CONSP (XCDR (zone))))
        {
 +        Lisp_Object abbr;
 +        if (!plain_integer)
 +          {
 +            abbr = XCAR (XCDR (zone));
 +            zone = XCAR (zone);
 +          }
 +
          EMACS_INT abszone = eabs (XINT (zone)), hour = abszone / (60 * 60);
 -        int min = (abszone / 60) % 60, sec = abszone % 60;
 -        sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], hour, min, sec);
 -        zone_string = tzbuf;
 +        int hour_remainder = abszone % (60 * 60);
 +        int min = hour_remainder / 60, sec = hour_remainder % 60;
 +
 +        if (plain_integer)
 +          {
 +            int prec = 2;
 +            EMACS_INT numzone = hour;
 +            if (hour_remainder != 0)
 +              {
 +                prec += 2, numzone = 100 * numzone + min;
 +                if (sec != 0)
 +                  prec += 2, numzone = 100 * numzone + sec;
 +              }
 +            sprintf (tzbuf, tzbuf_format, prec, numzone,
 +                     &"-"[XINT (zone) < 0], hour, min, sec);
 +            zone_string = tzbuf;
 +          }
 +        else
 +          {
 +            AUTO_STRING (leading, "<");
 +            AUTO_STRING_WITH_LEN (trailing, tzbuf,
 +                                  sprintf (tzbuf, trailing_tzbuf_format,
 +                                           &"-"[XINT (zone) < 0],
 +                                           hour, min, sec));
 +            zone_string = SSDATA (concat3 (leading, ENCODE_SYSTEM (abbr),
 +                                           trailing));
 +          }
        }
        else
        xsignal2 (Qerror, build_string ("Invalid time zone specification"),
@@@ -2004,13 -1969,9 +2004,13 @@@ DEFUN ("format-time-string", Fformat_ti
         doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted.
  TIME is specified as (HIGH LOW USEC PSEC), as returned by
  `current-time' or `file-attributes'.  The obsolete form (HIGH . LOW)
 -is also still accepted.  The optional ZONE is omitted or nil for Emacs
 -local time, t for Universal Time, `wall' for system wall clock time,
 -or a string as in the TZ environment variable.
 +is also still accepted.
 +
 +The optional ZONE is omitted or nil for Emacs local time, t for
 +Universal Time, `wall' for system wall clock time, or a string as in
 +the TZ environment variable.  It can also be a list (as from
 +`current-time-zone') or an integer (as from `decode-time') applied
 +without consideration for daylight saving time.
  
  The value is a copy of FORMAT-STRING, but with certain constructs replaced
  by text that describes the specified date and time in TIME:
@@@ -2081,6 -2042,7 +2081,6 @@@ format_time_string (char const *format
    char *buf = buffer;
    ptrdiff_t size = sizeof buffer;
    size_t len;
 -  Lisp_Object bufstring;
    int ns = t.tv_nsec;
    USE_SAFE_ALLOCA;
  
      }
  
    xtzfree (tz);
 -  bufstring = make_unibyte_string (buf, len);
 +  AUTO_STRING_WITH_LEN (bufstring, buf, len);
 +  Lisp_Object result = code_convert_string_norecord (bufstring,
 +                                                   Vlocale_coding_system, 0);
    SAFE_FREE ();
 -  return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);
 +  return result;
  }
  
  DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
  The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED),
  as from `current-time' and `file-attributes', or nil to use the
  current time.  The obsolete form (HIGH . LOW) is also still accepted.
 +
  The optional ZONE is omitted or nil for Emacs local time, t for
  Universal Time, `wall' for system wall clock time, or a string as in
 -the TZ environment variable.
 +the TZ environment variable.  It can also be a list (as from
 +`current-time-zone') or an integer (as from `decode-time') applied
 +without consideration for daylight saving time.
  
  The list has the following nine members: SEC is an integer between 0
  and 60; SEC is 60 for a leap second, which only some operating systems
@@@ -2192,7 -2149,6 +2192,7 @@@ check_tm_member (Lisp_Object obj, int o
  DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
         doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
  This is the reverse operation of `decode-time', which see.
 +
  The optional ZONE is omitted or nil for Emacs local time, t for
  Universal Time, `wall' for system wall clock time, or a string as in
  the TZ environment variable.  It can also be a list (as from
@@@ -2227,6 -2183,8 +2227,6 @@@ usage: (encode-time SECOND MINUTE HOUR 
    tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
    tm.tm_isdst = -1;
  
 -  if (CONSP (zone))
 -    zone = XCAR (zone);
    timezone_t tz = tzlookup (zone, false);
    value = emacs_mktime_z (tz, &tm);
    xtzfree (tz);
@@@ -2255,9 -2213,7 +2255,9 @@@ but this is considered obsolete
  
  The optional ZONE is omitted or nil for Emacs local time, t for
  Universal Time, `wall' for system wall clock time, or a string as in
 -the TZ environment variable.  */)
 +the TZ environment variable.  It can also be a list (as from
 +`current-time-zone') or an integer (as from `decode-time') applied
 +without consideration for daylight saving time.  */)
    (Lisp_Object specified_time, Lisp_Object zone)
  {
    time_t value = lisp_seconds_argument (specified_time);
@@@ -2333,12 -2289,8 +2333,12 @@@ instead of using the current time.  Th
  \(HIGH LOW . IGNORED).  Thus, you can use times obtained from
  `current-time' and from `file-attributes'.  SPECIFIED-TIME can also
  have the form (HIGH . LOW), but this is considered obsolete.
 -Optional second arg ZONE is omitted or nil for the local time zone, or
 -a string as in the TZ environment variable.
 +
 +The optional ZONE is omitted or nil for Emacs local time, t for
 +Universal Time, `wall' for system wall clock time, or a string as in
 +the TZ environment variable.  It can also be a list (as from
 +`current-time-zone') or an integer (as from `decode-time') applied
 +without consideration for daylight saving time.
  
  Some operating systems cannot provide all this information to Emacs;
  in this case, `current-time-zone' returns a list containing nil for
@@@ -2362,18 -2314,15 +2362,18 @@@ the data it can't find.  */
        zone_offset = make_number (offset);
        if (SCHARS (zone_name) == 0)
        {
 -        /* No local time zone name is available; use "+-NNNN" instead.  */
 -        long int m = offset / 60;
 -        long int am = offset < 0 ? - m : m;
 -        long int hour = am / 60;
 -        int min = am % 60;
 -        char buf[sizeof "+00" + INT_STRLEN_BOUND (long int)];
 -        zone_name = make_formatted_string (buf, "%c%02ld%02d",
 +        /* No local time zone name is available; use numeric zone instead.  */
 +        long int hour = offset / 3600;
 +        int min_sec = offset % 3600;
 +        int amin_sec = min_sec < 0 ? - min_sec : min_sec;
 +        int min = amin_sec / 60;
 +        int sec = amin_sec % 60;
 +        int min_prec = min_sec ? 2 : 0;
 +        int sec_prec = sec ? 2 : 0;
 +        char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)];
 +        zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d",
                                             (offset < 0 ? '-' : '+'),
 -                                           hour, min);
 +                                           hour, min_prec, min, sec_prec, sec);
        }
      }
  
  
  DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
         doc: /* Set the Emacs local time zone using TZ, a string specifying a time zone rule.
 -
  If TZ is nil or `wall', use system wall clock time; this differs from
  the usual Emacs convention where nil means current local time.  If TZ
 -is t, use Universal Time.  If TZ is an integer, treat it as in
 -`encode-time'.
 +is t, use Universal Time.  If TZ is a list (as from
 +`current-time-zone') or an integer (as from `decode-time'), use the
 +specified time zone without consideration for daylight saving time.
  
  Instead of calling this function, you typically want something else.
  To temporarily use a different time zone rule for just one invocation
@@@ -2535,7 -2484,7 +2535,7 @@@ insert1 (Lisp_Object arg
  
  DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
         doc: /* Insert the arguments, either strings or characters, at point.
- Point and before-insertion markers move forward to end up
+ Point and after-insertion markers move forward to end up
   after the inserted text.
  Any other markers at the point of insertion remain before the text.
  
@@@ -2559,7 -2508,7 +2559,7 @@@ usage: (insert &rest ARGS)  */
  DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
     0, MANY, 0,
         doc: /* Insert the arguments at point, inheriting properties from adjoining text.
- Point and before-insertion markers move forward to end up
+ Point and after-insertion markers move forward to end up
   after the inserted text.
  Any other markers at the point of insertion remain before the text.
  
@@@ -3977,8 -3926,6 +3977,8 @@@ styled_format (ptrdiff_t nargs, Lisp_Ob
        multibyte = true;
  
    int quoting_style = message ? text_quoting_style () : -1;
 +  if (quoting_style == LEAVE_QUOTING_STYLE)
 +    quoting_style = -1;
  
    /* If we start out planning a unibyte result,
       then discover it has to be multibyte, we jump back to retry.  */
@@@ -5050,7 -4997,7 +5050,7 @@@ Transposing beyond buffer boundaries i
          start2_addr = BYTE_POS_ADDR (start2_byte);
            memcpy (temp, start1_addr, len1_byte);
            memcpy (start1_addr, start2_addr, len2_byte);
 -          memcpy (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
 +          memmove (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
            memcpy (start1_addr + len2_byte + len_mid, temp, len1_byte);
          SAFE_FREE ();
  
diff --combined src/process.c
index 2d0fb567943f7e4547b1edd44a2e0b9a105f4327,14d7b6df1c32f730216dad4838a8d0417e62cea6..3e66949b6903f2ecfcba9f188271aa77a39f98ff
@@@ -75,6 -75,11 +75,6 @@@ along with GNU Emacs.  If not, see <htt
  # include <sys/stropts.h>
  #endif
  
 -#ifdef HAVE_RES_INIT
 -#include <arpa/nameser.h>
 -#include <resolv.h>
 -#endif
 -
  #ifdef HAVE_UTIL_H
  #include <util.h>
  #endif
  #endif
  #endif
  
 +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
 +/* This is 0.1s in nanoseconds. */
 +#define ASYNC_RETRY_NSEC 100000000
 +#endif
 +
  #ifdef WINDOWSNT
  extern int sys_select (int, fd_set *, fd_set *, fd_set *,
                       struct timespec *, void *);
@@@ -193,6 -193,16 +193,6 @@@ static EMACS_INT process_tick
  /* Number of events for which the user or sentinel has been notified.  */
  static EMACS_INT update_tick;
  
 -/* Define NON_BLOCKING_CONNECT if we can support non-blocking connects.
 -   The code can be simplified by assuming NON_BLOCKING_CONNECT once
 -   Emacs starts assuming POSIX 1003.1-2001 or later.  */
 -
 -#if (defined HAVE_SELECT                              \
 -     && (defined GNU_LINUX || defined HAVE_GETPEERNAME)       \
 -     && (defined EWOULDBLOCK || defined EINPROGRESS))
 -# define NON_BLOCKING_CONNECT
 -#endif
 -
  /* Define DATAGRAM_SOCKETS if datagrams can be used safely on
     this system.  We need to read full packets, so we need a
     "non-destructive" select.  So we require either native select,
@@@ -252,6 -262,7 +252,6 @@@ static fd_set non_process_wait_mask
  
  static fd_set write_mask;
  
 -#ifdef NON_BLOCKING_CONNECT
  /* Mask of bits indicating the descriptors that we wait for connect to
     complete on.  Once they complete, they are removed from this mask
     and added to the input_wait_mask and non_keyboard_wait_mask.  */
@@@ -260,6 -271,7 +260,6 @@@ static fd_set connect_wait_mask
  
  /* Number of bits set in connect_wait_mask.  */
  static int num_pending_connects;
 -#endif        /* NON_BLOCKING_CONNECT */
  
  /* The largest descriptor currently in use for a process object; -1 if none.  */
  static int max_process_desc;
  /* The largest descriptor currently in use for input; -1 if none.  */
  static int max_input_desc;
  
 +/* Set the external socket descriptor for Emacs to use when
 +   `make-network-process' is called with a non-nil
 +   `:use-external-socket' option.  The value should be either -1, or
 +   the file descriptor of a socket that is already bound.  */
 +static int external_sock_fd;
 +
  /* Indexed by descriptor, gives the process (if any) for that descriptor.  */
  static Lisp_Object chan_process[FD_SETSIZE];
 +static void wait_for_socket_fds (Lisp_Object, char const *);
  
  /* Alist of elements (NAME . PROCESS).  */
  static Lisp_Object Vprocess_alist;
@@@ -296,7 -301,7 +296,7 @@@ static struct coding_system *proc_encod
  /* Table of `partner address' for datagram sockets.  */
  static struct sockaddr_and_len {
    struct sockaddr *sa;
 -  int len;
 +  ptrdiff_t len;
  } datagram_address[FD_SETSIZE];
  #define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0)
  #define DATAGRAM_CONN_P(proc)                                           \
@@@ -376,6 -381,11 +376,6 @@@ pset_sentinel (struct Lisp_Process *p, 
    p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
  }
  static void
 -pset_status (struct Lisp_Process *p, Lisp_Object val)
 -{
 -  p->status = val;
 -}
 -static void
  pset_tty_name (struct Lisp_Process *p, Lisp_Object val)
  {
    p->tty_name = val;
@@@ -681,7 -691,12 +681,7 @@@ allocate_process (void
  static Lisp_Object
  make_process (Lisp_Object name)
  {
 -  register Lisp_Object val, tem, name1;
 -  register struct Lisp_Process *p;
 -  char suffix[sizeof "<>" + INT_STRLEN_BOUND (printmax_t)];
 -  printmax_t i;
 -
 -  p = allocate_process ();
 +  struct Lisp_Process *p = allocate_process ();
    /* Initialize Lisp data.  Note that allocate_process initializes all
       Lisp data to nil, so do it only for slots which should not be nil.  */
    pset_status (p, Qrun);
       non-Lisp data, so do it only for slots which should not be zero.  */
    p->infd = -1;
    p->outfd = -1;
 -  for (i = 0; i < PROCESS_OPEN_FDS; i++)
 +  for (int i = 0; i < PROCESS_OPEN_FDS; i++)
      p->open_fd[i] = -1;
  
  #ifdef HAVE_GNUTLS
    p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
 +  p->gnutls_boot_parameters = Qnil;
  #endif
  
    /* If name is already in use, modify it until it is unused.  */
  
 -  name1 = name;
 -  for (i = 1; ; i++)
 +  Lisp_Object name1 = name;
 +  for (printmax_t i = 1; ; i++)
      {
 -      tem = Fget_process (name1);
 -      if (NILP (tem)) break;
 -      name1 = concat2 (name, make_formatted_string (suffix, "<%"pMd">", i));
 +      Lisp_Object tem = Fget_process (name1);
 +      if (NILP (tem))
 +      break;
 +      char const suffix_fmt[] = "<%"pMd">";
 +      char suffix[sizeof suffix_fmt + INT_STRLEN_BOUND (printmax_t)];
 +      AUTO_STRING_WITH_LEN (lsuffix, suffix, sprintf (suffix, suffix_fmt, i));
 +      name1 = concat2 (name, lsuffix);
      }
    name = name1;
    pset_name (p, name);
    pset_sentinel (p, Qinternal_default_process_sentinel);
    pset_filter (p, Qinternal_default_process_filter);
 +  Lisp_Object val;
    XSETPROCESS (val, p);
    Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
    return val;
@@@ -733,19 -742,6 +733,19 @@@ remove_process (register Lisp_Object pr
    deactivate_process (proc);
  }
  
 +#ifdef HAVE_GETADDRINFO_A
 +static void
 +free_dns_request (Lisp_Object proc)
 +{
 +  struct Lisp_Process *p = XPROCESS (proc);
 +
 +  if (p->dns_request->ar_result)
 +    freeaddrinfo (p->dns_request->ar_result);
 +  xfree (p->dns_request);
 +  p->dns_request = NULL;
 +}
 +#endif
 +
  \f
  DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
         doc: /* Return t if OBJECT is a process.  */)
@@@ -836,25 -832,6 +836,25 @@@ nil, indicating the current buffer's pr
    process = get_process (process);
    p = XPROCESS (process);
  
 +#ifdef HAVE_GETADDRINFO_A
 +  if (p->dns_request)
 +    {
 +      /* Cancel the request.  Unless shutting down, wait until
 +       completion.  Free the request if completely canceled. */
 +
 +      bool canceled = gai_cancel (p->dns_request) != EAI_NOTCANCELED;
 +      if (!canceled && !inhibit_sentinels)
 +      {
 +        struct gaicb const *req = p->dns_request;
 +        while (gai_suspend (&req, 1, NULL) != 0)
 +          continue;
 +        canceled = true;
 +      }
 +      if (canceled)
 +      free_dns_request (process);
 +    }
 +#endif
 +
    p->raw_status_new = 0;
    if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p))
      {
@@@ -1031,23 -1008,6 +1031,23 @@@ DEFUN ("process-mark", Fprocess_mark, S
    return XPROCESS (process)->mark;
  }
  
 +static void
 +set_process_filter_masks (struct Lisp_Process *p)
 +{
 +  if (EQ (p->filter, Qt) && !EQ (p->status, Qlisten))
 +    {
 +      FD_CLR (p->infd, &input_wait_mask);
 +      FD_CLR (p->infd, &non_keyboard_wait_mask);
 +    }
 +  else if (EQ (p->filter, Qt)
 +         /* Network or serial process not stopped:  */
 +         && !EQ (p->command, Qt))
 +    {
 +      FD_SET (p->infd, &input_wait_mask);
 +      FD_SET (p->infd, &non_keyboard_wait_mask);
 +    }
 +}
 +
  DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
         2, 2, 0,
         doc: /* Give PROCESS the filter function FILTER; nil means default.
@@@ -1064,10 -1024,12 +1064,10 @@@ The string argument is normally a multi
  - if `default-enable-multibyte-characters' is nil, it is a unibyte
    string (the result of converting the decoded input multibyte
    string to unibyte with `string-make-unibyte').  */)
 -  (register Lisp_Object process, Lisp_Object filter)
 +  (Lisp_Object process, Lisp_Object filter)
  {
 -  struct Lisp_Process *p;
 -
    CHECK_PROCESS (process);
 -  p = XPROCESS (process);
 +  struct Lisp_Process *p = XPROCESS (process);
  
    /* Don't signal an error if the process's input file descriptor
       is closed.  This could make debugging Lisp more difficult,
    if (NILP (filter))
      filter = Qinternal_default_process_filter;
  
 +  pset_filter (p, filter);
 +
    if (p->infd >= 0)
 -    {
 -      if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
 -      {
 -        FD_CLR (p->infd, &input_wait_mask);
 -        FD_CLR (p->infd, &non_keyboard_wait_mask);
 -      }
 -      else if (EQ (p->filter, Qt)
 -             /* Network or serial process not stopped:  */
 -             && !EQ (p->command, Qt))
 -      {
 -        FD_SET (p->infd, &input_wait_mask);
 -        FD_SET (p->infd, &non_keyboard_wait_mask);
 -      }
 -    }
 +    set_process_filter_masks (p);
  
 -  pset_filter (p, filter);
    if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p))
      pset_childp (p, Fplist_put (p->childp, QCfilter, filter));
    setup_process_coding_systems (process);
@@@ -1134,7 -1108,9 +1134,9 @@@ See `set-process-sentinel' for more inf
  
  DEFUN ("set-process-window-size", Fset_process_window_size,
         Sset_process_window_size, 3, 3, 0,
-        doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH.  */)
+        doc: /* Tell PROCESS that it has logical window size WIDTH by HEIGHT.
+ Value is t if PROCESS was successfully told about the window size,
+ nil otherwise.  */)
    (Lisp_Object process, Lisp_Object height, Lisp_Object width)
  {
    CHECK_PROCESS (process);
    CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
    CHECK_RANGED_INTEGER (width, 0, USHRT_MAX);
  
 -  if (XPROCESS (process)->infd < 0
 +  if (NETCONN_P (process)
 +      || XPROCESS (process)->infd < 0
        || (set_window_size (XPROCESS (process)->infd,
                           XINT (height), XINT (width))
          < 0))
@@@ -1212,10 -1187,8 +1214,10 @@@ SERVICE) for a network connection or (P
  connection.  If KEY is t, the complete contact information for the
  connection is returned, else the specific value for the keyword KEY is
  returned.  See `make-network-process' or `make-serial-process' for a
 -list of keywords.  */)
 -  (register Lisp_Object process, Lisp_Object key)
 +list of keywords.
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed.  */)
 +  (Lisp_Object process, Lisp_Object key)
  {
    Lisp_Object contact;
  
    contact = XPROCESS (process)->childp;
  
  #ifdef DATAGRAM_SOCKETS
 +
 +  if (NETCONN_P (process))
 +    wait_for_socket_fds (process, "process-contact");
 +
    if (DATAGRAM_CONN_P (process)
        && (EQ (key, Qt) || EQ (key, QCremote)))
      contact = Fplist_put (contact, QCremote,
@@@ -1261,8 -1230,8 +1263,8 @@@ DEFUN ("process-plist", Fprocess_plist
  
  DEFUN ("set-process-plist", Fset_process_plist, Sset_process_plist,
         2, 2, 0,
 -       doc: /* Replace the plist of PROCESS with PLIST.  Returns PLIST.  */)
 -  (register Lisp_Object process, Lisp_Object plist)
 +       doc: /* Replace the plist of PROCESS with PLIST.  Return PLIST.  */)
 +  (Lisp_Object process, Lisp_Object plist)
  {
    CHECK_PROCESS (process);
    CHECK_LIST (plist);
@@@ -1302,7 -1271,7 +1304,7 @@@ A 4 or 5 element vector represents an I
  An 8 or 9 element vector represents an IPv6 address (with port number).
  If optional second argument OMIT-PORT is non-nil, don't include a port
  number in the string, even when present in ADDRESS.
 -Returns nil if format of ADDRESS is invalid.  */)
 +Return nil if format of ADDRESS is invalid.  */)
    (Lisp_Object address, Lisp_Object omit_port)
  {
    if (NILP (address))
@@@ -2250,12 -2219,12 +2252,12 @@@ usage:  (make-pipe-process &rest ARGS
     The address family of sa is not included in the result.  */
  
  Lisp_Object
 -conv_sockaddr_to_lisp (struct sockaddr *sa, int len)
 +conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len)
  {
    Lisp_Object address;
 -  int i;
 +  ptrdiff_t i;
    unsigned char *cp;
 -  register struct Lisp_Vector *p;
 +  struct Lisp_Vector *p;
  
    /* Workaround for a bug in getsockname on BSD: Names bound to
       sockets in the UNIX domain are inaccessible; getsockname returns
  
  /* Get family and required size for sockaddr structure to hold ADDRESS.  */
  
 -static int
 +static ptrdiff_t
  get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
  {
 -  register struct Lisp_Vector *p;
 +  struct Lisp_Vector *p;
  
    if (VECTORP (address))
      {
@@@ -2449,18 -2418,13 +2451,18 @@@ conv_lisp_to_sockaddr (int family, Lisp
  #ifdef DATAGRAM_SOCKETS
  DEFUN ("process-datagram-address", Fprocess_datagram_address, Sprocess_datagram_address,
         1, 1, 0,
 -       doc: /* Get the current datagram address associated with PROCESS.  */)
 +       doc: /* Get the current datagram address associated with PROCESS.
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed.  */)
    (Lisp_Object process)
  {
    int channel;
  
    CHECK_PROCESS (process);
  
 +  if (NETCONN_P (process))
 +    wait_for_socket_fds (process, "process-datagram-address");
 +
    if (!DATAGRAM_CONN_P (process))
      return Qnil;
  
  DEFUN ("set-process-datagram-address", Fset_process_datagram_address, Sset_process_datagram_address,
         2, 2, 0,
         doc: /* Set the datagram address for PROCESS to ADDRESS.
 -Returns nil upon error setting address, ADDRESS otherwise.  */)
 +Return nil upon error setting address, ADDRESS otherwise.
 +
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed.  */)
    (Lisp_Object process, Lisp_Object address)
  {
    int channel;
 -  int family, len;
 +  int family;
 +  ptrdiff_t len;
  
    CHECK_PROCESS (process);
  
 +  if (NETCONN_P (process))
 +    wait_for_socket_fds (process, "set-process-datagram-address");
 +
    if (!DATAGRAM_CONN_P (process))
      return Qnil;
  
@@@ -2542,7 -2499,7 +2544,7 @@@ static const struct socket_options 
  
  /* Set option OPT to value VAL on socket S.
  
 -   Returns (1<<socket_options[OPT].optbit) if option is known, 0 otherwise.
 +   Return (1<<socket_options[OPT].optbit) if option is known, 0 otherwise.
     Signals an error if setting a known option fails.
  */
  
@@@ -2644,10 -2601,7 +2646,10 @@@ DEFUN ("set-network-process-option"
         doc: /* For network process PROCESS set option OPTION to value VALUE.
  See `make-network-process' for a list of options and values.
  If optional fourth arg NO-ERROR is non-nil, don't signal an error if
 -OPTION is not a supported option, return nil instead; otherwise return t.  */)
 +OPTION is not a supported option, return nil instead; otherwise return t.
 +
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed. */)
    (Lisp_Object process, Lisp_Object option, Lisp_Object value, Lisp_Object no_error)
  {
    int s;
    if (!NETCONN1_P (p))
      error ("Process is not a network process");
  
 +  wait_for_socket_fds (process, "set-network-process-option");
 +
    s = p->infd;
    if (s < 0)
      error ("Process is not running");
@@@ -2954,612 -2906,134 +2956,612 @@@ usage:  (make-serial-process &rest ARGS
    return proc;
  }
  
 -/* Create a network stream/datagram client/server process.  Treated
 -   exactly like a normal process when reading and writing.  Primary
 -   differences are in status display and process deletion.  A network
 -   connection has no PID; you cannot signal it.  All you can do is
 -   stop/continue it and deactivate/close it via delete-process.  */
 +static void
 +set_network_socket_coding_system (Lisp_Object proc, Lisp_Object host,
 +                                Lisp_Object service, Lisp_Object name)
 +{
 +  Lisp_Object tem;
 +  struct Lisp_Process *p = XPROCESS (proc);
 +  Lisp_Object contact = p->childp;
 +  Lisp_Object coding_systems = Qt;
 +  Lisp_Object val;
  
 -DEFUN ("make-network-process", Fmake_network_process, Smake_network_process,
 -       0, MANY, 0,
 -       doc: /* Create and return a network server or client process.
 +  tem = Fplist_member (contact, QCcoding);
 +  if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
 +    tem = Qnil;  /* No error message (too late!).  */
  
 -In Emacs, network connections are represented by process objects, so
 -input and output work as for subprocesses and `delete-process' closes
 -a network connection.  However, a network process has no process id,
 -it cannot be signaled, and the status codes are different from normal
 -processes.
 +  /* Setup coding systems for communicating with the network stream.  */
 +  /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
  
 -Arguments are specified as keyword/argument pairs.  The following
 -arguments are defined:
 +  if (!NILP (tem))
 +    {
 +      val = XCAR (XCDR (tem));
 +      if (CONSP (val))
 +      val = XCAR (val);
 +    }
 +  else if (!NILP (Vcoding_system_for_read))
 +    val = Vcoding_system_for_read;
 +  else if ((!NILP (p->buffer)
 +          && NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
 +         || (NILP (p->buffer)
 +             && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
 +    /* We dare not decode end-of-line format by setting VAL to
 +       Qraw_text, because the existing Emacs Lisp libraries
 +       assume that they receive bare code including a sequence of
 +       CR LF.  */
 +    val = Qnil;
 +  else
 +    {
 +      if (NILP (host) || NILP (service))
 +      coding_systems = Qnil;
 +      else
 +      coding_systems = CALLN (Ffind_operation_coding_system,
 +                              Qopen_network_stream, name, p->buffer,
 +                              host, service);
 +      if (CONSP (coding_systems))
 +      val = XCAR (coding_systems);
 +      else if (CONSP (Vdefault_process_coding_system))
 +      val = XCAR (Vdefault_process_coding_system);
 +      else
 +      val = Qnil;
 +    }
 +  pset_decode_coding_system (p, val);
  
 -:name NAME -- NAME is name for process.  It is modified if necessary
 -to make it unique.
 +  if (!NILP (tem))
 +    {
 +      val = XCAR (XCDR (tem));
 +      if (CONSP (val))
 +      val = XCDR (val);
 +    }
 +  else if (!NILP (Vcoding_system_for_write))
 +    val = Vcoding_system_for_write;
 +  else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
 +    val = Qnil;
 +  else
 +    {
 +      if (EQ (coding_systems, Qt))
 +      {
 +        if (NILP (host) || NILP (service))
 +          coding_systems = Qnil;
 +        else
 +          coding_systems = CALLN (Ffind_operation_coding_system,
 +                                  Qopen_network_stream, name, p->buffer,
 +                                  host, service);
 +      }
 +      if (CONSP (coding_systems))
 +      val = XCDR (coding_systems);
 +      else if (CONSP (Vdefault_process_coding_system))
 +      val = XCDR (Vdefault_process_coding_system);
 +      else
 +      val = Qnil;
 +    }
 +  pset_encode_coding_system (p, val);
  
 -:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
 -with the process.  Process output goes at end of that buffer, unless
 -you specify an output stream or filter function to handle the output.
 -BUFFER may be also nil, meaning that this process is not associated
 -with any buffer.
 +  pset_decoding_buf (p, empty_unibyte_string);
 +  p->decoding_carryover = 0;
 +  pset_encoding_buf (p, empty_unibyte_string);
  
 -:host HOST -- HOST is name of the host to connect to, or its IP
 -address.  The symbol `local' specifies the local host.  If specified
 -for a server process, it must be a valid name or address for the local
 -host, and only clients connecting to that address will be accepted.
 +  p->inherit_coding_system_flag
 +    = !(!NILP (tem) || NILP (p->buffer) || !inherit_process_coding_system);
 +}
  
 -:service SERVICE -- SERVICE is name of the service desired, or an
 -integer specifying a port number to connect to.  If SERVICE is t,
 -a random port number is selected for the server.  (If Emacs was
 -compiled with getaddrinfo, a port number can also be specified as a
 -string, e.g. "80", as well as an integer.  This is not portable.)
 +#ifdef HAVE_GNUTLS
 +static void
 +finish_after_tls_connection (Lisp_Object proc)
 +{
 +  struct Lisp_Process *p = XPROCESS (proc);
 +  Lisp_Object contact = p->childp;
 +  Lisp_Object result = Qt;
  
 -:type TYPE -- TYPE is the type of connection.  The default (nil) is a
 -stream type connection, `datagram' creates a datagram type connection,
 -`seqpacket' creates a reliable datagram connection.
 +  if (!NILP (Ffboundp (Qnsm_verify_connection)))
 +    result = call3 (Qnsm_verify_connection,
 +                  proc,
 +                  Fplist_get (contact, QChost),
 +                  Fplist_get (contact, QCservice));
  
 -:family FAMILY -- FAMILY is the address (and protocol) family for the
 -service specified by HOST and SERVICE.  The default (nil) is to use
 -whatever address family (IPv4 or IPv6) that is defined for the host
 -and port number specified by HOST and SERVICE.  Other address families
 -supported are:
 -  local -- for a local (i.e. UNIX) address specified by SERVICE.
 -  ipv4  -- use IPv4 address family only.
 -  ipv6  -- use IPv6 address family only.
 +  if (NILP (result))
 +    {
 +      pset_status (p, list2 (Qfailed,
 +                           build_string ("The Network Security Manager stopped the connections")));
 +      deactivate_process (proc);
 +    }
 +  else
 +    {
 +      /* If we cleared the connection wait mask before we did
 +       the TLS setup, then we have to say that the process
 +       is finally "open" here. */
 +      if (! FD_ISSET (p->outfd, &connect_wait_mask))
 +      {
 +        pset_status (p, Qrun);
 +        /* Execute the sentinel here.  If we had relied on
 +           status_notify to do it later, it will read input
 +           from the process before calling the sentinel.  */
 +        exec_sentinel (proc, build_string ("open\n"));
 +      }
 +    }
 +}
 +#endif
  
 -:local ADDRESS -- ADDRESS is the local address used for the connection.
 -This parameter is ignored when opening a client process. When specified
 -for a server process, the FAMILY, HOST and SERVICE args are ignored.
 +static void
 +connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses,
 +                        Lisp_Object use_external_socket_p)
 +{
 +  ptrdiff_t count = SPECPDL_INDEX ();
 +  ptrdiff_t count1;
 +  int s = -1, outch, inch;
 +  int xerrno = 0;
 +  Lisp_Object ip_address;
 +  int family;
 +  struct sockaddr *sa = NULL;
 +  int ret;
 +  ptrdiff_t addrlen;
 +  struct Lisp_Process *p = XPROCESS (proc);
 +  Lisp_Object contact = p->childp;
 +  int optbits = 0;
 +  int socket_to_use = -1;
  
 -:remote ADDRESS -- ADDRESS is the remote partner's address for the
 -connection.  This parameter is ignored when opening a stream server
 -process.  For a datagram server process, it specifies the initial
 -setting of the remote datagram address.  When specified for a client
 -process, the FAMILY, HOST, and SERVICE args are ignored.
 +  if (!NILP (use_external_socket_p))
 +    {
 +      socket_to_use = external_sock_fd;
  
 -The format of ADDRESS depends on the address family:
 -- An IPv4 address is represented as an vector of integers [A B C D P]
 -corresponding to numeric IP address A.B.C.D and port number P.
 -- A local address is represented as a string with the address in the
 -local address space.
 -- An "unsupported family" address is represented by a cons (F . AV)
 -where F is the family number and AV is a vector containing the socket
 -address data with one element per address data byte.  Do not rely on
 -this format in portable code, as it may depend on implementation
 -defined constants, data sizes, and data structure alignment.
 +      /* Ensure we don't consume the external socket twice.  */
 +      external_sock_fd = -1;
 +    }
  
 -:coding CODING -- If CODING is a symbol, it specifies the coding
 -system used for both reading and writing for this process.  If CODING
 -is a cons (DECODING . ENCODING), DECODING is used for reading, and
 -ENCODING is used for writing.
 +  /* Do this in case we never enter the while-loop below.  */
 +  count1 = SPECPDL_INDEX ();
 +  s = -1;
  
 -:nowait BOOL -- If BOOL is non-nil for a stream type client process,
 -return without waiting for the connection to complete; instead, the
 -sentinel function will be called with second arg matching "open" (if
 -successful) or "failed" when the connect completes.  Default is to use
 -a blocking connect (i.e. wait) for stream type connections.
 +  while (!NILP (ip_addresses))
 +    {
 +      ip_address = XCAR (ip_addresses);
 +      ip_addresses = XCDR (ip_addresses);
  
 -:noquery BOOL -- Query the user unless BOOL is non-nil, and process is
 -running when Emacs is exited.
 +#ifdef WINDOWSNT
 +    retry_connect:
 +#endif
  
 -:stop BOOL -- Start process in the `stopped' state if BOOL non-nil.
 -In the stopped state, a server process does not accept new
 -connections, and a client process does not handle incoming traffic.
 -The stopped state is cleared by `continue-process' and set by
 -`stop-process'.
 +      addrlen = get_lisp_to_sockaddr_size (ip_address, &family);
 +      if (sa)
 +      free (sa);
 +      sa = xmalloc (addrlen);
 +      conv_lisp_to_sockaddr (family, ip_address, sa, addrlen);
  
 -:filter FILTER -- Install FILTER as the process filter.
 +      s = socket_to_use;
 +      if (s < 0)
 +      {
 +        s = socket (family, p->socktype | SOCK_CLOEXEC, p->ai_protocol);
 +        if (s < 0)
 +          {
 +            xerrno = errno;
 +            continue;
 +          }
 +      }
  
 -:filter-multibyte BOOL -- If BOOL is non-nil, strings given to the
 -process filter are multibyte, otherwise they are unibyte.
 -If this keyword is not specified, the strings are multibyte if
 -the default value of `enable-multibyte-characters' is non-nil.
 +#ifdef DATAGRAM_SOCKETS
 +      if (!p->is_server && p->socktype == SOCK_DGRAM)
 +      break;
 +#endif /* DATAGRAM_SOCKETS */
  
 -:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
 +      if (p->is_non_blocking_client)
 +      {
 +        ret = fcntl (s, F_SETFL, O_NONBLOCK);
 +        if (ret < 0)
 +          {
 +            xerrno = errno;
 +            emacs_close (s);
 +            s = -1;
 +            continue;
 +          }
 +      }
  
 -:log LOG -- Install LOG as the server process log function.  This
 -function is called when the server accepts a network connection from a
 -client.  The arguments are SERVER, CLIENT, and MESSAGE, where SERVER
 -is the server process, CLIENT is the new process for the connection,
 -and MESSAGE is a string.
 +      /* Make us close S if quit.  */
 +      record_unwind_protect_int (close_file_unwind, s);
  
 -:plist PLIST -- Install PLIST as the new process's initial plist.
 +      /* Parse network options in the arg list.  We simply ignore anything
 +       which isn't a known option (including other keywords).  An error
 +       is signaled if setting a known option fails.  */
 +      {
 +      Lisp_Object params = contact, key, val;
  
 -:server QLEN -- if QLEN is non-nil, create a server process for the
 -specified FAMILY, SERVICE, and connection type (stream or datagram).
 -If QLEN is an integer, it is used as the max. length of the server's
 -pending connection queue (also known as the backlog); the default
 -queue length is 5.  Default is to create a client process.
 +      while (!NILP (params))
 +        {
 +          key = XCAR (params);
 +          params = XCDR (params);
 +          val = XCAR (params);
 +          params = XCDR (params);
 +          optbits |= set_socket_option (s, key, val);
 +        }
 +      }
  
 -The following network options can be specified for this connection:
 +      if (p->is_server)
 +      {
 +        /* Configure as a server socket.  */
  
 -:broadcast BOOL    -- Allow send and receive of datagram broadcasts.
 -:dontroute BOOL    -- Only send to directly connected hosts.
 -:keepalive BOOL    -- Send keep-alive messages on network stream.
 -:linger BOOL or TIMEOUT -- Send queued messages before closing.
 +        /* SO_REUSEADDR = 1 is default for server sockets; must specify
 +           explicit :reuseaddr key to override this.  */
 +#ifdef HAVE_LOCAL_SOCKETS
 +        if (family != AF_LOCAL)
 +#endif
 +          if (!(optbits & (1 << OPIX_REUSEADDR)))
 +            {
 +              int optval = 1;
 +              if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
 +                report_file_error ("Cannot set reuse option on server socket", Qnil);
 +            }
 +
 +          /* If passed a socket descriptor, it should be already bound. */
 +        if (socket_to_use < 0 && bind (s, sa, addrlen) != 0)
 +          report_file_error ("Cannot bind server socket", Qnil);
 +
 +#ifdef HAVE_GETSOCKNAME
 +        if (p->port == 0)
 +          {
 +            struct sockaddr_in sa1;
 +            socklen_t len1 = sizeof (sa1);
 +            if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
 +              {
 +                Lisp_Object service;
 +                service = make_number (ntohs (sa1.sin_port));
 +                contact = Fplist_put (contact, QCservice, service);
 +                /* Save the port number so that we can stash it in
 +                   the process object later.  */
 +                ((struct sockaddr_in *)sa)->sin_port = sa1.sin_port;
 +              }
 +          }
 +#endif
 +
 +        if (p->socktype != SOCK_DGRAM && listen (s, p->backlog))
 +          report_file_error ("Cannot listen on server socket", Qnil);
 +
 +        break;
 +      }
 +
 +      immediate_quit = 1;
 +      QUIT;
 +
 +      ret = connect (s, sa, addrlen);
 +      xerrno = errno;
 +
 +      if (ret == 0 || xerrno == EISCONN)
 +      {
 +        /* The unwind-protect will be discarded afterwards.
 +           Likewise for immediate_quit.  */
 +        break;
 +      }
 +
 +      if (p->is_non_blocking_client && xerrno == EINPROGRESS)
 +      break;
 +
 +#ifndef WINDOWSNT
 +      if (xerrno == EINTR)
 +      {
 +        /* Unlike most other syscalls connect() cannot be called
 +           again.  (That would return EALREADY.)  The proper way to
 +           wait for completion is pselect().  */
 +        int sc;
 +        socklen_t len;
 +        fd_set fdset;
 +      retry_select:
 +        FD_ZERO (&fdset);
 +        FD_SET (s, &fdset);
 +        QUIT;
 +        sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
 +        if (sc == -1)
 +          {
 +            if (errno == EINTR)
 +              goto retry_select;
 +            else
 +              report_file_error ("Failed select", Qnil);
 +          }
 +        eassert (sc > 0);
 +
 +        len = sizeof xerrno;
 +        eassert (FD_ISSET (s, &fdset));
 +        if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
 +          report_file_error ("Failed getsockopt", Qnil);
 +        if (xerrno)
 +          report_file_errno ("Failed connect", Qnil, xerrno);
 +        break;
 +      }
 +#endif /* !WINDOWSNT */
 +
 +      immediate_quit = 0;
 +
 +      /* Discard the unwind protect closing S.  */
 +      specpdl_ptr = specpdl + count1;
 +      emacs_close (s);
 +      s = -1;
 +
 +#ifdef WINDOWSNT
 +      if (xerrno == EINTR)
 +      goto retry_connect;
 +#endif
 +    }
 +
 +  if (s >= 0)
 +    {
 +#ifdef DATAGRAM_SOCKETS
 +      if (p->socktype == SOCK_DGRAM)
 +      {
 +        if (datagram_address[s].sa)
 +          emacs_abort ();
 +
 +        datagram_address[s].sa = xmalloc (addrlen);
 +        datagram_address[s].len = addrlen;
 +        if (p->is_server)
 +          {
 +            Lisp_Object remote;
 +            memset (datagram_address[s].sa, 0, addrlen);
 +            if (remote = Fplist_get (contact, QCremote), !NILP (remote))
 +              {
 +                int rfamily;
 +                ptrdiff_t rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
 +                if (rlen != 0 && rfamily == family
 +                    && rlen == addrlen)
 +                  conv_lisp_to_sockaddr (rfamily, remote,
 +                                         datagram_address[s].sa, rlen);
 +              }
 +          }
 +        else
 +          memcpy (datagram_address[s].sa, sa, addrlen);
 +      }
 +#endif
 +
 +      contact = Fplist_put (contact, p->is_server? QClocal: QCremote,
 +                          conv_sockaddr_to_lisp (sa, addrlen));
 +#ifdef HAVE_GETSOCKNAME
 +      if (!p->is_server)
 +      {
 +        struct sockaddr_in sa1;
 +        socklen_t len1 = sizeof (sa1);
 +        if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
 +          contact = Fplist_put (contact, QClocal,
 +                                conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1));
 +      }
 +#endif
 +    }
 +
 +  immediate_quit = 0;
 +
 +  if (s < 0)
 +    {
 +      /* If non-blocking got this far - and failed - assume non-blocking is
 +       not supported after all.  This is probably a wrong assumption, but
 +       the normal blocking calls to open-network-stream handles this error
 +       better.  */
 +      if (p->is_non_blocking_client)
 +      return;
 +
 +      report_file_errno ((p->is_server
 +                        ? "make server process failed"
 +                        : "make client process failed"),
 +                       contact, xerrno);
 +    }
 +
 +  inch = s;
 +  outch = s;
 +
 +  chan_process[inch] = proc;
 +
 +  fcntl (inch, F_SETFL, O_NONBLOCK);
 +
 +  p = XPROCESS (proc);
 +  p->open_fd[SUBPROCESS_STDIN] = inch;
 +  p->infd  = inch;
 +  p->outfd = outch;
 +
 +  /* Discard the unwind protect for closing S, if any.  */
 +  specpdl_ptr = specpdl + count1;
 +
 +  /* Unwind bind_polling_period and request_sigio.  */
 +  unbind_to (count, Qnil);
 +
 +  if (p->is_server && p->socktype != SOCK_DGRAM)
 +    pset_status (p, Qlisten);
 +
 +  /* Make the process marker point into the process buffer (if any).  */
 +  if (BUFFERP (p->buffer))
 +    set_marker_both (p->mark, p->buffer,
 +                   BUF_ZV (XBUFFER (p->buffer)),
 +                   BUF_ZV_BYTE (XBUFFER (p->buffer)));
 +
 +  if (p->is_non_blocking_client)
 +    {
 +      /* We may get here if connect did succeed immediately.  However,
 +       in that case, we still need to signal this like a non-blocking
 +       connection.  */
 +      pset_status (p, Qconnect);
 +      if (!FD_ISSET (inch, &connect_wait_mask))
 +      {
 +        FD_SET (inch, &connect_wait_mask);
 +        FD_SET (inch, &write_mask);
 +        num_pending_connects++;
 +      }
 +    }
 +  else
 +    /* A server may have a client filter setting of Qt, but it must
 +       still listen for incoming connects unless it is stopped.  */
 +    if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt))
 +      || (EQ (p->status, Qlisten) && NILP (p->command)))
 +      {
 +      FD_SET (inch, &input_wait_mask);
 +      FD_SET (inch, &non_keyboard_wait_mask);
 +      }
 +
 +  if (inch > max_process_desc)
 +    max_process_desc = inch;
 +
 +  /* Set up the masks based on the process filter. */
 +  set_process_filter_masks (p);
 +
 +  setup_process_coding_systems (proc);
 +
 +#ifdef HAVE_GNUTLS
 +  /* Continue the asynchronous connection. */
 +  if (!NILP (p->gnutls_boot_parameters))
 +    {
 +      Lisp_Object boot, params = p->gnutls_boot_parameters;
 +
 +      boot = Fgnutls_boot (proc, XCAR (params), XCDR (params));
 +      p->gnutls_boot_parameters = Qnil;
 +
 +      if (p->gnutls_initstage == GNUTLS_STAGE_READY)
 +      /* Run sentinels, etc. */
 +      finish_after_tls_connection (proc);
 +      else if (p->gnutls_initstage != GNUTLS_STAGE_HANDSHAKE_TRIED)
 +      {
 +        deactivate_process (proc);
 +        if (NILP (boot))
 +          pset_status (p, list2 (Qfailed,
 +                                 build_string ("TLS negotiation failed")));
 +        else
 +          pset_status (p, list2 (Qfailed, boot));
 +      }
 +    }
 +#endif
 +
 +}
 +
 +/* Create a network stream/datagram client/server process.  Treated
 +   exactly like a normal process when reading and writing.  Primary
 +   differences are in status display and process deletion.  A network
 +   connection has no PID; you cannot signal it.  All you can do is
 +   stop/continue it and deactivate/close it via delete-process.  */
 +
 +DEFUN ("make-network-process", Fmake_network_process, Smake_network_process,
 +       0, MANY, 0,
 +       doc: /* Create and return a network server or client process.
 +
 +In Emacs, network connections are represented by process objects, so
 +input and output work as for subprocesses and `delete-process' closes
 +a network connection.  However, a network process has no process id,
 +it cannot be signaled, and the status codes are different from normal
 +processes.
 +
 +Arguments are specified as keyword/argument pairs.  The following
 +arguments are defined:
 +
 +:name NAME -- NAME is name for process.  It is modified if necessary
 +to make it unique.
 +
 +:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
 +with the process.  Process output goes at end of that buffer, unless
 +you specify an output stream or filter function to handle the output.
 +BUFFER may be also nil, meaning that this process is not associated
 +with any buffer.
 +
 +:host HOST -- HOST is name of the host to connect to, or its IP
 +address.  The symbol `local' specifies the local host.  If specified
 +for a server process, it must be a valid name or address for the local
 +host, and only clients connecting to that address will be accepted.
 +
 +:service SERVICE -- SERVICE is name of the service desired, or an
 +integer specifying a port number to connect to.  If SERVICE is t,
 +a random port number is selected for the server.  A port number can
 +be specified as an integer string, e.g., "80", as well as an integer.
 +
 +:type TYPE -- TYPE is the type of connection.  The default (nil) is a
 +stream type connection, `datagram' creates a datagram type connection,
 +`seqpacket' creates a reliable datagram connection.
 +
 +:family FAMILY -- FAMILY is the address (and protocol) family for the
 +service specified by HOST and SERVICE.  The default (nil) is to use
 +whatever address family (IPv4 or IPv6) that is defined for the host
 +and port number specified by HOST and SERVICE.  Other address families
 +supported are:
 +  local -- for a local (i.e. UNIX) address specified by SERVICE.
 +  ipv4  -- use IPv4 address family only.
 +  ipv6  -- use IPv6 address family only.
 +
 +:local ADDRESS -- ADDRESS is the local address used for the connection.
 +This parameter is ignored when opening a client process. When specified
 +for a server process, the FAMILY, HOST and SERVICE args are ignored.
 +
 +:remote ADDRESS -- ADDRESS is the remote partner's address for the
 +connection.  This parameter is ignored when opening a stream server
 +process.  For a datagram server process, it specifies the initial
 +setting of the remote datagram address.  When specified for a client
 +process, the FAMILY, HOST, and SERVICE args are ignored.
 +
 +The format of ADDRESS depends on the address family:
 +- An IPv4 address is represented as an vector of integers [A B C D P]
 +corresponding to numeric IP address A.B.C.D and port number P.
 +- A local address is represented as a string with the address in the
 +local address space.
 +- An "unsupported family" address is represented by a cons (F . AV)
 +where F is the family number and AV is a vector containing the socket
 +address data with one element per address data byte.  Do not rely on
 +this format in portable code, as it may depend on implementation
 +defined constants, data sizes, and data structure alignment.
 +
 +:coding CODING -- If CODING is a symbol, it specifies the coding
 +system used for both reading and writing for this process.  If CODING
 +is a cons (DECODING . ENCODING), DECODING is used for reading, and
 +ENCODING is used for writing.
 +
 +:nowait BOOL -- If NOWAIT is non-nil for a stream type client
 +process, return without waiting for the connection to complete;
 +instead, the sentinel function will be called with second arg matching
 +"open" (if successful) or "failed" when the connect completes.
 +Default is to use a blocking connect (i.e. wait) for stream type
 +connections.
 +
 +:noquery BOOL -- Query the user unless BOOL is non-nil, and process is
 +running when Emacs is exited.
 +
 +:stop BOOL -- Start process in the `stopped' state if BOOL non-nil.
 +In the stopped state, a server process does not accept new
 +connections, and a client process does not handle incoming traffic.
 +The stopped state is cleared by `continue-process' and set by
 +`stop-process'.
 +
 +:filter FILTER -- Install FILTER as the process filter.
 +
 +:filter-multibyte BOOL -- If BOOL is non-nil, strings given to the
 +process filter are multibyte, otherwise they are unibyte.
 +If this keyword is not specified, the strings are multibyte if
 +the default value of `enable-multibyte-characters' is non-nil.
 +
 +:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
 +
 +:log LOG -- Install LOG as the server process log function.  This
 +function is called when the server accepts a network connection from a
 +client.  The arguments are SERVER, CLIENT, and MESSAGE, where SERVER
 +is the server process, CLIENT is the new process for the connection,
 +and MESSAGE is a string.
 +
 +:plist PLIST -- Install PLIST as the new process's initial plist.
 +
 +:tls-parameters LIST -- is a list that should be supplied if you're
 +opening a TLS connection.  The first element is the TLS type (either
 +`gnutls-x509pki' or `gnutls-anon'), and the remaining elements should
 +be a keyword list accepted by gnutls-boot (as returned by
 +`gnutls-boot-parameters').
 +
 +:server QLEN -- if QLEN is non-nil, create a server process for the
 +specified FAMILY, SERVICE, and connection type (stream or datagram).
 +If QLEN is an integer, it is used as the max. length of the server's
 +pending connection queue (also known as the backlog); the default
 +queue length is 5.  Default is to create a client process.
 +
 +The following network options can be specified for this connection:
 +
 +:broadcast BOOL    -- Allow send and receive of datagram broadcasts.
 +:dontroute BOOL    -- Only send to directly connected hosts.
 +:keepalive BOOL    -- Send keep-alive messages on network stream.
 +:linger BOOL or TIMEOUT -- Send queued messages before closing.
  :oobinline BOOL    -- Place out-of-band data in receive data stream.
  :priority INT      -- Set protocol defined priority for sent packets.
  :reuseaddr BOOL    -- Allow reusing a recently used local address
                        (this is allowed by default for a server process).
  :bindtodevice NAME -- bind to interface NAME.  Using this may require
                        special privileges on some systems.
 +:use-external-socket BOOL -- Use any pre-allocated sockets that have
 +                             been passed to Emacs.  If Emacs wasn't
 +                             passed a socket, this option is silently
 +                             ignored.
 +
  
  Consult the relevant system programmer's manual pages for more
  information on using these options.
@@@ -3595,24 -3069,41 +3597,24 @@@ usage: (make-network-process &rest ARGS
    Lisp_Object proc;
    Lisp_Object contact;
    struct Lisp_Process *p;
 -#ifdef HAVE_GETADDRINFO
 -  struct addrinfo ai, *res, *lres;
 -  struct addrinfo hints;
    const char *portstring;
 -  char portbuf[128];
 -#else /* HAVE_GETADDRINFO */
 -  struct _emacs_addrinfo
 -  {
 -    int ai_family;
 -    int ai_socktype;
 -    int ai_protocol;
 -    int ai_addrlen;
 -    struct sockaddr *ai_addr;
 -    struct _emacs_addrinfo *ai_next;
 -  } ai, *res, *lres;
 -#endif /* HAVE_GETADDRINFO */
 -  struct sockaddr_in address_in;
 +  ptrdiff_t portstringlen ATTRIBUTE_UNUSED;
 +  char portbuf[INT_BUFSIZE_BOUND (EMACS_INT)];
  #ifdef HAVE_LOCAL_SOCKETS
    struct sockaddr_un address_un;
  #endif
 -  int port;
 -  int ret = 0;
 -  int xerrno = 0;
 -  int s = -1, outch, inch;
 -  ptrdiff_t count = SPECPDL_INDEX ();
 -  ptrdiff_t count1;
 -  Lisp_Object colon_address;  /* Either QClocal or QCremote.  */
 +  EMACS_INT port = 0;
    Lisp_Object tem;
    Lisp_Object name, buffer, host, service, address;
 -  Lisp_Object filter, sentinel;
 -  bool is_non_blocking_client = 0;
 -  bool is_server = 0;
 -  int backlog = 5;
 +  Lisp_Object filter, sentinel, use_external_socket_p;
 +  Lisp_Object ip_addresses = Qnil;
    int socktype;
    int family = -1;
 +  int ai_protocol = 0;
 +#ifdef HAVE_GETADDRINFO_A
 +  struct gaicb *dns_request = NULL;
 +#endif
 +  ptrdiff_t count = SPECPDL_INDEX ();
  
    if (nargs == 0)
      return Qnil;
    else
      error ("Unsupported connection type");
  
 -  /* :server BOOL */
 -  tem = Fplist_get (contact, QCserver);
 -  if (!NILP (tem))
 -    {
 -      /* Don't support network sockets when non-blocking mode is
 -       not available, since a blocked Emacs is not useful.  */
 -      is_server = 1;
 -      if (TYPE_RANGED_INTEGERP (int, tem))
 -      backlog = XINT (tem);
 -    }
 -
 -  /* Make colon_address an alias for :local (server) or :remote (client).  */
 -  colon_address = is_server ? QClocal : QCremote;
 -
 -  /* :nowait BOOL */
 -  if (!is_server && socktype != SOCK_DGRAM
 -      && (tem = Fplist_get (contact, QCnowait), !NILP (tem)))
 -    {
 -#ifndef NON_BLOCKING_CONNECT
 -      error ("Non-blocking connect not supported");
 -#else
 -      is_non_blocking_client = 1;
 -#endif
 -    }
 -
    name = Fplist_get (contact, QCname);
    buffer = Fplist_get (contact, QCbuffer);
    filter = Fplist_get (contact, QCfilter);
    sentinel = Fplist_get (contact, QCsentinel);
 +  use_external_socket_p = Fplist_get (contact, QCuse_external_socket);
  
    CHECK_STRING (name);
  
 -  /* Initialize addrinfo structure in case we don't use getaddrinfo.  */
 -  ai.ai_socktype = socktype;
 -  ai.ai_protocol = 0;
 -  ai.ai_next = NULL;
 -  res = &ai;
 -
    /* :local ADDRESS or :remote ADDRESS */
 -  address = Fplist_get (contact, colon_address);
 +  tem = Fplist_get (contact, QCserver);
 +  if (!NILP (tem))
 +    address = Fplist_get (contact, QCremote);
 +  else
 +    address = Fplist_get (contact, QClocal);
    if (!NILP (address))
      {
        host = service = Qnil;
  
 -      if (!(ai.ai_addrlen = get_lisp_to_sockaddr_size (address, &family)))
 +      if (!get_lisp_to_sockaddr_size (address, &family))
        error ("Malformed :address");
 -      ai.ai_family = family;
 -      ai.ai_addr = alloca (ai.ai_addrlen);
 -      conv_lisp_to_sockaddr (family, address, ai.ai_addr, ai.ai_addrlen);
 +
 +      ip_addresses = list1 (address);
        goto open_socket;
      }
  
    tem = Fplist_get (contact, QCfamily);
    if (NILP (tem))
      {
 -#if defined (HAVE_GETADDRINFO) && defined (AF_INET6)
 +#ifdef AF_INET6
        family = AF_UNSPEC;
  #else
        family = AF_INET;
    else
      error ("Unknown address family");
  
 -  ai.ai_family = family;
 -
    /* :service SERVICE -- string, integer (port number), or t (random port).  */
    service = Fplist_get (contact, QCservice);
  
    /* :host HOST -- hostname, ip address, or 'local for localhost.  */
    host = Fplist_get (contact, QChost);
 -  if (!NILP (host))
 +  if (NILP (host))
 +    {
 +      /* The "connection" function gets it bind info from the address we're
 +       given, so use this dummy address if nothing is specified. */
 +#ifdef HAVE_LOCAL_SOCKETS
 +      if (family != AF_LOCAL)
 +#endif
 +      host = build_string ("127.0.0.1");
 +    }
 +  else
      {
        if (EQ (host, Qlocal))
        /* Depending on setup, "localhost" may map to different IPv4 and/or
          host = Qnil;
        }
        CHECK_STRING (service);
 -      memset (&address_un, 0, sizeof address_un);
 -      address_un.sun_family = AF_LOCAL;
        if (sizeof address_un.sun_path <= SBYTES (service))
        error ("Service name too long");
 -      lispstpcpy (address_un.sun_path, service);
 -      ai.ai_addr = (struct sockaddr *) &address_un;
 -      ai.ai_addrlen = sizeof address_un;
 +      ip_addresses = list1 (service);
        goto open_socket;
      }
  #endif
      }
  #endif
  
 -#ifdef HAVE_GETADDRINFO
 -  /* If we have a host, use getaddrinfo to resolve both host and service.
 -     Otherwise, use getservbyname to lookup the service.  */
    if (!NILP (host))
      {
 -
        /* SERVICE can either be a string or int.
         Convert to a C string for later use by getaddrinfo.  */
        if (EQ (service, Qt))
 -      portstring = "0";
 +      {
 +        portstring = "0";
 +        portstringlen = 1;
 +      }
        else if (INTEGERP (service))
        {
 -        sprintf (portbuf, "%"pI"d", XINT (service));
          portstring = portbuf;
 +        portstringlen = sprintf (portbuf, "%"pI"d", XINT (service));
        }
        else
        {
          CHECK_STRING (service);
          portstring = SSDATA (service);
 +        portstringlen = SBYTES (service);
        }
 +    }
  
 -      immediate_quit = 1;
 -      QUIT;
 -      memset (&hints, 0, sizeof (hints));
 -      hints.ai_flags = 0;
 -      hints.ai_family = family;
 -      hints.ai_socktype = socktype;
 -      hints.ai_protocol = 0;
 -
 -#ifdef HAVE_RES_INIT
 -      res_init ();
 -#endif
 -
 -      ret = getaddrinfo (SSDATA (host), portstring, &hints, &res);
 +#ifdef HAVE_GETADDRINFO_A
 +  if (!NILP (host) && !NILP (Fplist_get (contact, QCnowait)))
 +    {
 +      ptrdiff_t hostlen = SBYTES (host);
 +      struct req
 +      {
 +      struct gaicb gaicb;
 +      struct addrinfo hints;
 +      char str[FLEXIBLE_ARRAY_MEMBER];
 +      } *req = xmalloc (offsetof (struct req, str)
 +                      + hostlen + 1 + portstringlen + 1);
 +      dns_request = &req->gaicb;
 +      dns_request->ar_name = req->str;
 +      dns_request->ar_service = req->str + hostlen + 1;
 +      dns_request->ar_request = &req->hints;
 +      dns_request->ar_result = NULL;
 +      memset (&req->hints, 0, sizeof req->hints);
 +      req->hints.ai_family = family;
 +      req->hints.ai_socktype = socktype;
 +      strcpy (req->str, SSDATA (host));
 +      strcpy (req->str + hostlen + 1, portstring);
 +
 +      int ret = getaddrinfo_a (GAI_NOWAIT, &dns_request, 1, NULL);
        if (ret)
 -#ifdef HAVE_GAI_STRERROR
 -      error ("%s/%s %s", SSDATA (host), portstring, gai_strerror (ret));
 -#else
 -      error ("%s/%s getaddrinfo error %d", SSDATA (host), portstring, ret);
 -#endif
 -      immediate_quit = 0;
 +      error ("%s/%s getaddrinfo_a error %d", SSDATA (host), portstring, ret);
  
        goto open_socket;
      }
 -#endif /* HAVE_GETADDRINFO */
 -
 -  /* We end up here if getaddrinfo is not defined, or in case no hostname
 -     has been specified (e.g. for a local server process).  */
 -
 -  if (EQ (service, Qt))
 -    port = 0;
 -  else if (INTEGERP (service))
 -    port = htons ((unsigned short) XINT (service));
 -  else
 -    {
 -      struct servent *svc_info;
 -      CHECK_STRING (service);
 -      svc_info = getservbyname (SSDATA (service),
 -                              (socktype == SOCK_DGRAM ? "udp" : "tcp"));
 -      if (svc_info == 0)
 -      error ("Unknown service: %s", SDATA (service));
 -      port = svc_info->s_port;
 -    }
 +#endif /* HAVE_GETADDRINFO_A */
  
 -  memset (&address_in, 0, sizeof address_in);
 -  address_in.sin_family = family;
 -  address_in.sin_addr.s_addr = INADDR_ANY;
 -  address_in.sin_port = port;
 +  /* If we have a host, use getaddrinfo to resolve both host and service.
 +     Otherwise, use getservbyname to lookup the service.  */
  
 -#ifndef HAVE_GETADDRINFO
    if (!NILP (host))
      {
 -      struct hostent *host_info_ptr;
 -
 -      /* gethostbyname may fail with TRY_AGAIN, but we don't honor that,
 -       as it may `hang' Emacs for a very long time.  */
 -      immediate_quit = 1;
 -      QUIT;
 -
 -#ifdef HAVE_RES_INIT
 -      res_init ();
 -#endif
 -
 -      host_info_ptr = gethostbyname (SDATA (host));
 -      immediate_quit = 0;
 -
 -      if (host_info_ptr)
 -      {
 -        memcpy (&address_in.sin_addr, host_info_ptr->h_addr,
 -                host_info_ptr->h_length);
 -        family = host_info_ptr->h_addrtype;
 -        address_in.sin_family = family;
 -      }
 -      else
 -      /* Attempt to interpret host as numeric inet address.  */
 -      {
 -        unsigned long numeric_addr;
 -        numeric_addr = inet_addr (SSDATA (host));
 -        if (numeric_addr == -1)
 -          error ("Unknown host \"%s\"", SDATA (host));
 -
 -        memcpy (&address_in.sin_addr, &numeric_addr,
 -                sizeof (address_in.sin_addr));
 -      }
 -
 -    }
 -#endif /* not HAVE_GETADDRINFO */
 -
 -  ai.ai_family = family;
 -  ai.ai_addr = (struct sockaddr *) &address_in;
 -  ai.ai_addrlen = sizeof address_in;
 -
 - open_socket:
 -
 -  /* Do this in case we never enter the for-loop below.  */
 -  count1 = SPECPDL_INDEX ();
 -  s = -1;
 -
 -  for (lres = res; lres; lres = lres->ai_next)
 -    {
 -      ptrdiff_t optn;
 -      int optbits;
 -
 -#ifdef WINDOWSNT
 -    retry_connect:
 -#endif
 -
 -      s = socket (lres->ai_family, lres->ai_socktype | SOCK_CLOEXEC,
 -                lres->ai_protocol);
 -      if (s < 0)
 -      {
 -        xerrno = errno;
 -        continue;
 -      }
 -
 -#ifdef DATAGRAM_SOCKETS
 -      if (!is_server && socktype == SOCK_DGRAM)
 -      break;
 -#endif /* DATAGRAM_SOCKETS */
 -
 -#ifdef NON_BLOCKING_CONNECT
 -      if (is_non_blocking_client)
 -      {
 -        ret = fcntl (s, F_SETFL, O_NONBLOCK);
 -        if (ret < 0)
 -          {
 -            xerrno = errno;
 -            emacs_close (s);
 -            s = -1;
 -            continue;
 -          }
 -      }
 -#endif
 -
 -      /* Make us close S if quit.  */
 -      record_unwind_protect_int (close_file_unwind, s);
 -
 -      /* Parse network options in the arg list.
 -       We simply ignore anything which isn't a known option (including other keywords).
 -       An error is signaled if setting a known option fails.  */
 -      for (optn = optbits = 0; optn < nargs - 1; optn += 2)
 -      optbits |= set_socket_option (s, args[optn], args[optn + 1]);
 -
 -      if (is_server)
 -      {
 -        /* Configure as a server socket.  */
 -
 -        /* SO_REUSEADDR = 1 is default for server sockets; must specify
 -           explicit :reuseaddr key to override this.  */
 -#ifdef HAVE_LOCAL_SOCKETS
 -        if (family != AF_LOCAL)
 -#endif
 -          if (!(optbits & (1 << OPIX_REUSEADDR)))
 -            {
 -              int optval = 1;
 -              if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
 -                report_file_error ("Cannot set reuse option on server socket", Qnil);
 -            }
 -
 -        if (bind (s, lres->ai_addr, lres->ai_addrlen))
 -          report_file_error ("Cannot bind server socket", Qnil);
 -
 -#ifdef HAVE_GETSOCKNAME
 -        if (EQ (service, Qt))
 -          {
 -            struct sockaddr_in sa1;
 -            socklen_t len1 = sizeof (sa1);
 -            if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
 -              {
 -                ((struct sockaddr_in *)(lres->ai_addr))->sin_port = sa1.sin_port;
 -                service = make_number (ntohs (sa1.sin_port));
 -                contact = Fplist_put (contact, QCservice, service);
 -              }
 -          }
 -#endif
 -
 -        if (socktype != SOCK_DGRAM && listen (s, backlog))
 -          report_file_error ("Cannot listen on server socket", Qnil);
 -
 -        break;
 -      }
 +      struct addrinfo *res, *lres;
 +      int ret;
  
        immediate_quit = 1;
        QUIT;
  
 -      ret = connect (s, lres->ai_addr, lres->ai_addrlen);
 -      xerrno = errno;
 +      struct addrinfo hints;
 +      memset (&hints, 0, sizeof hints);
 +      hints.ai_family = family;
 +      hints.ai_socktype = socktype;
  
 -      if (ret == 0 || xerrno == EISCONN)
 +      ret = getaddrinfo (SSDATA (host), portstring, &hints, &res);
 +      if (ret)
 +#ifdef HAVE_GAI_STRERROR
        {
 -        /* The unwind-protect will be discarded afterwards.
 -           Likewise for immediate_quit.  */
 -        break;
 +        synchronize_system_messages_locale ();
 +        char const *str = gai_strerror (ret);
 +        if (! NILP (Vlocale_coding_system))
 +          str = SSDATA (code_convert_string_norecord
 +                        (build_string (str), Vlocale_coding_system, 0));
 +        error ("%s/%s %s", SSDATA (host), portstring, str);
        }
 -
 -#ifdef NON_BLOCKING_CONNECT
 -#ifdef EINPROGRESS
 -      if (is_non_blocking_client && xerrno == EINPROGRESS)
 -      break;
  #else
 -#ifdef EWOULDBLOCK
 -      if (is_non_blocking_client && xerrno == EWOULDBLOCK)
 -      break;
 -#endif
 -#endif
 +      error ("%s/%s getaddrinfo error %d", SSDATA (host), portstring, ret);
  #endif
 +      immediate_quit = 0;
  
 -#ifndef WINDOWSNT
 -      if (xerrno == EINTR)
 +      for (lres = res; lres; lres = lres->ai_next)
        {
 -        /* Unlike most other syscalls connect() cannot be called
 -           again.  (That would return EALREADY.)  The proper way to
 -           wait for completion is pselect().  */
 -        int sc;
 -        socklen_t len;
 -        fd_set fdset;
 -      retry_select:
 -        FD_ZERO (&fdset);
 -        FD_SET (s, &fdset);
 -        QUIT;
 -        sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
 -        if (sc == -1)
 -          {
 -            if (errno == EINTR)
 -              goto retry_select;
 -            else
 -              report_file_error ("Failed select", Qnil);
 -          }
 -        eassert (sc > 0);
 -
 -        len = sizeof xerrno;
 -        eassert (FD_ISSET (s, &fdset));
 -        if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
 -          report_file_error ("Failed getsockopt", Qnil);
 -        if (xerrno)
 -          report_file_errno ("Failed connect", Qnil, xerrno);
 -        break;
 +        ip_addresses = Fcons (conv_sockaddr_to_lisp
 +                              (lres->ai_addr, lres->ai_addrlen),
 +                              ip_addresses);
 +        ai_protocol = lres->ai_protocol;
        }
 -#endif /* !WINDOWSNT */
  
 -      immediate_quit = 0;
 +      ip_addresses = Fnreverse (ip_addresses);
  
 -      /* Discard the unwind protect closing S.  */
 -      specpdl_ptr = specpdl + count1;
 -      emacs_close (s);
 -      s = -1;
 +      freeaddrinfo (res);
  
 -#ifdef WINDOWSNT
 -      if (xerrno == EINTR)
 -      goto retry_connect;
 -#endif
 +      goto open_socket;
      }
  
 -  if (s >= 0)
 +  /* No hostname has been specified (e.g., a local server process).  */
 +
 +  if (EQ (service, Qt))
 +    port = 0;
 +  else if (INTEGERP (service))
 +    port = XINT (service);
 +  else
      {
 -#ifdef DATAGRAM_SOCKETS
 -      if (socktype == SOCK_DGRAM)
 +      CHECK_STRING (service);
 +
 +      port = -1;
 +      if (SBYTES (service) != 0)
        {
 -        if (datagram_address[s].sa)
 -          emacs_abort ();
 -        datagram_address[s].sa = xmalloc (lres->ai_addrlen);
 -        datagram_address[s].len = lres->ai_addrlen;
 -        if (is_server)
 +        /* Allow the service to be a string containing the port number,
 +           because that's allowed if you have getaddrbyname.  */
 +        char *service_end;
 +        long int lport = strtol (SSDATA (service), &service_end, 10);
 +        if (service_end == SSDATA (service) + SBYTES (service))
 +          port = lport;
 +        else
            {
 -            Lisp_Object remote;
 -            memset (datagram_address[s].sa, 0, lres->ai_addrlen);
 -            if (remote = Fplist_get (contact, QCremote), !NILP (remote))
 -              {
 -                int rfamily, rlen;
 -                rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
 -                if (rlen != 0 && rfamily == lres->ai_family
 -                    && rlen == lres->ai_addrlen)
 -                  conv_lisp_to_sockaddr (rfamily, remote,
 -                                         datagram_address[s].sa, rlen);
 -              }
 +            struct servent *svc_info
 +              = getservbyname (SSDATA (service),
 +                               socktype == SOCK_DGRAM ? "udp" : "tcp");
 +            if (svc_info)
 +              port = ntohs (svc_info->s_port);
            }
 -        else
 -          memcpy (datagram_address[s].sa, lres->ai_addr, lres->ai_addrlen);
 -      }
 -#endif
 -      contact = Fplist_put (contact, colon_address,
 -                          conv_sockaddr_to_lisp (lres->ai_addr, lres->ai_addrlen));
 -#ifdef HAVE_GETSOCKNAME
 -      if (!is_server)
 -      {
 -        struct sockaddr_in sa1;
 -        socklen_t len1 = sizeof (sa1);
 -        if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
 -          contact = Fplist_put (contact, QClocal,
 -                                conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1));
        }
 -#endif
 -    }
 -
 -  immediate_quit = 0;
 -
 -#ifdef HAVE_GETADDRINFO
 -  if (res != &ai)
 -    {
 -      block_input ();
 -      freeaddrinfo (res);
 -      unblock_input ();
      }
 -#endif
 -
 -  if (s < 0)
 -    {
 -      /* If non-blocking got this far - and failed - assume non-blocking is
 -       not supported after all.  This is probably a wrong assumption, but
 -       the normal blocking calls to open-network-stream handles this error
 -       better.  */
 -      if (is_non_blocking_client)
 -        return Qnil;
  
 -      report_file_errno ((is_server
 -                        ? "make server process failed"
 -                        : "make client process failed"),
 -                       contact, xerrno);
 +  if (! (0 <= port && port < 1 << 16))
 +    {
 +      AUTO_STRING (unknown_service, "Unknown service: %s");
 +      xsignal1 (Qerror, CALLN (Fformat, unknown_service, service));
      }
  
 -  inch = s;
 -  outch = s;
 + open_socket:
  
    if (!NILP (buffer))
      buffer = Fget_buffer_create (buffer);
    proc = make_process (name);
 -
 -  chan_process[inch] = proc;
 -
 -  fcntl (inch, F_SETFL, O_NONBLOCK);
 -
    p = XPROCESS (proc);
 -
    pset_childp (p, contact);
    pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist)));
    pset_type (p, Qnetwork);
    if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
      pset_command (p, Qt);
    p->pid = 0;
 +  p->backlog = 5;
 +  p->is_non_blocking_client = false;
 +  p->is_server = false;
 +  p->port = port;
 +  p->socktype = socktype;
 +  p->ai_protocol = ai_protocol;
 +#ifdef HAVE_GETADDRINFO_A
 +  p->dns_request = NULL;
 +#endif
 +#ifdef HAVE_GNUTLS
 +  tem = Fplist_get (contact, QCtls_parameters);
 +  CHECK_LIST (tem);
 +  p->gnutls_boot_parameters = tem;
 +#endif
  
 -  p->open_fd[SUBPROCESS_STDIN] = inch;
 -  p->infd  = inch;
 -  p->outfd = outch;
 -
 -  /* Discard the unwind protect for closing S, if any.  */
 -  specpdl_ptr = specpdl + count1;
 +  set_network_socket_coding_system (proc, host, service, name);
  
 -  /* Unwind bind_polling_period and request_sigio.  */
    unbind_to (count, Qnil);
  
 -  if (is_server && socktype != SOCK_DGRAM)
 -    pset_status (p, Qlisten);
 -
 -  /* Make the process marker point into the process buffer (if any).  */
 -  if (BUFFERP (buffer))
 -    set_marker_both (p->mark, buffer,
 -                   BUF_ZV (XBUFFER (buffer)),
 -                   BUF_ZV_BYTE (XBUFFER (buffer)));
 +  /* :server BOOL */
 +  tem = Fplist_get (contact, QCserver);
 +  if (!NILP (tem))
 +    {
 +      /* Don't support network sockets when non-blocking mode is
 +       not available, since a blocked Emacs is not useful.  */
 +      p->is_server = true;
 +      if (TYPE_RANGED_INTEGERP (int, tem))
 +      p->backlog = XINT (tem);
 +    }
  
 -#ifdef NON_BLOCKING_CONNECT
 -  if (is_non_blocking_client)
 +  /* :nowait BOOL */
 +  if (!p->is_server && socktype != SOCK_DGRAM
 +      && !NILP (Fplist_get (contact, QCnowait)))
 +    p->is_non_blocking_client = true;
 +
 +#ifdef HAVE_GETADDRINFO_A
 +  /* With async address resolution, the list of addresses is empty, so
 +     postpone connecting to the server. */
 +  if (!p->is_server && NILP (ip_addresses))
      {
 -      /* We may get here if connect did succeed immediately.  However,
 -       in that case, we still need to signal this like a non-blocking
 -       connection.  */
 -      pset_status (p, Qconnect);
 -      if (!FD_ISSET (inch, &connect_wait_mask))
 -      {
 -        FD_SET (inch, &connect_wait_mask);
 -        FD_SET (inch, &write_mask);
 -        num_pending_connects++;
 -      }
 +      p->dns_request = dns_request;
 +      p->status = Qconnect;
 +      return proc;
      }
 -  else
  #endif
 -    /* A server may have a client filter setting of Qt, but it must
 -       still listen for incoming connects unless it is stopped.  */
 -    if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt))
 -      || (EQ (p->status, Qlisten) && NILP (p->command)))
 -      {
 -      FD_SET (inch, &input_wait_mask);
 -      FD_SET (inch, &non_keyboard_wait_mask);
 -      }
 -
 -  if (inch > max_process_desc)
 -    max_process_desc = inch;
 -
 -  tem = Fplist_member (contact, QCcoding);
 -  if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
 -    tem = Qnil;  /* No error message (too late!).  */
 -
 -  {
 -    /* Setup coding systems for communicating with the network stream.  */
 -    /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
 -    Lisp_Object coding_systems = Qt;
 -    Lisp_Object val;
 -
 -    if (!NILP (tem))
 -      {
 -      val = XCAR (XCDR (tem));
 -      if (CONSP (val))
 -        val = XCAR (val);
 -      }
 -    else if (!NILP (Vcoding_system_for_read))
 -      val = Vcoding_system_for_read;
 -    else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters)))
 -           || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
 -      /* We dare not decode end-of-line format by setting VAL to
 -       Qraw_text, because the existing Emacs Lisp libraries
 -       assume that they receive bare code including a sequence of
 -       CR LF.  */
 -      val = Qnil;
 -    else
 -      {
 -      if (NILP (host) || NILP (service))
 -        coding_systems = Qnil;
 -      else
 -        coding_systems = CALLN (Ffind_operation_coding_system,
 -                                Qopen_network_stream, name, buffer,
 -                                host, service);
 -      if (CONSP (coding_systems))
 -        val = XCAR (coding_systems);
 -      else if (CONSP (Vdefault_process_coding_system))
 -        val = XCAR (Vdefault_process_coding_system);
 -      else
 -        val = Qnil;
 -      }
 -    pset_decode_coding_system (p, val);
 -
 -    if (!NILP (tem))
 -      {
 -      val = XCAR (XCDR (tem));
 -      if (CONSP (val))
 -        val = XCDR (val);
 -      }
 -    else if (!NILP (Vcoding_system_for_write))
 -      val = Vcoding_system_for_write;
 -    else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
 -      val = Qnil;
 -    else
 -      {
 -      if (EQ (coding_systems, Qt))
 -        {
 -          if (NILP (host) || NILP (service))
 -            coding_systems = Qnil;
 -          else
 -            coding_systems = CALLN (Ffind_operation_coding_system,
 -                                    Qopen_network_stream, name, buffer,
 -                                    host, service);
 -        }
 -      if (CONSP (coding_systems))
 -        val = XCDR (coding_systems);
 -      else if (CONSP (Vdefault_process_coding_system))
 -        val = XCDR (Vdefault_process_coding_system);
 -      else
 -        val = Qnil;
 -      }
 -    pset_encode_coding_system (p, val);
 -  }
 -  setup_process_coding_systems (proc);
 -
 -  pset_decoding_buf (p, empty_unibyte_string);
 -  p->decoding_carryover = 0;
 -  pset_encoding_buf (p, empty_unibyte_string);
 -
 -  p->inherit_coding_system_flag
 -    = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
  
 +  connect_network_socket (proc, ip_addresses, use_external_socket_p);
    return proc;
  }
  
@@@ -4321,6 -4130,7 +4323,6 @@@ deactivate_process (Lisp_Object proc
        chan_process[inchannel] = Qnil;
        FD_CLR (inchannel, &input_wait_mask);
        FD_CLR (inchannel, &non_keyboard_wait_mask);
 -#ifdef NON_BLOCKING_CONNECT
        if (FD_ISSET (inchannel, &connect_wait_mask))
        {
          FD_CLR (inchannel, &connect_wait_mask);
          if (--num_pending_connects < 0)
            emacs_abort ();
        }
 -#endif
        if (inchannel == max_process_desc)
        {
          /* We just closed the highest-numbered process input descriptor,
@@@ -4631,91 -4442,6 +4633,91 @@@ server_accept_connection (Lisp_Object s
    exec_sentinel (proc, concat3 (open_from, host_string, nl));
  }
  
 +#ifdef HAVE_GETADDRINFO_A
 +static Lisp_Object
 +check_for_dns (Lisp_Object proc)
 +{
 +  struct Lisp_Process *p = XPROCESS (proc);
 +  Lisp_Object ip_addresses = Qnil;
 +
 +  /* Sanity check. */
 +  if (! p->dns_request)
 +    return Qnil;
 +
 +  int ret = gai_error (p->dns_request);
 +  if (ret == EAI_INPROGRESS)
 +    return Qt;
 +
 +  /* We got a response. */
 +  if (ret == 0)
 +    {
 +      struct addrinfo *res;
 +
 +      for (res = p->dns_request->ar_result; res; res = res->ai_next)
 +      {
 +        ip_addresses = Fcons (conv_sockaddr_to_lisp
 +                              (res->ai_addr, res->ai_addrlen),
 +                              ip_addresses);
 +      }
 +
 +      ip_addresses = Fnreverse (ip_addresses);
 +    }
 +  /* The DNS lookup failed. */
 +  else if (EQ (p->status, Qconnect))
 +    {
 +      deactivate_process (proc);
 +      pset_status (p, (list2
 +                     (Qfailed,
 +                      concat3 (build_string ("Name lookup of "),
 +                               build_string (p->dns_request->ar_name),
 +                               build_string (" failed")))));
 +    }
 +
 +  free_dns_request (proc);
 +
 +  /* This process should not already be connected (or killed). */
 +  if (!EQ (p->status, Qconnect))
 +    return Qnil;
 +
 +  return ip_addresses;
 +}
 +
 +#endif /* HAVE_GETADDRINFO_A */
 +
 +static void
 +wait_for_socket_fds (Lisp_Object process, char const *name)
 +{
 +  while (XPROCESS (process)->infd < 0
 +       && EQ (XPROCESS (process)->status, Qconnect))
 +    {
 +      add_to_log ("Waiting for socket from %s...", build_string (name));
 +      wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
 +    }
 +}
 +
 +static void
 +wait_while_connecting (Lisp_Object process)
 +{
 +  while (EQ (XPROCESS (process)->status, Qconnect))
 +    {
 +      add_to_log ("Waiting for connection...");
 +      wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
 +    }
 +}
 +
 +static void
 +wait_for_tls_negotiation (Lisp_Object process)
 +{
 +#ifdef HAVE_GNUTLS
 +  while (XPROCESS (process)->gnutls_p
 +       && XPROCESS (process)->gnutls_initstage != GNUTLS_STAGE_READY)
 +    {
 +      add_to_log ("Waiting for TLS...");
 +      wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
 +    }
 +#endif
 +}
 +
  /* This variable is different from waiting_for_input in keyboard.c.
     It is used to communicate to a lisp process-filter/sentinel (via the
     function Fwaiting_for_user_input_p below) whether Emacs was waiting
@@@ -4794,9 -4520,6 +4796,9 @@@ wait_reading_process_output (intmax_t t
    struct timespec got_output_end_time = invalid_timespec ();
    enum { MINIMUM = -1, TIMEOUT, INFINITY } wait;
    int got_some_output = -1;
 +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
 +  bool retry_for_async;
 +#endif
    ptrdiff_t count = SPECPDL_INDEX ();
  
    /* Close to the current time if known, an invalid timespec otherwise.  */
        if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
        break;
  
 +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
 +      {
 +      Lisp_Object process_list_head, aproc;
 +      struct Lisp_Process *p;
 +
 +      retry_for_async = false;
 +      FOR_EACH_PROCESS(process_list_head, aproc)
 +        {
 +          p = XPROCESS (aproc);
 +
 +          if (! wait_proc || p == wait_proc)
 +            {
 +#ifdef HAVE_GETADDRINFO_A
 +              /* Check for pending DNS requests. */
 +              if (p->dns_request)
 +                {
 +                  Lisp_Object ip_addresses = check_for_dns (aproc);
 +                  if (!NILP (ip_addresses) && !EQ (ip_addresses, Qt))
 +                    connect_network_socket (aproc, ip_addresses, Qnil);
 +                  else
 +                    retry_for_async = true;
 +                }
 +#endif
 +#ifdef HAVE_GNUTLS
 +              /* Continue TLS negotiation. */
 +              if (p->gnutls_initstage == GNUTLS_STAGE_HANDSHAKE_TRIED
 +                  && p->is_non_blocking_client)
 +                {
 +                  gnutls_try_handshake (p);
 +                  p->gnutls_handshakes_tried++;
 +
 +                  if (p->gnutls_initstage == GNUTLS_STAGE_READY)
 +                    {
 +                      gnutls_verify_boot (aproc, Qnil);
 +                      finish_after_tls_connection (aproc);
 +                    }
 +                  else
 +                    {
 +                      retry_for_async = true;
 +                      if (p->gnutls_handshakes_tried
 +                          > GNUTLS_EMACS_HANDSHAKES_LIMIT)
 +                        {
 +                          deactivate_process (aproc);
 +                          pset_status (p, list2 (Qfailed,
 +                                                 build_string ("TLS negotiation failed")));
 +                        }
 +                    }
 +                }
 +#endif
 +            }
 +        }
 +      }
 +#endif /* GETADDRINFO_A or GNUTLS */
 +
        /* Compute time from now till when time limit is up.  */
        /* Exit if already run out.  */
        if (wait == TIMEOUT)
          timeout = make_timespec (0, 0);
          if ((pselect (max (max_process_desc, max_input_desc) + 1,
                        &Atemp,
 -#ifdef NON_BLOCKING_CONNECT
                        (num_pending_connects > 0 ? &Ctemp : NULL),
 -#else
 -                      NULL,
 -#endif
                        NULL, &timeout, NULL)
               <= 0))
            {
          if (timeout.tv_sec > 0 || timeout.tv_nsec > 0)
            now = invalid_timespec ();
  
 +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
 +        if (retry_for_async
 +            && (timeout.tv_sec > 0 || timeout.tv_nsec > ASYNC_RETRY_NSEC))
 +          {
 +            timeout.tv_sec = 0;
 +            timeout.tv_nsec = ASYNC_RETRY_NSEC;
 +          }
 +#endif
 +
  #if defined (HAVE_NS)
            nfds = ns_select
  #elif defined (HAVE_GLIB)
                                 list2 (Qexit, make_number (256)));
                }
            }
 -#ifdef NON_BLOCKING_CONNECT
          if (FD_ISSET (channel, &Writeok)
              && FD_ISSET (channel, &connect_wait_mask))
            {
                }
              else
                {
 -                pset_status (p, Qrun);
 -                /* Execute the sentinel here.  If we had relied on
 -                   status_notify to do it later, it will read input
 -                   from the process before calling the sentinel.  */
 -                exec_sentinel (proc, build_string ("open\n"));
 +#ifdef HAVE_GNUTLS
 +                /* If we have an incompletely set up TLS connection,
 +                   then defer the sentinel signaling until
 +                   later. */
 +                if (NILP (p->gnutls_boot_parameters)
 +                    && !p->gnutls_p)
 +#endif
 +                  {
 +                    pset_status (p, Qrun);
 +                    /* Execute the sentinel here.  If we had relied on
 +                       status_notify to do it later, it will read input
 +                       from the process before calling the sentinel.  */
 +                    exec_sentinel (proc, build_string ("open\n"));
 +                  }
 +
                  if (0 <= p->infd && !EQ (p->filter, Qt)
                      && !EQ (p->command, Qt))
                    {
                    }
                }
            }
 -#endif /* NON_BLOCKING_CONNECT */
        }                       /* End for each file descriptor.  */
      }                         /* End while exit conditions not met.  */
  
@@@ -5991,12 -5647,6 +5993,12 @@@ send_process (Lisp_Object proc, const c
    ssize_t rv;
    struct coding_system *coding;
  
 +  if (NETCONN_P (proc))
 +    {
 +      wait_while_connecting (proc);
 +      wait_for_tls_negotiation (proc);
 +    }
 +
    if (p->raw_status_new)
      update_status (p);
    if (! EQ (p->status, Qrun))
@@@ -6214,10 -5864,7 +6216,10 @@@ nil, indicating the current buffer's pr
  Called from program, takes three arguments, PROCESS, START and END.
  If the region is more than 500 characters long,
  it is sent in several bunches.  This may happen even for shorter regions.
 -Output from processes can arrive in between bunches.  */)
 +Output from processes can arrive in between bunches.
 +
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed.  */)
    (Lisp_Object process, Lisp_Object start, Lisp_Object end)
  {
    Lisp_Object proc = get_process (process);
    if (XINT (start) < GPT && XINT (end) > GPT)
      move_gap_both (XINT (start), start_byte);
  
 +  if (NETCONN_P (proc))
 +    wait_while_connecting (proc);
 +
    send_process (proc, (char *) BYTE_POS_ADDR (start_byte),
                end_byte - start_byte, Fcurrent_buffer ());
  
@@@ -6247,14 -5891,12 +6249,14 @@@ PROCESS may be a process, a buffer, th
  nil, indicating the current buffer's process.
  If STRING is more than 500 characters long,
  it is sent in several bunches.  This may happen even for shorter strings.
 -Output from processes can arrive in between bunches.  */)
 +Output from processes can arrive in between bunches.
 +
 +If PROCESS is a non-blocking network process that hasn't been fully
 +set up yet, this function will block until socket setup has completed.  */)
    (Lisp_Object process, Lisp_Object string)
  {
 -  Lisp_Object proc;
    CHECK_STRING (string);
 -  proc = get_process (process);
 +  Lisp_Object proc = get_process (process);
    send_process (proc, SSDATA (string),
                SBYTES (string), string);
    return Qnil;
@@@ -6296,8 -5938,12 +6298,8 @@@ process group.  */
  {
    /* Initialize in case ioctl doesn't exist or gives an error,
       in a way that will cause returning t.  */
 -  pid_t gid;
 -  Lisp_Object proc;
 -  struct Lisp_Process *p;
 -
 -  proc = get_process (process);
 -  p = XPROCESS (proc);
 +  Lisp_Object proc = get_process (process);
 +  struct Lisp_Process *p = XPROCESS (proc);
  
    if (!EQ (p->type, Qreal))
      error ("Process %s is not a subprocess",
      error ("Process %s is not active",
           SDATA (p->name));
  
 -  gid = emacs_get_tty_pgrp (p);
 +  pid_t gid = emacs_get_tty_pgrp (p);
  
    if (gid == p->pid)
      return Qnil;
@@@ -6377,7 -6023,7 +6379,7 @@@ process_send_signal (Lisp_Object proces
          break;
  
        case SIGTSTP:
 -#if defined (VSWTCH) && !defined (PREFER_VSUSP)
 +#ifdef VSWTCH
          sig_char = &t.c_cc[VSWTCH];
  #else
          sig_char = &t.c_cc[VSUSP];
@@@ -6665,15 -6311,10 +6667,15 @@@ process has been transmitted to the ser
    struct coding_system *coding = NULL;
    int outfd;
  
 -  if (DATAGRAM_CONN_P (process))
 +  proc = get_process (process);
 +
 +  if (NETCONN_P (proc))
 +    wait_while_connecting (proc);
 +
 +  if (DATAGRAM_CONN_P (proc))
      return process;
  
 -  proc = get_process (process);
 +
    outfd = XPROCESS (proc)->outfd;
    if (outfd >= 0)
      coding = proc_encode_coding_system[outfd];
@@@ -7118,24 -6759,22 +7120,24 @@@ DEFUN ("set-process-coding-system", Fse
         Sset_process_coding_system, 1, 3, 0,
         doc: /* Set coding systems of PROCESS to DECODING and ENCODING.
  DECODING will be used to decode subprocess output and ENCODING to
 -encode subprocess input.  */)
 -  (register Lisp_Object process, Lisp_Object decoding, Lisp_Object encoding)
 +encode subprocess input. */)
 +  (Lisp_Object process, Lisp_Object decoding, Lisp_Object encoding)
  {
 -  register struct Lisp_Process *p;
 -
    CHECK_PROCESS (process);
 -  p = XPROCESS (process);
 -  if (p->infd < 0)
 -    error ("Input file descriptor of %s closed", SDATA (p->name));
 -  if (p->outfd < 0)
 -    error ("Output file descriptor of %s closed", SDATA (p->name));
 +
 +  struct Lisp_Process *p = XPROCESS (process);
 +
    Fcheck_coding_system (decoding);
    Fcheck_coding_system (encoding);
    encoding = coding_inherit_eol_type (encoding, Qnil);
    pset_decode_coding_system (p, decoding);
    pset_encode_coding_system (p, encoding);
 +
 +  /* If the sockets haven't been set up yet, the final setup part of
 +     this will be called asynchronously. */
 +  if (p->infd < 0 || p->outfd < 0)
 +    return Qnil;
 +
    setup_process_coding_systems (process);
  
    return Qnil;
@@@ -7160,18 -6799,13 +7162,18 @@@ all character code conversion except fo
  suppressed.  */)
    (Lisp_Object process, Lisp_Object flag)
  {
 -  register struct Lisp_Process *p;
 -
    CHECK_PROCESS (process);
 -  p = XPROCESS (process);
 +
 +  struct Lisp_Process *p = XPROCESS (process);
    if (NILP (flag))
      pset_decode_coding_system
        (p, raw_text_coding_system (p->decode_coding_system));
 +
 +  /* If the sockets haven't been set up yet, the final setup part of
 +     this will be called asynchronously. */
 +  if (p->infd < 0 || p->outfd < 0)
 +    return Qnil;
 +
    setup_process_coding_systems (process);
  
    return Qnil;
@@@ -7182,11 -6816,14 +7184,11 @@@ DEFUN ("process-filter-multibyte-p", Fp
         doc: /* Return t if a multibyte string is given to PROCESS's filter.*/)
    (Lisp_Object process)
  {
 -  register struct Lisp_Process *p;
 -  struct coding_system *coding;
 -
    CHECK_PROCESS (process);
 -  p = XPROCESS (process);
 +  struct Lisp_Process *p = XPROCESS (process);
    if (p->infd < 0)
      return Qnil;
 -  coding = proc_decode_coding_system[p->infd];
 +  struct coding_system *coding = proc_decode_coding_system[p->infd];
    return (CODING_FOR_UNIBYTE (coding) ? Qnil : Qt);
  }
  
@@@ -7740,10 -7377,10 +7742,10 @@@ catch_child_signal (void
  /* This is not called "init_process" because that is the name of a
     Mach system call, so it would cause problems on Darwin systems.  */
  void
 -init_process_emacs (void)
 +init_process_emacs (int sockfd)
  {
  #ifdef subprocesses
 -  register int i;
 +  int i;
  
    inhibit_sentinels = 0;
  
    FD_ZERO (&non_process_wait_mask);
    FD_ZERO (&write_mask);
    max_process_desc = max_input_desc = -1;
 +  external_sock_fd = sockfd;
    memset (fd_callback_info, 0, sizeof (fd_callback_info));
  
 -#ifdef NON_BLOCKING_CONNECT
    FD_ZERO (&connect_wait_mask);
    num_pending_connects = 0;
 -#endif
  
    process_output_delay_count = 0;
    process_output_skip = 0;
@@@ -7865,9 -7503,6 +7867,9 @@@ syms_of_process (void
    DEFSYM (QCserver, ":server");
    DEFSYM (QCnowait, ":nowait");
    DEFSYM (QCsentinel, ":sentinel");
 +  DEFSYM (QCuse_external_socket, ":use-external-socket");
 +  DEFSYM (QCtls_parameters, ":tls-parameters");
 +  DEFSYM (Qnsm_verify_connection, "nsm-verify-connection");
    DEFSYM (QClog, ":log");
    DEFSYM (QCnoquery, ":noquery");
    DEFSYM (QCstop, ":stop");
@@@ -8017,7 -7652,9 +8019,7 @@@ The variable takes effect when `start-p
  #define ADD_SUBFEATURE(key, val) \
    subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures)
  
 -#ifdef NON_BLOCKING_CONNECT
     ADD_SUBFEATURE (QCnowait, Qt);
 -#endif
  #ifdef DATAGRAM_SOCKETS
     ADD_SUBFEATURE (QCtype, Qdatagram);
  #endif