diff options
| author | Karoly Lorentey | 2006-01-06 16:13:05 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-01-06 16:13:05 +0000 |
| commit | a8bf7299ee74781dd485c33c5eac20aee0f0ebef (patch) | |
| tree | d2bc1c0d3d7a64a19945b5bb5d175cae37088bca /src/process.c | |
| parent | e079ecf45241cc5d2904db7ede9592f9861bb9aa (diff) | |
| parent | 600bc46cd52fbdedf592158c6b03ccfca88dbade (diff) | |
| download | emacs-a8bf7299ee74781dd485c33c5eac20aee0f0ebef.tar.gz emacs-a8bf7299ee74781dd485c33c5eac20aee0f0ebef.zip | |
Merged from miles@gnu.org--gnu-2005 (patch 683-684)
Patches applied:
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-683
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-684
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-493
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 162 |
1 files changed, 142 insertions, 20 deletions
diff --git a/src/process.c b/src/process.c index e869456e5c8..05ea7c863b0 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -118,6 +118,14 @@ Boston, MA 02110-1301, USA. */ | |||
| 118 | #include <sys/wait.h> | 118 | #include <sys/wait.h> |
| 119 | #endif | 119 | #endif |
| 120 | 120 | ||
| 121 | /* Disable IPv6 support for w32 until someone figures out how to do it | ||
| 122 | properly. */ | ||
| 123 | #ifdef WINDOWSNT | ||
| 124 | # ifdef AF_INET6 | ||
| 125 | # undef AF_INET6 | ||
| 126 | # endif | ||
| 127 | #endif | ||
| 128 | |||
| 121 | #include "lisp.h" | 129 | #include "lisp.h" |
| 122 | #include "systime.h" | 130 | #include "systime.h" |
| 123 | #include "systty.h" | 131 | #include "systty.h" |
| @@ -140,7 +148,10 @@ Boston, MA 02110-1301, USA. */ | |||
| 140 | Lisp_Object Qprocessp; | 148 | Lisp_Object Qprocessp; |
| 141 | Lisp_Object Qrun, Qstop, Qsignal; | 149 | Lisp_Object Qrun, Qstop, Qsignal; |
| 142 | Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; | 150 | Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; |
| 143 | Lisp_Object Qlocal, Qdatagram; | 151 | Lisp_Object Qlocal, Qipv4, Qdatagram; |
| 152 | #ifdef AF_INET6 | ||
| 153 | Lisp_Object Qipv6; | ||
| 154 | #endif | ||
| 144 | Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; | 155 | Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; |
| 145 | Lisp_Object QClocal, QCremote, QCcoding; | 156 | Lisp_Object QClocal, QCremote, QCcoding; |
| 146 | Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; | 157 | Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; |
| @@ -1195,9 +1206,11 @@ a socket connection. */) | |||
| 1195 | DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, | 1206 | DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address, |
| 1196 | 1, 2, 0, | 1207 | 1, 2, 0, |
| 1197 | doc: /* Convert network ADDRESS from internal format to a string. | 1208 | doc: /* Convert network ADDRESS from internal format to a string. |
| 1209 | A 4 or 5 element vector represents an IPv4 address (with port number). | ||
| 1210 | An 8 or 9 element vector represents an IPv6 address (with port number). | ||
| 1198 | If optional second argument OMIT-PORT is non-nil, don't include a port | 1211 | If optional second argument OMIT-PORT is non-nil, don't include a port |
| 1199 | number in the string; in this case, interpret a 4 element vector as an | 1212 | number in the string, even when present in ADDRESS. |
| 1200 | IP address. Returns nil if format of ADDRESS is invalid. */) | 1213 | Returns nil if format of ADDRESS is invalid. */) |
| 1201 | (address, omit_port) | 1214 | (address, omit_port) |
| 1202 | Lisp_Object address, omit_port; | 1215 | Lisp_Object address, omit_port; |
| 1203 | { | 1216 | { |
| @@ -1207,13 +1220,13 @@ IP address. Returns nil if format of ADDRESS is invalid. */) | |||
| 1207 | if (STRINGP (address)) /* AF_LOCAL */ | 1220 | if (STRINGP (address)) /* AF_LOCAL */ |
| 1208 | return address; | 1221 | return address; |
| 1209 | 1222 | ||
| 1210 | if (VECTORP (address)) /* AF_INET */ | 1223 | if (VECTORP (address)) /* AF_INET or AF_INET6 */ |
| 1211 | { | 1224 | { |
| 1212 | register struct Lisp_Vector *p = XVECTOR (address); | 1225 | register struct Lisp_Vector *p = XVECTOR (address); |
| 1213 | Lisp_Object args[6]; | 1226 | Lisp_Object args[6]; |
| 1214 | int nargs, i; | 1227 | int nargs, i; |
| 1215 | 1228 | ||
| 1216 | if (!NILP (omit_port) && (p->size == 4 || p->size == 5)) | 1229 | if (p->size == 4 || (p->size == 5 && !NILP (omit_port))) |
| 1217 | { | 1230 | { |
| 1218 | args[0] = build_string ("%d.%d.%d.%d"); | 1231 | args[0] = build_string ("%d.%d.%d.%d"); |
| 1219 | nargs = 4; | 1232 | nargs = 4; |
| @@ -1223,6 +1236,16 @@ IP address. Returns nil if format of ADDRESS is invalid. */) | |||
| 1223 | args[0] = build_string ("%d.%d.%d.%d:%d"); | 1236 | args[0] = build_string ("%d.%d.%d.%d:%d"); |
| 1224 | nargs = 5; | 1237 | nargs = 5; |
| 1225 | } | 1238 | } |
| 1239 | else if (p->size == 8 || (p->size == 9 && !NILP (omit_port))) | ||
| 1240 | { | ||
| 1241 | args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); | ||
| 1242 | nargs = 8; | ||
| 1243 | } | ||
| 1244 | else if (p->size == 9) | ||
| 1245 | { | ||
| 1246 | args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d"); | ||
| 1247 | nargs = 9; | ||
| 1248 | } | ||
| 1226 | else | 1249 | else |
| 1227 | return Qnil; | 1250 | return Qnil; |
| 1228 | 1251 | ||
| @@ -2212,6 +2235,20 @@ conv_sockaddr_to_lisp (sa, len) | |||
| 2212 | cp = (unsigned char *)&sin->sin_addr; | 2235 | cp = (unsigned char *)&sin->sin_addr; |
| 2213 | break; | 2236 | break; |
| 2214 | } | 2237 | } |
| 2238 | #ifdef AF_INET6 | ||
| 2239 | case AF_INET6: | ||
| 2240 | { | ||
| 2241 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; | ||
| 2242 | uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr; | ||
| 2243 | len = sizeof (sin6->sin6_addr)/2 + 1; | ||
| 2244 | address = Fmake_vector (make_number (len), Qnil); | ||
| 2245 | p = XVECTOR (address); | ||
| 2246 | p->contents[--len] = make_number (ntohs (sin6->sin6_port)); | ||
| 2247 | for (i = 0; i < len; i++) | ||
| 2248 | p->contents[i] = make_number (ntohs (ip6[i])); | ||
| 2249 | return address; | ||
| 2250 | } | ||
| 2251 | #endif | ||
| 2215 | #ifdef HAVE_LOCAL_SOCKETS | 2252 | #ifdef HAVE_LOCAL_SOCKETS |
| 2216 | case AF_LOCAL: | 2253 | case AF_LOCAL: |
| 2217 | { | 2254 | { |
| @@ -2256,6 +2293,13 @@ get_lisp_to_sockaddr_size (address, familyp) | |||
| 2256 | *familyp = AF_INET; | 2293 | *familyp = AF_INET; |
| 2257 | return sizeof (struct sockaddr_in); | 2294 | return sizeof (struct sockaddr_in); |
| 2258 | } | 2295 | } |
| 2296 | #ifdef AF_INET6 | ||
| 2297 | else if (p->size == 9) | ||
| 2298 | { | ||
| 2299 | *familyp = AF_INET6; | ||
| 2300 | return sizeof (struct sockaddr_in6); | ||
| 2301 | } | ||
| 2302 | #endif | ||
| 2259 | } | 2303 | } |
| 2260 | #ifdef HAVE_LOCAL_SOCKETS | 2304 | #ifdef HAVE_LOCAL_SOCKETS |
| 2261 | else if (STRINGP (address)) | 2305 | else if (STRINGP (address)) |
| @@ -2302,6 +2346,23 @@ conv_lisp_to_sockaddr (family, address, sa, len) | |||
| 2302 | sin->sin_port = htons (i); | 2346 | sin->sin_port = htons (i); |
| 2303 | cp = (unsigned char *)&sin->sin_addr; | 2347 | cp = (unsigned char *)&sin->sin_addr; |
| 2304 | } | 2348 | } |
| 2349 | #ifdef AF_INET6 | ||
| 2350 | else if (family == AF_INET6) | ||
| 2351 | { | ||
| 2352 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; | ||
| 2353 | uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr; | ||
| 2354 | len = sizeof (sin6->sin6_addr) + 1; | ||
| 2355 | i = XINT (p->contents[--len]); | ||
| 2356 | sin6->sin6_port = htons (i); | ||
| 2357 | for (i = 0; i < len; i++) | ||
| 2358 | if (INTEGERP (p->contents[i])) | ||
| 2359 | { | ||
| 2360 | int j = XFASTINT (p->contents[i]) & 0xffff; | ||
| 2361 | ip6[i] = ntohs (j); | ||
| 2362 | } | ||
| 2363 | return; | ||
| 2364 | } | ||
| 2365 | #endif | ||
| 2305 | } | 2366 | } |
| 2306 | else if (STRINGP (address)) | 2367 | else if (STRINGP (address)) |
| 2307 | { | 2368 | { |
| @@ -2595,10 +2656,13 @@ a random port number is selected for the server. | |||
| 2595 | stream type connection, `datagram' creates a datagram type connection. | 2656 | stream type connection, `datagram' creates a datagram type connection. |
| 2596 | 2657 | ||
| 2597 | :family FAMILY -- FAMILY is the address (and protocol) family for the | 2658 | :family FAMILY -- FAMILY is the address (and protocol) family for the |
| 2598 | service specified by HOST and SERVICE. The default address family is | 2659 | service specified by HOST and SERVICE. The default (nil) is to use |
| 2599 | Inet (or IPv4) for the host and port number specified by HOST and | 2660 | whatever address family (IPv4 or IPv6) that is defined for the host |
| 2600 | SERVICE. Other address families supported are: | 2661 | and port number specified by HOST and SERVICE. Other address families |
| 2662 | supported are: | ||
| 2601 | local -- for a local (i.e. UNIX) address specified by SERVICE. | 2663 | local -- for a local (i.e. UNIX) address specified by SERVICE. |
| 2664 | ipv4 -- use IPv4 address family only. | ||
| 2665 | ipv6 -- use IPv6 address family only. | ||
| 2602 | 2666 | ||
| 2603 | :local ADDRESS -- ADDRESS is the local address used for the connection. | 2667 | :local ADDRESS -- ADDRESS is the local address used for the connection. |
| 2604 | This parameter is ignored when opening a client process. When specified | 2668 | This parameter is ignored when opening a client process. When specified |
| @@ -2715,8 +2779,8 @@ usage: (make-network-process &rest ARGS) */) | |||
| 2715 | struct Lisp_Process *p; | 2779 | struct Lisp_Process *p; |
| 2716 | #ifdef HAVE_GETADDRINFO | 2780 | #ifdef HAVE_GETADDRINFO |
| 2717 | struct addrinfo ai, *res, *lres; | 2781 | struct addrinfo ai, *res, *lres; |
| 2718 | struct addrinfo hints; | 2782 | struct addrinfo hints; |
| 2719 | char *portstring, portbuf[128]; | 2783 | char *portstring, portbuf[128]; |
| 2720 | #else /* HAVE_GETADDRINFO */ | 2784 | #else /* HAVE_GETADDRINFO */ |
| 2721 | struct _emacs_addrinfo | 2785 | struct _emacs_addrinfo |
| 2722 | { | 2786 | { |
| @@ -2855,19 +2919,29 @@ usage: (make-network-process &rest ARGS) */) | |||
| 2855 | 2919 | ||
| 2856 | /* :family FAMILY -- nil (for Inet), local, or integer. */ | 2920 | /* :family FAMILY -- nil (for Inet), local, or integer. */ |
| 2857 | tem = Fplist_get (contact, QCfamily); | 2921 | tem = Fplist_get (contact, QCfamily); |
| 2858 | if (INTEGERP (tem)) | 2922 | if (NILP (tem)) |
| 2859 | family = XINT (tem); | ||
| 2860 | else | ||
| 2861 | { | 2923 | { |
| 2862 | if (NILP (tem)) | 2924 | #if defined(HAVE_GETADDRINFO) && defined(AF_INET6) |
| 2863 | family = AF_INET; | 2925 | family = AF_UNSPEC; |
| 2864 | #ifdef HAVE_LOCAL_SOCKETS | 2926 | #else |
| 2865 | else if (EQ (tem, Qlocal)) | 2927 | family = AF_INET; |
| 2866 | family = AF_LOCAL; | ||
| 2867 | #endif | 2928 | #endif |
| 2868 | } | 2929 | } |
| 2869 | if (family < 0) | 2930 | #ifdef HAVE_LOCAL_SOCKETS |
| 2931 | else if (EQ (tem, Qlocal)) | ||
| 2932 | family = AF_LOCAL; | ||
| 2933 | #endif | ||
| 2934 | #ifdef AF_INET6 | ||
| 2935 | else if (EQ (tem, Qipv6)) | ||
| 2936 | family = AF_INET6; | ||
| 2937 | #endif | ||
| 2938 | else if (EQ (tem, Qipv4)) | ||
| 2939 | family = AF_INET; | ||
| 2940 | else if (INTEGERP (tem)) | ||
| 2941 | family = XINT (tem); | ||
| 2942 | else | ||
| 2870 | error ("Unknown address family"); | 2943 | error ("Unknown address family"); |
| 2944 | |||
| 2871 | ai.ai_family = family; | 2945 | ai.ai_family = family; |
| 2872 | 2946 | ||
| 2873 | /* :service SERVICE -- string, integer (port number), or t (random port). */ | 2947 | /* :service SERVICE -- string, integer (port number), or t (random port). */ |
| @@ -2933,7 +3007,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 2933 | QUIT; | 3007 | QUIT; |
| 2934 | memset (&hints, 0, sizeof (hints)); | 3008 | memset (&hints, 0, sizeof (hints)); |
| 2935 | hints.ai_flags = 0; | 3009 | hints.ai_flags = 0; |
| 2936 | hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family; | 3010 | hints.ai_family = family; |
| 2937 | hints.ai_socktype = socktype; | 3011 | hints.ai_socktype = socktype; |
| 2938 | hints.ai_protocol = 0; | 3012 | hints.ai_protocol = 0; |
| 2939 | ret = getaddrinfo (SDATA (host), portstring, &hints, &res); | 3013 | ret = getaddrinfo (SDATA (host), portstring, &hints, &res); |
| @@ -3522,6 +3596,21 @@ static struct ifflag_def ifflag_table[] = { | |||
| 3522 | #ifdef IFF_DYNAMIC | 3596 | #ifdef IFF_DYNAMIC |
| 3523 | { IFF_DYNAMIC, "dynamic" }, | 3597 | { IFF_DYNAMIC, "dynamic" }, |
| 3524 | #endif | 3598 | #endif |
| 3599 | #ifdef IFF_OACTIV | ||
| 3600 | { IFF_OACTIV, "oactiv" }, /* OpenBSD: transmission in progress */ | ||
| 3601 | #endif | ||
| 3602 | #ifdef IFF_SIMPLEX | ||
| 3603 | { IFF_SIMPLEX, "simplex" }, /* OpenBSD: can't hear own transmissions */ | ||
| 3604 | #endif | ||
| 3605 | #ifdef IFF_LINK0 | ||
| 3606 | { IFF_LINK0, "link0" }, /* OpenBSD: per link layer defined bit */ | ||
| 3607 | #endif | ||
| 3608 | #ifdef IFF_LINK1 | ||
| 3609 | { IFF_LINK1, "link1" }, /* OpenBSD: per link layer defined bit */ | ||
| 3610 | #endif | ||
| 3611 | #ifdef IFF_LINK2 | ||
| 3612 | { IFF_LINK2, "link2" }, /* OpenBSD: per link layer defined bit */ | ||
| 3613 | #endif | ||
| 3525 | { 0, 0 } | 3614 | { 0, 0 } |
| 3526 | }; | 3615 | }; |
| 3527 | 3616 | ||
| @@ -3816,6 +3905,9 @@ server_accept_connection (server, channel) | |||
| 3816 | union u_sockaddr { | 3905 | union u_sockaddr { |
| 3817 | struct sockaddr sa; | 3906 | struct sockaddr sa; |
| 3818 | struct sockaddr_in in; | 3907 | struct sockaddr_in in; |
| 3908 | #ifdef AF_INET6 | ||
| 3909 | struct sockaddr_in6 in6; | ||
| 3910 | #endif | ||
| 3819 | #ifdef HAVE_LOCAL_SOCKETS | 3911 | #ifdef HAVE_LOCAL_SOCKETS |
| 3820 | struct sockaddr_un un; | 3912 | struct sockaddr_un un; |
| 3821 | #endif | 3913 | #endif |
| @@ -3872,6 +3964,26 @@ server_accept_connection (server, channel) | |||
| 3872 | } | 3964 | } |
| 3873 | break; | 3965 | break; |
| 3874 | 3966 | ||
| 3967 | #ifdef AF_INET6 | ||
| 3968 | case AF_INET6: | ||
| 3969 | { | ||
| 3970 | Lisp_Object args[9]; | ||
| 3971 | uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr; | ||
| 3972 | int i; | ||
| 3973 | args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); | ||
| 3974 | for (i = 0; i < 8; i++) | ||
| 3975 | args[i+1] = make_number (ntohs(ip6[i])); | ||
| 3976 | host = Fformat (9, args); | ||
| 3977 | service = make_number (ntohs (saddr.in.sin_port)); | ||
| 3978 | |||
| 3979 | args[0] = build_string (" <[%s]:%d>"); | ||
| 3980 | args[1] = host; | ||
| 3981 | args[2] = service; | ||
| 3982 | caller = Fformat (3, args); | ||
| 3983 | } | ||
| 3984 | break; | ||
| 3985 | #endif | ||
| 3986 | |||
| 3875 | #ifdef HAVE_LOCAL_SOCKETS | 3987 | #ifdef HAVE_LOCAL_SOCKETS |
| 3876 | case AF_LOCAL: | 3988 | case AF_LOCAL: |
| 3877 | #endif | 3989 | #endif |
| @@ -6721,6 +6833,10 @@ init_process () | |||
| 6721 | #ifdef HAVE_LOCAL_SOCKETS | 6833 | #ifdef HAVE_LOCAL_SOCKETS |
| 6722 | ADD_SUBFEATURE (QCfamily, Qlocal); | 6834 | ADD_SUBFEATURE (QCfamily, Qlocal); |
| 6723 | #endif | 6835 | #endif |
| 6836 | ADD_SUBFEATURE (QCfamily, Qipv4); | ||
| 6837 | #ifdef AF_INET6 | ||
| 6838 | ADD_SUBFEATURE (QCfamily, Qipv6); | ||
| 6839 | #endif | ||
| 6724 | #ifdef HAVE_GETSOCKNAME | 6840 | #ifdef HAVE_GETSOCKNAME |
| 6725 | ADD_SUBFEATURE (QCservice, Qt); | 6841 | ADD_SUBFEATURE (QCservice, Qt); |
| 6726 | #endif | 6842 | #endif |
| @@ -6779,6 +6895,12 @@ syms_of_process () | |||
| 6779 | staticpro (&Qlisten); | 6895 | staticpro (&Qlisten); |
| 6780 | Qlocal = intern ("local"); | 6896 | Qlocal = intern ("local"); |
| 6781 | staticpro (&Qlocal); | 6897 | staticpro (&Qlocal); |
| 6898 | Qipv4 = intern ("ipv4"); | ||
| 6899 | staticpro (&Qipv4); | ||
| 6900 | #ifdef AF_INET6 | ||
| 6901 | Qipv6 = intern ("ipv6"); | ||
| 6902 | staticpro (&Qipv6); | ||
| 6903 | #endif | ||
| 6782 | Qdatagram = intern ("datagram"); | 6904 | Qdatagram = intern ("datagram"); |
| 6783 | staticpro (&Qdatagram); | 6905 | staticpro (&Qdatagram); |
| 6784 | 6906 | ||