diff options
| author | Michael R. Mauger | 2017-07-03 15:32:41 -0400 |
|---|---|---|
| committer | Michael R. Mauger | 2017-07-03 15:32:41 -0400 |
| commit | 776635c01abd4aa759e7aa9584b513146978568c (patch) | |
| tree | 554f444bc96cb6b05435e8bf195de4df1b00df8f /src/process.c | |
| parent | 77083e2d34ba5559ae2899d3b03cf08c2e6c5ad4 (diff) | |
| parent | 4cd0db3d6e6e4d5bd49283483bdafbbfc0f583f1 (diff) | |
| download | emacs-776635c01abd4aa759e7aa9584b513146978568c.tar.gz emacs-776635c01abd4aa759e7aa9584b513146978568c.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 144 |
1 files changed, 88 insertions, 56 deletions
diff --git a/src/process.c b/src/process.c index 2f2e5c1b251..abd017bb907 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -2049,7 +2049,21 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2049 | int volatile forkerr_volatile = forkerr; | 2049 | int volatile forkerr_volatile = forkerr; |
| 2050 | struct Lisp_Process *p_volatile = p; | 2050 | struct Lisp_Process *p_volatile = p; |
| 2051 | 2051 | ||
| 2052 | #ifdef DARWIN_OS | ||
| 2053 | /* Darwin doesn't let us run setsid after a vfork, so use fork when | ||
| 2054 | necessary. Also, reset SIGCHLD handling after a vfork, as | ||
| 2055 | apparently macOS can mistakenly deliver SIGCHLD to the child. */ | ||
| 2056 | if (pty_flag) | ||
| 2057 | pid = fork (); | ||
| 2058 | else | ||
| 2059 | { | ||
| 2060 | pid = vfork (); | ||
| 2061 | if (pid == 0) | ||
| 2062 | signal (SIGCHLD, SIG_DFL); | ||
| 2063 | } | ||
| 2064 | #else | ||
| 2052 | pid = vfork (); | 2065 | pid = vfork (); |
| 2066 | #endif | ||
| 2053 | 2067 | ||
| 2054 | current_dir = current_dir_volatile; | 2068 | current_dir = current_dir_volatile; |
| 2055 | lisp_pty_name = lisp_pty_name_volatile; | 2069 | lisp_pty_name = lisp_pty_name_volatile; |
| @@ -2467,7 +2481,7 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len) | |||
| 2467 | { | 2481 | { |
| 2468 | case AF_INET: | 2482 | case AF_INET: |
| 2469 | { | 2483 | { |
| 2470 | struct sockaddr_in *sin = (struct sockaddr_in *) sa; | 2484 | DECLARE_POINTER_ALIAS (sin, struct sockaddr_in, sa); |
| 2471 | len = sizeof (sin->sin_addr) + 1; | 2485 | len = sizeof (sin->sin_addr) + 1; |
| 2472 | address = Fmake_vector (make_number (len), Qnil); | 2486 | address = Fmake_vector (make_number (len), Qnil); |
| 2473 | p = XVECTOR (address); | 2487 | p = XVECTOR (address); |
| @@ -2478,8 +2492,8 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len) | |||
| 2478 | #ifdef AF_INET6 | 2492 | #ifdef AF_INET6 |
| 2479 | case AF_INET6: | 2493 | case AF_INET6: |
| 2480 | { | 2494 | { |
| 2481 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; | 2495 | DECLARE_POINTER_ALIAS (sin6, struct sockaddr_in6, sa); |
| 2482 | uint16_t *ip6 = (uint16_t *) &sin6->sin6_addr; | 2496 | DECLARE_POINTER_ALIAS (ip6, uint16_t, &sin6->sin6_addr); |
| 2483 | len = sizeof (sin6->sin6_addr) / 2 + 1; | 2497 | len = sizeof (sin6->sin6_addr) / 2 + 1; |
| 2484 | address = Fmake_vector (make_number (len), Qnil); | 2498 | address = Fmake_vector (make_number (len), Qnil); |
| 2485 | p = XVECTOR (address); | 2499 | p = XVECTOR (address); |
| @@ -2492,7 +2506,7 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len) | |||
| 2492 | #ifdef HAVE_LOCAL_SOCKETS | 2506 | #ifdef HAVE_LOCAL_SOCKETS |
| 2493 | case AF_LOCAL: | 2507 | case AF_LOCAL: |
| 2494 | { | 2508 | { |
| 2495 | struct sockaddr_un *sockun = (struct sockaddr_un *) sa; | 2509 | DECLARE_POINTER_ALIAS (sockun, struct sockaddr_un, sa); |
| 2496 | ptrdiff_t name_length = len - offsetof (struct sockaddr_un, sun_path); | 2510 | ptrdiff_t name_length = len - offsetof (struct sockaddr_un, sun_path); |
| 2497 | /* If the first byte is NUL, the name is a Linux abstract | 2511 | /* If the first byte is NUL, the name is a Linux abstract |
| 2498 | socket name, and the name can contain embedded NULs. If | 2512 | socket name, and the name can contain embedded NULs. If |
| @@ -2603,7 +2617,7 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int | |||
| 2603 | p = XVECTOR (address); | 2617 | p = XVECTOR (address); |
| 2604 | if (family == AF_INET) | 2618 | if (family == AF_INET) |
| 2605 | { | 2619 | { |
| 2606 | struct sockaddr_in *sin = (struct sockaddr_in *) sa; | 2620 | DECLARE_POINTER_ALIAS (sin, struct sockaddr_in, sa); |
| 2607 | len = sizeof (sin->sin_addr) + 1; | 2621 | len = sizeof (sin->sin_addr) + 1; |
| 2608 | hostport = XINT (p->contents[--len]); | 2622 | hostport = XINT (p->contents[--len]); |
| 2609 | sin->sin_port = htons (hostport); | 2623 | sin->sin_port = htons (hostport); |
| @@ -2613,8 +2627,8 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int | |||
| 2613 | #ifdef AF_INET6 | 2627 | #ifdef AF_INET6 |
| 2614 | else if (family == AF_INET6) | 2628 | else if (family == AF_INET6) |
| 2615 | { | 2629 | { |
| 2616 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; | 2630 | DECLARE_POINTER_ALIAS (sin6, struct sockaddr_in6, sa); |
| 2617 | uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr; | 2631 | DECLARE_POINTER_ALIAS (ip6, uint16_t, &sin6->sin6_addr); |
| 2618 | len = sizeof (sin6->sin6_addr) / 2 + 1; | 2632 | len = sizeof (sin6->sin6_addr) / 2 + 1; |
| 2619 | hostport = XINT (p->contents[--len]); | 2633 | hostport = XINT (p->contents[--len]); |
| 2620 | sin6->sin6_port = htons (hostport); | 2634 | sin6->sin6_port = htons (hostport); |
| @@ -2636,7 +2650,7 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int | |||
| 2636 | #ifdef HAVE_LOCAL_SOCKETS | 2650 | #ifdef HAVE_LOCAL_SOCKETS |
| 2637 | if (family == AF_LOCAL) | 2651 | if (family == AF_LOCAL) |
| 2638 | { | 2652 | { |
| 2639 | struct sockaddr_un *sockun = (struct sockaddr_un *) sa; | 2653 | DECLARE_POINTER_ALIAS (sockun, struct sockaddr_un, sa); |
| 2640 | cp = SDATA (address); | 2654 | cp = SDATA (address); |
| 2641 | for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++) | 2655 | for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++) |
| 2642 | sockun->sun_path[i] = *cp++; | 2656 | sockun->sun_path[i] = *cp++; |
| @@ -3409,18 +3423,33 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos, | |||
| 3409 | report_file_error ("Cannot bind server socket", Qnil); | 3423 | report_file_error ("Cannot bind server socket", Qnil); |
| 3410 | 3424 | ||
| 3411 | #ifdef HAVE_GETSOCKNAME | 3425 | #ifdef HAVE_GETSOCKNAME |
| 3412 | if (p->port == 0) | 3426 | if (p->port == 0 |
| 3427 | #ifdef HAVE_LOCAL_SOCKETS | ||
| 3428 | && family != AF_LOCAL | ||
| 3429 | #endif | ||
| 3430 | ) | ||
| 3413 | { | 3431 | { |
| 3414 | struct sockaddr_in sa1; | 3432 | struct sockaddr_in sa1; |
| 3415 | socklen_t len1 = sizeof (sa1); | 3433 | socklen_t len1 = sizeof (sa1); |
| 3416 | if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0) | 3434 | #ifdef AF_INET6 |
| 3435 | /* The code below assumes the port is at the same offset | ||
| 3436 | and of the same width in both IPv4 and IPv6 | ||
| 3437 | structures, but the standards don't guarantee that, | ||
| 3438 | so verify it here. */ | ||
| 3439 | struct sockaddr_in6 sa6; | ||
| 3440 | verify ((offsetof (struct sockaddr_in, sin_port) | ||
| 3441 | == offsetof (struct sockaddr_in6, sin6_port)) | ||
| 3442 | && sizeof (sa1.sin_port) == sizeof (sa6.sin6_port)); | ||
| 3443 | #endif | ||
| 3444 | DECLARE_POINTER_ALIAS (psa1, struct sockaddr, &sa1); | ||
| 3445 | if (getsockname (s, psa1, &len1) == 0) | ||
| 3417 | { | 3446 | { |
| 3418 | Lisp_Object service; | 3447 | Lisp_Object service = make_number (ntohs (sa1.sin_port)); |
| 3419 | service = make_number (ntohs (sa1.sin_port)); | ||
| 3420 | contact = Fplist_put (contact, QCservice, service); | 3448 | contact = Fplist_put (contact, QCservice, service); |
| 3421 | /* Save the port number so that we can stash it in | 3449 | /* Save the port number so that we can stash it in |
| 3422 | the process object later. */ | 3450 | the process object later. */ |
| 3423 | ((struct sockaddr_in *)sa)->sin_port = sa1.sin_port; | 3451 | DECLARE_POINTER_ALIAS (psa, struct sockaddr_in, sa); |
| 3452 | psa->sin_port = sa1.sin_port; | ||
| 3424 | } | 3453 | } |
| 3425 | } | 3454 | } |
| 3426 | #endif | 3455 | #endif |
| @@ -3526,11 +3555,12 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos, | |||
| 3526 | #ifdef HAVE_GETSOCKNAME | 3555 | #ifdef HAVE_GETSOCKNAME |
| 3527 | if (!p->is_server) | 3556 | if (!p->is_server) |
| 3528 | { | 3557 | { |
| 3529 | struct sockaddr_in sa1; | 3558 | struct sockaddr_storage sa1; |
| 3530 | socklen_t len1 = sizeof (sa1); | 3559 | socklen_t len1 = sizeof (sa1); |
| 3531 | if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0) | 3560 | DECLARE_POINTER_ALIAS (psa1, struct sockaddr, &sa1); |
| 3561 | if (getsockname (s, psa1, &len1) == 0) | ||
| 3532 | contact = Fplist_put (contact, QClocal, | 3562 | contact = Fplist_put (contact, QClocal, |
| 3533 | conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1)); | 3563 | conv_sockaddr_to_lisp (psa1, len1)); |
| 3534 | } | 3564 | } |
| 3535 | #endif | 3565 | #endif |
| 3536 | } | 3566 | } |
| @@ -4379,7 +4409,7 @@ network_interface_info (Lisp_Object ifname) | |||
| 4379 | 4409 | ||
| 4380 | for (it = ifap; it != NULL; it = it->ifa_next) | 4410 | for (it = ifap; it != NULL; it = it->ifa_next) |
| 4381 | { | 4411 | { |
| 4382 | struct sockaddr_dl *sdl = (struct sockaddr_dl *) it->ifa_addr; | 4412 | DECLARE_POINTER_ALIAS (sdl, struct sockaddr_dl, it->ifa_addr); |
| 4383 | unsigned char linkaddr[6]; | 4413 | unsigned char linkaddr[6]; |
| 4384 | int n; | 4414 | int n; |
| 4385 | 4415 | ||
| @@ -4563,8 +4593,16 @@ is nil, from any process) before the timeout expired. */) | |||
| 4563 | /* Can't wait for a process that is dedicated to a different | 4593 | /* Can't wait for a process that is dedicated to a different |
| 4564 | thread. */ | 4594 | thread. */ |
| 4565 | if (!EQ (proc->thread, Qnil) && !EQ (proc->thread, Fcurrent_thread ())) | 4595 | if (!EQ (proc->thread, Qnil) && !EQ (proc->thread, Fcurrent_thread ())) |
| 4566 | error ("Attempt to accept output from process %s locked to thread %s", | 4596 | { |
| 4567 | SDATA (proc->name), SDATA (XTHREAD (proc->thread)->name)); | 4597 | Lisp_Object proc_thread_name = XTHREAD (proc->thread)->name; |
| 4598 | |||
| 4599 | if (STRINGP (proc_thread_name)) | ||
| 4600 | error ("Attempt to accept output from process %s locked to thread %s", | ||
| 4601 | SDATA (proc->name), SDATA (proc_thread_name)); | ||
| 4602 | else | ||
| 4603 | error ("Attempt to accept output from process %s locked to thread %p", | ||
| 4604 | SDATA (proc->name), XTHREAD (proc->thread)); | ||
| 4605 | } | ||
| 4568 | } | 4606 | } |
| 4569 | else | 4607 | else |
| 4570 | just_this_one = Qnil; | 4608 | just_this_one = Qnil; |
| @@ -4626,7 +4664,7 @@ static EMACS_INT connect_counter = 0; | |||
| 4626 | static void | 4664 | static void |
| 4627 | server_accept_connection (Lisp_Object server, int channel) | 4665 | server_accept_connection (Lisp_Object server, int channel) |
| 4628 | { | 4666 | { |
| 4629 | Lisp_Object proc, caller, name, buffer; | 4667 | Lisp_Object buffer; |
| 4630 | Lisp_Object contact, host, service; | 4668 | Lisp_Object contact, host, service; |
| 4631 | struct Lisp_Process *ps = XPROCESS (server); | 4669 | struct Lisp_Process *ps = XPROCESS (server); |
| 4632 | struct Lisp_Process *p; | 4670 | struct Lisp_Process *p; |
| @@ -4668,49 +4706,43 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4668 | information for this process. */ | 4706 | information for this process. */ |
| 4669 | host = Qt; | 4707 | host = Qt; |
| 4670 | service = Qnil; | 4708 | service = Qnil; |
| 4709 | Lisp_Object args[11]; | ||
| 4710 | int nargs = 0; | ||
| 4711 | AUTO_STRING (procname_format_in, "%s <%d.%d.%d.%d:%d>"); | ||
| 4712 | AUTO_STRING (procname_format_in6, "%s <[%x:%x:%x:%x:%x:%x:%x:%x]:%d>"); | ||
| 4713 | AUTO_STRING (procname_format_default, "%s <%d>"); | ||
| 4671 | switch (saddr.sa.sa_family) | 4714 | switch (saddr.sa.sa_family) |
| 4672 | { | 4715 | { |
| 4673 | case AF_INET: | 4716 | case AF_INET: |
| 4674 | { | 4717 | { |
| 4718 | args[nargs++] = procname_format_in; | ||
| 4719 | nargs++; | ||
| 4675 | unsigned char *ip = (unsigned char *)&saddr.in.sin_addr.s_addr; | 4720 | unsigned char *ip = (unsigned char *)&saddr.in.sin_addr.s_addr; |
| 4676 | |||
| 4677 | AUTO_STRING (ipv4_format, "%d.%d.%d.%d"); | ||
| 4678 | host = CALLN (Fformat, ipv4_format, | ||
| 4679 | make_number (ip[0]), make_number (ip[1]), | ||
| 4680 | make_number (ip[2]), make_number (ip[3])); | ||
| 4681 | service = make_number (ntohs (saddr.in.sin_port)); | 4721 | service = make_number (ntohs (saddr.in.sin_port)); |
| 4682 | AUTO_STRING (caller_format, " <%s:%d>"); | 4722 | for (int i = 0; i < 4; i++) |
| 4683 | caller = CALLN (Fformat, caller_format, host, service); | 4723 | args[nargs++] = make_number (ip[i]); |
| 4724 | args[nargs++] = service; | ||
| 4684 | } | 4725 | } |
| 4685 | break; | 4726 | break; |
| 4686 | 4727 | ||
| 4687 | #ifdef AF_INET6 | 4728 | #ifdef AF_INET6 |
| 4688 | case AF_INET6: | 4729 | case AF_INET6: |
| 4689 | { | 4730 | { |
| 4690 | Lisp_Object args[9]; | 4731 | args[nargs++] = procname_format_in6; |
| 4691 | uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr; | 4732 | nargs++; |
| 4692 | int i; | 4733 | DECLARE_POINTER_ALIAS (ip6, uint16_t, &saddr.in6.sin6_addr); |
| 4693 | |||
| 4694 | AUTO_STRING (ipv6_format, "%x:%x:%x:%x:%x:%x:%x:%x"); | ||
| 4695 | args[0] = ipv6_format; | ||
| 4696 | for (i = 0; i < 8; i++) | ||
| 4697 | args[i + 1] = make_number (ntohs (ip6[i])); | ||
| 4698 | host = CALLMANY (Fformat, args); | ||
| 4699 | service = make_number (ntohs (saddr.in.sin_port)); | 4734 | service = make_number (ntohs (saddr.in.sin_port)); |
| 4700 | AUTO_STRING (caller_format, " <[%s]:%d>"); | 4735 | for (int i = 0; i < 8; i++) |
| 4701 | caller = CALLN (Fformat, caller_format, host, service); | 4736 | args[nargs++] = make_number (ip6[i]); |
| 4737 | args[nargs++] = service; | ||
| 4702 | } | 4738 | } |
| 4703 | break; | 4739 | break; |
| 4704 | #endif | 4740 | #endif |
| 4705 | 4741 | ||
| 4706 | #ifdef HAVE_LOCAL_SOCKETS | ||
| 4707 | case AF_LOCAL: | ||
| 4708 | #endif | ||
| 4709 | default: | 4742 | default: |
| 4710 | caller = Fnumber_to_string (make_number (connect_counter)); | 4743 | args[nargs++] = procname_format_default; |
| 4711 | AUTO_STRING (space_less_than, " <"); | 4744 | nargs++; |
| 4712 | AUTO_STRING (greater_than, ">"); | 4745 | args[nargs++] = make_number (connect_counter); |
| 4713 | caller = concat3 (space_less_than, caller, greater_than); | ||
| 4714 | break; | 4746 | break; |
| 4715 | } | 4747 | } |
| 4716 | 4748 | ||
| @@ -4731,16 +4763,17 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4731 | buffer = ps->name; | 4763 | buffer = ps->name; |
| 4732 | if (!NILP (buffer)) | 4764 | if (!NILP (buffer)) |
| 4733 | { | 4765 | { |
| 4734 | buffer = concat2 (buffer, caller); | 4766 | args[1] = buffer; |
| 4735 | buffer = Fget_buffer_create (buffer); | 4767 | buffer = Fget_buffer_create (Fformat (nargs, args)); |
| 4736 | } | 4768 | } |
| 4737 | } | 4769 | } |
| 4738 | 4770 | ||
| 4739 | /* Generate a unique name for the new server process. Combine the | 4771 | /* Generate a unique name for the new server process. Combine the |
| 4740 | server process name with the caller identification. */ | 4772 | server process name with the caller identification. */ |
| 4741 | 4773 | ||
| 4742 | name = concat2 (ps->name, caller); | 4774 | args[1] = ps->name; |
| 4743 | proc = make_process (name); | 4775 | Lisp_Object name = Fformat (nargs, args); |
| 4776 | Lisp_Object proc = make_process (name); | ||
| 4744 | 4777 | ||
| 4745 | chan_process[s] = proc; | 4778 | chan_process[s] = proc; |
| 4746 | 4779 | ||
| @@ -5338,14 +5371,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5338 | nfds = xg_select (max_desc + 1, | 5371 | nfds = xg_select (max_desc + 1, |
| 5339 | &Available, (check_write ? &Writeok : 0), | 5372 | &Available, (check_write ? &Writeok : 0), |
| 5340 | NULL, &timeout, NULL); | 5373 | NULL, &timeout, NULL); |
| 5374 | #elif defined HAVE_NS | ||
| 5375 | /* And NS builds call thread_select in ns_select. */ | ||
| 5376 | nfds = ns_select (max_desc + 1, | ||
| 5377 | &Available, (check_write ? &Writeok : 0), | ||
| 5378 | NULL, &timeout, NULL); | ||
| 5341 | #else /* !HAVE_GLIB */ | 5379 | #else /* !HAVE_GLIB */ |
| 5342 | nfds = thread_select ( | 5380 | nfds = thread_select (pselect, max_desc + 1, |
| 5343 | # ifdef HAVE_NS | ||
| 5344 | ns_select | ||
| 5345 | # else | ||
| 5346 | pselect | ||
| 5347 | # endif | ||
| 5348 | , max_desc + 1, | ||
| 5349 | &Available, | 5381 | &Available, |
| 5350 | (check_write ? &Writeok : 0), | 5382 | (check_write ? &Writeok : 0), |
| 5351 | NULL, &timeout, NULL); | 5383 | NULL, &timeout, NULL); |