diff options
| author | Lars Ingebrigtsen | 2019-08-23 04:49:52 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-08-23 04:49:52 +0200 |
| commit | 53cb3d3e0ddb666dc5b7774957ca863c668213cb (patch) | |
| tree | 011cf32acf25b0cd86debf5b3c22be289e60bd87 /src/process.c | |
| parent | b4d3a882a8423e81c418fc56b7a9677f5582fcc7 (diff) | |
| parent | 29d485fb768fbe375d60fd80cb2dbdbd90f3becc (diff) | |
| download | emacs-53cb3d3e0ddb666dc5b7774957ca863c668213cb.tar.gz emacs-53cb3d3e0ddb666dc5b7774957ca863c668213cb.zip | |
Merge remote-tracking branch 'origin/netsec'
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 108 |
1 files changed, 93 insertions, 15 deletions
diff --git a/src/process.c b/src/process.c index 066edbc83d6..7097b7ace17 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -276,6 +276,10 @@ static int read_process_output (Lisp_Object, int); | |||
| 276 | static void create_pty (Lisp_Object); | 276 | static void create_pty (Lisp_Object); |
| 277 | static void exec_sentinel (Lisp_Object, Lisp_Object); | 277 | static void exec_sentinel (Lisp_Object, Lisp_Object); |
| 278 | 278 | ||
| 279 | static Lisp_Object | ||
| 280 | network_lookup_address_info_1 (Lisp_Object host, const char *service, | ||
| 281 | struct addrinfo *hints, struct addrinfo **res); | ||
| 282 | |||
| 279 | /* Number of bits set in connect_wait_mask. */ | 283 | /* Number of bits set in connect_wait_mask. */ |
| 280 | static int num_pending_connects; | 284 | static int num_pending_connects; |
| 281 | 285 | ||
| @@ -4106,7 +4110,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 4106 | if (!NILP (host)) | 4110 | if (!NILP (host)) |
| 4107 | { | 4111 | { |
| 4108 | struct addrinfo *res, *lres; | 4112 | struct addrinfo *res, *lres; |
| 4109 | int ret; | 4113 | Lisp_Object msg; |
| 4110 | 4114 | ||
| 4111 | maybe_quit (); | 4115 | maybe_quit (); |
| 4112 | 4116 | ||
| @@ -4115,20 +4119,11 @@ usage: (make-network-process &rest ARGS) */) | |||
| 4115 | hints.ai_family = family; | 4119 | hints.ai_family = family; |
| 4116 | hints.ai_socktype = socktype; | 4120 | hints.ai_socktype = socktype; |
| 4117 | 4121 | ||
| 4118 | ret = getaddrinfo (SSDATA (host), portstring, &hints, &res); | 4122 | msg = network_lookup_address_info_1 (host, portstring, &hints, &res); |
| 4119 | if (ret) | 4123 | if (!EQ(msg, Qt)) |
| 4120 | #ifdef HAVE_GAI_STRERROR | 4124 | { |
| 4121 | { | 4125 | error ("%s", SSDATA (msg)); |
| 4122 | synchronize_system_messages_locale (); | 4126 | } |
| 4123 | char const *str = gai_strerror (ret); | ||
| 4124 | if (! NILP (Vlocale_coding_system)) | ||
| 4125 | str = SSDATA (code_convert_string_norecord | ||
| 4126 | (build_string (str), Vlocale_coding_system, 0)); | ||
| 4127 | error ("%s/%s %s", SSDATA (host), portstring, str); | ||
| 4128 | } | ||
| 4129 | #else | ||
| 4130 | error ("%s/%s getaddrinfo error %d", SSDATA (host), portstring, ret); | ||
| 4131 | #endif | ||
| 4132 | 4127 | ||
| 4133 | for (lres = res; lres; lres = lres->ai_next) | 4128 | for (lres = res; lres; lres = lres->ai_next) |
| 4134 | addrinfos = Fcons (conv_addrinfo_to_lisp (lres), addrinfos); | 4129 | addrinfos = Fcons (conv_addrinfo_to_lisp (lres), addrinfos); |
| @@ -4576,6 +4571,88 @@ Data that is unavailable is returned as nil. */) | |||
| 4576 | #endif | 4571 | #endif |
| 4577 | } | 4572 | } |
| 4578 | 4573 | ||
| 4574 | static Lisp_Object | ||
| 4575 | network_lookup_address_info_1 (Lisp_Object host, const char *service, | ||
| 4576 | struct addrinfo *hints, struct addrinfo **res) | ||
| 4577 | { | ||
| 4578 | Lisp_Object msg = Qt; | ||
| 4579 | int ret; | ||
| 4580 | |||
| 4581 | if (STRING_MULTIBYTE (host) && SBYTES (host) != SCHARS (host)) | ||
| 4582 | error ("Non-ASCII hostname %s detected, please use puny-encode-domain", | ||
| 4583 | SSDATA (host)); | ||
| 4584 | ret = getaddrinfo (SSDATA (host), service, hints, res); | ||
| 4585 | if (ret) | ||
| 4586 | { | ||
| 4587 | if (service == NULL) | ||
| 4588 | service = "0"; | ||
| 4589 | #ifdef HAVE_GAI_STRERROR | ||
| 4590 | synchronize_system_messages_locale (); | ||
| 4591 | char const *str = gai_strerror (ret); | ||
| 4592 | if (! NILP (Vlocale_coding_system)) | ||
| 4593 | str = SSDATA (code_convert_string_norecord | ||
| 4594 | (build_string (str), Vlocale_coding_system, 0)); | ||
| 4595 | AUTO_STRING (format, "%s/%s %s"); | ||
| 4596 | msg = CALLN (Fformat, format, host, build_string (service), build_string (str)); | ||
| 4597 | #else | ||
| 4598 | AUTO_STRING (format, "%s/%s getaddrinfo error %d"); | ||
| 4599 | msg = CALLN (Fformat, format, host, build_string (service), make_number (ret)); | ||
| 4600 | #endif | ||
| 4601 | } | ||
| 4602 | return msg; | ||
| 4603 | } | ||
| 4604 | |||
| 4605 | DEFUN ("network-lookup-address-info", Fnetwork_lookup_address_info, | ||
| 4606 | Snetwork_lookup_address_info, 1, 2, 0, | ||
| 4607 | doc: /* Look up ip address info of NAME. | ||
| 4608 | Optional parameter FAMILY controls whether to look up IPv4 or IPv6 | ||
| 4609 | addresses. The default of nil means both, symbol `ipv4' means IPv4 | ||
| 4610 | only, symbol `ipv6' means IPv6 only. Returns a list of addresses, or | ||
| 4611 | nil if none were found. Each address is a vector of integers. */) | ||
| 4612 | (Lisp_Object name, Lisp_Object family) | ||
| 4613 | { | ||
| 4614 | Lisp_Object addresses = Qnil; | ||
| 4615 | Lisp_Object msg = Qnil; | ||
| 4616 | |||
| 4617 | struct addrinfo *res, *lres; | ||
| 4618 | struct addrinfo hints; | ||
| 4619 | |||
| 4620 | memset (&hints, 0, sizeof hints); | ||
| 4621 | if (EQ (family, Qnil)) | ||
| 4622 | hints.ai_family = AF_UNSPEC; | ||
| 4623 | else if (EQ (family, Qipv4)) | ||
| 4624 | hints.ai_family = AF_INET; | ||
| 4625 | else if (EQ (family, Qipv6)) | ||
| 4626 | #ifdef AF_INET6 | ||
| 4627 | hints.ai_family = AF_INET6; | ||
| 4628 | #else | ||
| 4629 | /* If we don't support IPv6, querying will never work anyway */ | ||
| 4630 | return addresses; | ||
| 4631 | #endif | ||
| 4632 | else | ||
| 4633 | error ("Unsupported lookup type"); | ||
| 4634 | hints.ai_socktype = SOCK_DGRAM; | ||
| 4635 | |||
| 4636 | msg = network_lookup_address_info_1 (name, NULL, &hints, &res); | ||
| 4637 | if (!EQ(msg, Qt)) | ||
| 4638 | { | ||
| 4639 | message ("%s", SSDATA(msg)); | ||
| 4640 | } | ||
| 4641 | else | ||
| 4642 | { | ||
| 4643 | for (lres = res; lres; lres = lres->ai_next) | ||
| 4644 | { | ||
| 4645 | addresses = Fcons (conv_sockaddr_to_lisp | ||
| 4646 | (lres->ai_addr, lres->ai_addrlen), | ||
| 4647 | addresses); | ||
| 4648 | } | ||
| 4649 | addresses = Fnreverse (addresses); | ||
| 4650 | |||
| 4651 | freeaddrinfo (res); | ||
| 4652 | } | ||
| 4653 | return addresses; | ||
| 4654 | } | ||
| 4655 | |||
| 4579 | /* Turn off input and output for process PROC. */ | 4656 | /* Turn off input and output for process PROC. */ |
| 4580 | 4657 | ||
| 4581 | static void | 4658 | static void |
| @@ -8345,6 +8422,7 @@ returns non-`nil'. */); | |||
| 8345 | defsubr (&Sset_network_process_option); | 8422 | defsubr (&Sset_network_process_option); |
| 8346 | defsubr (&Smake_network_process); | 8423 | defsubr (&Smake_network_process); |
| 8347 | defsubr (&Sformat_network_address); | 8424 | defsubr (&Sformat_network_address); |
| 8425 | defsubr (&Snetwork_lookup_address_info); | ||
| 8348 | defsubr (&Snetwork_interface_list); | 8426 | defsubr (&Snetwork_interface_list); |
| 8349 | defsubr (&Snetwork_interface_info); | 8427 | defsubr (&Snetwork_interface_info); |
| 8350 | #ifdef DATAGRAM_SOCKETS | 8428 | #ifdef DATAGRAM_SOCKETS |