Kazu Yamamoto (山本和彦) <[EMAIL PROTECTED]> writes: > Hello, > > From: [EMAIL PROTECTED] (Kim F. Storm) > Subject: Re: :family extension for make_network_process > >> > I would report one documentation mistake and propose an extension for >> > make_network_process. >> >> Does the following patch give good results? > > Yes. This code is much better than mine. > Thanks!
It seems odd to only partially support IPv6, so here is a more complete patch which adds an external representation of IPv6 addresses (a 9 element vector -- 8 x 16-bit values for the address + 1 port number). Can you pls. see if it makes sense. BTW, with IPv4, it is custom to write 1.2.3.4:999 to separate the IP address and port number. Is there a similar notation for IPv6? I have used 1:2:3:4:5:6:7:8;999 in this patch for format-network-address in lack of anything better.... *** process.c 01 Oct 2005 21:33:29 +0200 1.467 --- process.c 14 Dec 2005 16:42:54 +0100 *************** *** 140,146 **** Lisp_Object Qprocessp; Lisp_Object Qrun, Qstop, Qsignal; Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; ! Lisp_Object Qlocal, Qdatagram; Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; Lisp_Object QClocal, QCremote, QCcoding; Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; --- 140,149 ---- Lisp_Object Qprocessp; Lisp_Object Qrun, Qstop, Qsignal; Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; ! Lisp_Object Qlocal, Qipv4, Qdatagram; ! #ifdef AF_INET6 ! Lisp_Object Qipv6; ! #endif Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype; Lisp_Object QClocal, QCremote, QCcoding; Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; *************** *** 1197,1203 **** doc: /* Convert network ADDRESS from internal format to a string. If optional second argument OMIT-PORT is non-nil, don't include a port number in the string; in this case, interpret a 4 element vector as an ! IP address. Returns nil if format of ADDRESS is invalid. */) (address, omit_port) Lisp_Object address, omit_port; { --- 1200,1207 ---- doc: /* Convert network ADDRESS from internal format to a string. If optional second argument OMIT-PORT is non-nil, don't include a port number in the string; in this case, interpret a 4 element vector as an ! IPv4 address and an 8 element vector as an IPv6 address. ! Returns nil if format of ADDRESS is invalid. */) (address, omit_port) Lisp_Object address, omit_port; { *************** *** 1207,1213 **** if (STRINGP (address)) /* AF_LOCAL */ return address; ! if (VECTORP (address)) /* AF_INET */ { register struct Lisp_Vector *p = XVECTOR (address); Lisp_Object args[6]; --- 1211,1217 ---- if (STRINGP (address)) /* AF_LOCAL */ return address; ! if (VECTORP (address)) /* AF_INET or AF_INET6 */ { register struct Lisp_Vector *p = XVECTOR (address); Lisp_Object args[6]; *************** *** 1223,1228 **** --- 1227,1242 ---- args[0] = build_string ("%d.%d.%d.%d:%d"); nargs = 5; } + else if (!NILP (omit_port) && (p->size == 8 || p->size == 9)) + { + args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); + nargs = 8; + } + else if (p->size == 9) + { + args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x;%d"); + nargs = 9; + } else return Qnil; *************** *** 2212,2217 **** --- 2226,2244 ---- cp = (unsigned char *)&sin->sin_addr; break; } + #ifdef AF_INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + len = sizeof (sin6->sin6_addr)/2 + 1; + address = Fmake_vector (make_number (len), Qnil); + p = XVECTOR (address); + p->contents[--len] = make_number (ntohs (sin6->sin6_port)); + for (i = 0; i < len; i++) + p->contents[i] = make_number (ntohs (sin6->sin6_addr.s6_addr16[i])); + return address; + } + #endif #ifdef HAVE_LOCAL_SOCKETS case AF_LOCAL: { *************** *** 2256,2261 **** --- 2283,2295 ---- *familyp = AF_INET; return sizeof (struct sockaddr_in); } + #ifdef AF_INET6 + else if (p->size == 9) + { + *familyp = AF_INET6; + return sizeof (struct sockaddr_in6); + } + #endif } #ifdef HAVE_LOCAL_SOCKETS else if (STRINGP (address)) *************** *** 2302,2307 **** --- 2336,2357 ---- sin->sin_port = htons (i); cp = (unsigned char *)&sin->sin_addr; } + #ifdef AF_INET6 + else if (family == AF_INET6) + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + len = sizeof (sin6->sin6_addr) + 1; + i = XINT (p->contents[--len]); + sin6->sin6_port = htons (i); + for (i = 0; i < len; i++) + if (INTEGERP (p->contents[i])) + { + int j = XFASTINT (p->contents[i]) & 0xffff; + sin6->sin6_addr.s6_addr16[i] = ntohs (j); + } + return; + } + #endif } else if (STRINGP (address)) { *************** *** 2595,2604 **** stream type connection, `datagram' creates a datagram type connection. :family FAMILY -- FAMILY is the address (and protocol) family for the ! service specified by HOST and SERVICE. The default address family is ! Inet (or IPv4) 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. :local ADDRESS -- ADDRESS is the local address used for the connection. This parameter is ignored when opening a client process. When specified --- 2645,2657 ---- stream type connection, `datagram' creates a datagram type 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 *************** *** 2855,2873 **** /* :family FAMILY -- nil (for Inet), local, or integer. */ tem = Fplist_get (contact, QCfamily); ! if (INTEGERP (tem)) ! family = XINT (tem); ! else { ! if (NILP (tem)) ! family = AF_INET; ! #ifdef HAVE_LOCAL_SOCKETS ! else if (EQ (tem, Qlocal)) ! family = AF_LOCAL; #endif } ! if (family < 0) error ("Unknown address family"); ai.ai_family = family; /* :service SERVICE -- string, integer (port number), or t (random port). */ --- 2908,2936 ---- /* :family FAMILY -- nil (for Inet), local, or integer. */ tem = Fplist_get (contact, QCfamily); ! if (NILP (tem)) { ! #ifdef HAVE_GETADDRINFO ! family = AF_UNSPEC; ! #else ! family = AF_INET; #endif } ! #ifdef HAVE_LOCAL_SOCKETS ! else if (EQ (tem, Qlocal)) ! family = AF_LOCAL; ! #endif ! #ifdef AF_INET6 ! else if (EQ (tem, Qipv6)) ! family = AF_INET6; ! #endif ! else if (EQ (tem, Qipv4)) ! family = AF_INET; ! else if (INTEGERP (tem)) ! family = XINT (tem); ! else error ("Unknown address family"); + ai.ai_family = family; /* :service SERVICE -- string, integer (port number), or t (random port). */ *************** *** 2933,2939 **** QUIT; memset (&hints, 0, sizeof (hints)); hints.ai_flags = 0; ! hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family; hints.ai_socktype = socktype; hints.ai_protocol = 0; ret = getaddrinfo (SDATA (host), portstring, &hints, &res); --- 2996,3002 ---- QUIT; memset (&hints, 0, sizeof (hints)); hints.ai_flags = 0; ! hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = 0; ret = getaddrinfo (SDATA (host), portstring, &hints, &res); *************** *** 3816,3821 **** --- 3879,3887 ---- union u_sockaddr { struct sockaddr sa; struct sockaddr_in in; + #ifdef AF_INET6 + struct sockaddr_in6 in6; + #endif #ifdef HAVE_LOCAL_SOCKETS struct sockaddr_un un; #endif *************** *** 3872,3877 **** --- 3938,3963 ---- } break; + #ifdef AF_INET6 + case AF_INET6: + { + Lisp_Object args[9]; + uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr.s6_addr16; + int i; + args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); + for (i = 0; i < 8; i++) + args[i+1] = make_number (ntohs(ip6[i])); + host = Fformat (9, args); + service = make_number (ntohs (saddr.in.sin_port)); + + args[0] = build_string (" <%s;%d>"); + args[1] = host; + args[2] = service; + caller = Fformat (3, args); + } + break; + #endif + #ifdef HAVE_LOCAL_SOCKETS case AF_LOCAL: #endif *************** *** 6724,6729 **** --- 6810,6819 ---- #ifdef HAVE_LOCAL_SOCKETS ADD_SUBFEATURE (QCfamily, Qlocal); #endif + ADD_SUBFEATURE (QCfamily, Qipv4); + #ifdef AF_INET6 + ADD_SUBFEATURE (QCfamily, Qipv6); + #endif #ifdef HAVE_GETSOCKNAME ADD_SUBFEATURE (QCservice, Qt); #endif *************** *** 6782,6787 **** --- 6872,6883 ---- staticpro (&Qlisten); Qlocal = intern ("local"); staticpro (&Qlocal); + Qipv4 = intern ("ipv4"); + staticpro (&Qipv4); + #ifdef AF_INET6 + Qipv6 = intern ("ipv6"); + staticpro (&Qipv6); + #endif Qdatagram = intern ("datagram"); staticpro (&Qdatagram); -- Kim F. Storm <[EMAIL PROTECTED]> http://www.cua.dk _______________________________________________ emacs-pretest-bug mailing list emacs-pretest-bug@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug