diff options
| author | Andreas Schwab | 2009-01-01 15:58:38 +0000 |
|---|---|---|
| committer | Andreas Schwab | 2009-01-01 15:58:38 +0000 |
| commit | 63136da6cab06479d733520c755981a0afa2f533 (patch) | |
| tree | 5469aae2986e0958aa4999bf36a13cb50d7ed863 /src/process.c | |
| parent | 097e9c90ee05614467d54f06dc6f8910c160d575 (diff) | |
| download | emacs-63136da6cab06479d733520c755981a0afa2f533.tar.gz emacs-63136da6cab06479d733520c755981a0afa2f533.zip | |
(conv_sockaddr_to_lisp): Add workaround for
getsockname bug on BSD.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/src/process.c b/src/process.c index 4172ffe1f50..681c9fa783d 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* Asynchronous subprocess control for GNU Emacs. | 1 | /* Asynchronous subprocess control for GNU Emacs. |
| 2 | Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, | 2 | Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, |
| 3 | 1996, 1998, 1999, 2001, 2002, 2003, 2004, | 3 | 1996, 1998, 1999, 2001, 2002, 2003, 2004, |
| 4 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 4 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -41,6 +41,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #ifdef HAVE_INTTYPES_H | 41 | #ifdef HAVE_INTTYPES_H |
| 42 | #include <inttypes.h> | 42 | #include <inttypes.h> |
| 43 | #endif | 43 | #endif |
| 44 | #ifdef STDC_HEADERS | ||
| 45 | #include <stdlib.h> | ||
| 46 | #endif | ||
| 44 | 47 | ||
| 45 | #ifdef HAVE_UNISTD_H | 48 | #ifdef HAVE_UNISTD_H |
| 46 | #include <unistd.h> | 49 | #include <unistd.h> |
| @@ -554,7 +557,7 @@ allocate_pty () | |||
| 554 | #ifdef PTY_TTY_NAME_SPRINTF | 557 | #ifdef PTY_TTY_NAME_SPRINTF |
| 555 | PTY_TTY_NAME_SPRINTF | 558 | PTY_TTY_NAME_SPRINTF |
| 556 | #else | 559 | #else |
| 557 | sprintf (pty_name, "/dev/tty%c%x", c, i); | 560 | sprintf (pty_name, "/dev/tty%c%x", c, i); |
| 558 | #endif /* no PTY_TTY_NAME_SPRINTF */ | 561 | #endif /* no PTY_TTY_NAME_SPRINTF */ |
| 559 | if (access (pty_name, 6) != 0) | 562 | if (access (pty_name, 6) != 0) |
| 560 | { | 563 | { |
| @@ -1477,7 +1480,7 @@ list_processes_1 (query_only) | |||
| 1477 | insert_string (tembuf); | 1480 | insert_string (tembuf); |
| 1478 | } | 1481 | } |
| 1479 | else if (NETCONN1_P (p)) | 1482 | else if (NETCONN1_P (p)) |
| 1480 | { | 1483 | { |
| 1481 | /* For a local socket, there is no host name, | 1484 | /* For a local socket, there is no host name, |
| 1482 | so display service instead. */ | 1485 | so display service instead. */ |
| 1483 | Lisp_Object host = Fplist_get (p->childp, QChost); | 1486 | Lisp_Object host = Fplist_get (p->childp, QChost); |
| @@ -1493,7 +1496,7 @@ list_processes_1 (query_only) | |||
| 1493 | (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"), | 1496 | (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"), |
| 1494 | (STRINGP (host) ? (char *)SDATA (host) : "?")); | 1497 | (STRINGP (host) ? (char *)SDATA (host) : "?")); |
| 1495 | insert_string (tembuf); | 1498 | insert_string (tembuf); |
| 1496 | } | 1499 | } |
| 1497 | else if (SERIALCONN1_P (p)) | 1500 | else if (SERIALCONN1_P (p)) |
| 1498 | { | 1501 | { |
| 1499 | Lisp_Object port = Fplist_get (p->childp, QCport); | 1502 | Lisp_Object port = Fplist_get (p->childp, QCport); |
| @@ -2264,6 +2267,12 @@ conv_sockaddr_to_lisp (sa, len) | |||
| 2264 | unsigned char *cp; | 2267 | unsigned char *cp; |
| 2265 | register struct Lisp_Vector *p; | 2268 | register struct Lisp_Vector *p; |
| 2266 | 2269 | ||
| 2270 | /* Workaround for a bug in getsockname on BSD: Names bound to | ||
| 2271 | sockets in the UNIX domain are inaccessible; getsockname returns | ||
| 2272 | a zero length name. */ | ||
| 2273 | if (len < OFFSETOF (struct sockaddr, sa_family) + sizeof (sa->sa_family)) | ||
| 2274 | return build_string (""); | ||
| 2275 | |||
| 2267 | switch (sa->sa_family) | 2276 | switch (sa->sa_family) |
| 2268 | { | 2277 | { |
| 2269 | case AF_INET: | 2278 | case AF_INET: |
| @@ -2273,14 +2282,14 @@ conv_sockaddr_to_lisp (sa, len) | |||
| 2273 | address = Fmake_vector (make_number (len), Qnil); | 2282 | address = Fmake_vector (make_number (len), Qnil); |
| 2274 | p = XVECTOR (address); | 2283 | p = XVECTOR (address); |
| 2275 | p->contents[--len] = make_number (ntohs (sin->sin_port)); | 2284 | p->contents[--len] = make_number (ntohs (sin->sin_port)); |
| 2276 | cp = (unsigned char *)&sin->sin_addr; | 2285 | cp = (unsigned char *) &sin->sin_addr; |
| 2277 | break; | 2286 | break; |
| 2278 | } | 2287 | } |
| 2279 | #ifdef AF_INET6 | 2288 | #ifdef AF_INET6 |
| 2280 | case AF_INET6: | 2289 | case AF_INET6: |
| 2281 | { | 2290 | { |
| 2282 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; | 2291 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; |
| 2283 | uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr; | 2292 | uint16_t *ip6 = (uint16_t *) &sin6->sin6_addr; |
| 2284 | len = sizeof (sin6->sin6_addr)/2 + 1; | 2293 | len = sizeof (sin6->sin6_addr)/2 + 1; |
| 2285 | address = Fmake_vector (make_number (len), Qnil); | 2294 | address = Fmake_vector (make_number (len), Qnil); |
| 2286 | p = XVECTOR (address); | 2295 | p = XVECTOR (address); |
| @@ -2301,11 +2310,11 @@ conv_sockaddr_to_lisp (sa, len) | |||
| 2301 | } | 2310 | } |
| 2302 | #endif | 2311 | #endif |
| 2303 | default: | 2312 | default: |
| 2304 | len -= sizeof (sa->sa_family); | 2313 | len -= OFFSETOF (struct sockaddr, sa_family) + sizeof (sa->sa_family); |
| 2305 | address = Fcons (make_number (sa->sa_family), | 2314 | address = Fcons (make_number (sa->sa_family), |
| 2306 | Fmake_vector (make_number (len), Qnil)); | 2315 | Fmake_vector (make_number (len), Qnil)); |
| 2307 | p = XVECTOR (XCDR (address)); | 2316 | p = XVECTOR (XCDR (address)); |
| 2308 | cp = (unsigned char *) sa + sizeof (sa->sa_family); | 2317 | cp = (unsigned char *) &sa->sa_family + sizeof (sa->sa_family); |
| 2309 | break; | 2318 | break; |
| 2310 | } | 2319 | } |
| 2311 | 2320 | ||
| @@ -3334,7 +3343,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3334 | #ifdef HAVE_GAI_STRERROR | 3343 | #ifdef HAVE_GAI_STRERROR |
| 3335 | error ("%s/%s %s", SDATA (host), portstring, gai_strerror(ret)); | 3344 | error ("%s/%s %s", SDATA (host), portstring, gai_strerror(ret)); |
| 3336 | #else | 3345 | #else |
| 3337 | error ("%s/%s getaddrinfo error %d", SDATA (host), portstring, ret); | 3346 | error ("%s/%s getaddrinfo error %d", SDATA (host), portstring, ret); |
| 3338 | #endif | 3347 | #endif |
| 3339 | immediate_quit = 0; | 3348 | immediate_quit = 0; |
| 3340 | 3349 | ||
| @@ -3455,7 +3464,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3455 | 3464 | ||
| 3456 | /* Parse network options in the arg list. | 3465 | /* Parse network options in the arg list. |
| 3457 | We simply ignore anything which isn't a known option (including other keywords). | 3466 | We simply ignore anything which isn't a known option (including other keywords). |
| 3458 | An error is signaled if setting a known option fails. */ | 3467 | An error is signaled if setting a known option fails. */ |
| 3459 | for (optn = optbits = 0; optn < nargs-1; optn += 2) | 3468 | for (optn = optbits = 0; optn < nargs-1; optn += 2) |
| 3460 | optbits |= set_socket_option (s, args[optn], args[optn+1]); | 3469 | optbits |= set_socket_option (s, args[optn], args[optn+1]); |
| 3461 | 3470 | ||
| @@ -4537,12 +4546,12 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4537 | QUIT; | 4546 | QUIT; |
| 4538 | #ifdef SYNC_INPUT | 4547 | #ifdef SYNC_INPUT |
| 4539 | else | 4548 | else |
| 4540 | { | 4549 | { |
| 4541 | if (interrupt_input_pending) | 4550 | if (interrupt_input_pending) |
| 4542 | handle_async_input (); | 4551 | handle_async_input (); |
| 4543 | if (pending_atimers) | 4552 | if (pending_atimers) |
| 4544 | do_pending_atimers (); | 4553 | do_pending_atimers (); |
| 4545 | } | 4554 | } |
| 4546 | #endif | 4555 | #endif |
| 4547 | 4556 | ||
| 4548 | /* Exit now if the cell we're waiting for became non-nil. */ | 4557 | /* Exit now if the cell we're waiting for became non-nil. */ |
| @@ -4674,7 +4683,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4674 | } | 4683 | } |
| 4675 | 4684 | ||
| 4676 | /* Don't wait for output from a non-running process. Just | 4685 | /* Don't wait for output from a non-running process. Just |
| 4677 | read whatever data has already been received. */ | 4686 | read whatever data has already been received. */ |
| 4678 | if (wait_proc && wait_proc->raw_status_new) | 4687 | if (wait_proc && wait_proc->raw_status_new) |
| 4679 | update_status (wait_proc); | 4688 | update_status (wait_proc); |
| 4680 | if (wait_proc | 4689 | if (wait_proc |
| @@ -4694,22 +4703,22 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4694 | if (nread == 0) | 4703 | if (nread == 0) |
| 4695 | break; | 4704 | break; |
| 4696 | 4705 | ||
| 4697 | if (0 < nread) | 4706 | if (0 < nread) |
| 4698 | { | 4707 | { |
| 4699 | total_nread += nread; | 4708 | total_nread += nread; |
| 4700 | got_some_input = 1; | 4709 | got_some_input = 1; |
| 4701 | } | 4710 | } |
| 4702 | #ifdef EIO | 4711 | #ifdef EIO |
| 4703 | else if (nread == -1 && EIO == errno) | 4712 | else if (nread == -1 && EIO == errno) |
| 4704 | break; | 4713 | break; |
| 4705 | #endif | 4714 | #endif |
| 4706 | #ifdef EAGAIN | 4715 | #ifdef EAGAIN |
| 4707 | else if (nread == -1 && EAGAIN == errno) | 4716 | else if (nread == -1 && EAGAIN == errno) |
| 4708 | break; | 4717 | break; |
| 4709 | #endif | 4718 | #endif |
| 4710 | #ifdef EWOULDBLOCK | 4719 | #ifdef EWOULDBLOCK |
| 4711 | else if (nread == -1 && EWOULDBLOCK == errno) | 4720 | else if (nread == -1 && EWOULDBLOCK == errno) |
| 4712 | break; | 4721 | break; |
| 4713 | #endif | 4722 | #endif |
| 4714 | } | 4723 | } |
| 4715 | if (total_nread > 0 && do_display) | 4724 | if (total_nread > 0 && do_display) |
| @@ -4804,11 +4813,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4804 | } | 4813 | } |
| 4805 | #endif | 4814 | #endif |
| 4806 | #ifdef HAVE_NS | 4815 | #ifdef HAVE_NS |
| 4807 | nfds = ns_select | 4816 | nfds = ns_select |
| 4808 | #else | 4817 | #else |
| 4809 | nfds = select | 4818 | nfds = select |
| 4810 | #endif | 4819 | #endif |
| 4811 | (max (max (max_process_desc, max_keyboard_desc), | 4820 | (max (max (max_process_desc, max_keyboard_desc), |
| 4812 | max_gpm_desc) + 1, | 4821 | max_gpm_desc) + 1, |
| 4813 | &Available, | 4822 | &Available, |
| 4814 | #ifdef NON_BLOCKING_CONNECT | 4823 | #ifdef NON_BLOCKING_CONNECT |
| @@ -5074,7 +5083,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 5074 | 5083 | ||
| 5075 | #ifdef GNU_LINUX | 5084 | #ifdef GNU_LINUX |
| 5076 | /* getsockopt(,,SO_ERROR,,) is said to hang on some systems. | 5085 | /* getsockopt(,,SO_ERROR,,) is said to hang on some systems. |
| 5077 | So only use it on systems where it is known to work. */ | 5086 | So only use it on systems where it is known to work. */ |
| 5078 | { | 5087 | { |
| 5079 | int xlen = sizeof(xerrno); | 5088 | int xlen = sizeof(xerrno); |
| 5080 | if (getsockopt(channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen)) | 5089 | if (getsockopt(channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen)) |
| @@ -5641,7 +5650,7 @@ send_process (proc, buf, len, object) | |||
| 5641 | if (p->pty_flag) | 5650 | if (p->pty_flag) |
| 5642 | { | 5651 | { |
| 5643 | /* Starting this at zero is always correct when not the first | 5652 | /* Starting this at zero is always correct when not the first |
| 5644 | iteration because the previous iteration ended by sending C-d. | 5653 | iteration because the previous iteration ended by sending C-d. |
| 5645 | It may not be correct for the first iteration | 5654 | It may not be correct for the first iteration |
| 5646 | if a partial line was sent in a separate send_process call. | 5655 | if a partial line was sent in a separate send_process call. |
| 5647 | If that proves worth handling, we need to save linepos | 5656 | If that proves worth handling, we need to save linepos |
| @@ -5945,7 +5954,7 @@ process_send_signal (process, signo, current_group, nomsg) | |||
| 5945 | by sending an input character to it. */ | 5954 | by sending an input character to it. */ |
| 5946 | 5955 | ||
| 5947 | /* TERMIOS is the latest and bestest, and seems most likely to | 5956 | /* TERMIOS is the latest and bestest, and seems most likely to |
| 5948 | work. If the system has it, use it. */ | 5957 | work. If the system has it, use it. */ |
| 5949 | #ifdef HAVE_TERMIOS | 5958 | #ifdef HAVE_TERMIOS |
| 5950 | struct termios t; | 5959 | struct termios t; |
| 5951 | cc_t *sig_char = NULL; | 5960 | cc_t *sig_char = NULL; |
| @@ -6548,7 +6557,7 @@ sigchld_handler (signo) | |||
| 6548 | #endif /* no WUNTRACED */ | 6557 | #endif /* no WUNTRACED */ |
| 6549 | /* Keep trying to get a status until we get a definitive result. */ | 6558 | /* Keep trying to get a status until we get a definitive result. */ |
| 6550 | do | 6559 | do |
| 6551 | { | 6560 | { |
| 6552 | errno = 0; | 6561 | errno = 0; |
| 6553 | pid = wait3 (&w, WNOHANG | WUNTRACED, 0); | 6562 | pid = wait3 (&w, WNOHANG | WUNTRACED, 0); |
| 6554 | } | 6563 | } |
| @@ -6645,7 +6654,7 @@ sigchld_handler (signo) | |||
| 6645 | if (WIFEXITED (w)) | 6654 | if (WIFEXITED (w)) |
| 6646 | synch_process_retcode = WRETCODE (w); | 6655 | synch_process_retcode = WRETCODE (w); |
| 6647 | else if (WIFSIGNALED (w)) | 6656 | else if (WIFSIGNALED (w)) |
| 6648 | synch_process_termsig = WTERMSIG (w); | 6657 | synch_process_termsig = WTERMSIG (w); |
| 6649 | 6658 | ||
| 6650 | /* Tell wait_reading_process_output that it needs to wake up and | 6659 | /* Tell wait_reading_process_output that it needs to wake up and |
| 6651 | look around. */ | 6660 | look around. */ |
| @@ -6663,7 +6672,7 @@ sigchld_handler (signo) | |||
| 6663 | to use up all the processes that have something to tell us. */ | 6672 | to use up all the processes that have something to tell us. */ |
| 6664 | #if (defined WINDOWSNT \ | 6673 | #if (defined WINDOWSNT \ |
| 6665 | || (defined USG && !defined GNU_LINUX \ | 6674 | || (defined USG && !defined GNU_LINUX \ |
| 6666 | && !(defined HPUX && defined WNOHANG))) | 6675 | && !(defined HPUX && defined WNOHANG))) |
| 6667 | #if defined (USG) && ! defined (POSIX_SIGNALS) | 6676 | #if defined (USG) && ! defined (POSIX_SIGNALS) |
| 6668 | signal (signo, sigchld_handler); | 6677 | signal (signo, sigchld_handler); |
| 6669 | #endif | 6678 | #endif |