<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
</style>
</head>
<body class='hmmessage'>
I commited a workaround here, that introduces essentially a third copy of relevant code.<BR>
Anyone have further ideas?<BR>
 <BR>
 <BR>
 <BR><FONT size=2>
(* This is a clone of IP.GetHostAddr that returns<BR>
TRUE if IP.GetHostAddr is likely to succeed and<BR>
FALSE if IP.GetHostAddr is likely to fail. *)<BR>
VAR mu := NEW(MUTEX);<BR>
 <BR>
PROCEDURE PredictIPGetHostAddrSuccess(): BOOLEAN =<BR>
VAR hname: ARRAY [0..255] OF CHAR;<BR>
BEGIN<BR>
LOCK mu DO<BR>
RETURN (Unix.gethostname(ADR(hname[0]), BYTESIZE(hname)) = 0)<BR>
AND (Unetdb.gethostbyname(ADR(hname[0])) # NIL);<BR>
END;<BR>
END PredictIPGetHostAddrSuccess;<BR>
 <BR>
(* return TRUE if server and client are on same host *)<BR>
PROCEDURE SameHost (trsl: XClient.T): BOOLEAN =<BR>
VAR<BR>
display := DisplayHost(trsl);<BR>
displayAddr: IP.Address;<BR>
 <BR>
BEGIN<BR>
 <BR>
IF display = NIL THEN RETURN TRUE; END;<BR>
 <BR>
TRY<BR>
 <BR>
IF NOT IP.GetHostByName(display, displayAddr) THEN RETURN FALSE; END;<BR>
 <BR>
(* IP.GetHostAddr can return a fatal exception; try to avoid that<BR>
by predicting its success. *)<BR>
IF NOT PredictIPGetHostAddrSuccess() THEN<BR>
RETURN FALSE;<BR>
END;<BR>
 <BR>
RETURN displayAddr = IP.GetHostAddr();<BR>
EXCEPT<BR>
| IP.Error => RETURN FALSE;<BR>
END;<BR>
END SameHost;<BR></FONT>
 <BR>
 - Jay<BR><BR>

<HR id=stopSpelling>
<BR>
From: jay.krell@cornell.edu<BR>To: m3devel@elegosoft.com<BR>Date: Sun, 11 Jan 2009 12:57:13 +0000<BR>Subject: [M3devel] Juno (X) networking problem on AMD64_FREEBSD<BR><BR>
<STYLE>
.ExternalClass .EC_hmmessage P
{padding:0px;}
.ExternalClass body.EC_hmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Hi. Unix network programming question..<BR><BR>AMD64_FREEBSD:<BR><BR>$DISPLAY is set to point back to Cygwin host.<BR>It works for PPC_LINUX.<BR><BR>[jay@fbsdamd64a /cm3/bin]$ ./Juno<BR><BR>***<BR>*** runtime error:<BR>***    Exception "IPError.FatalError" not in RAISES list<BR>***    file "../src/common/IPError.m3", line 27<BR>***<BR><BR>Abort trap: 6 (core dumped)<BR>[jay@fbsdamd64a /cm3/bin]$<BR><BR>IP.m3:<BR> <BR>PROCEDURE GetHostAddr(): Address =<BR>  VAR hname: ARRAY [0..255] OF CHAR;<BR>  BEGIN<BR>    LOCK mu DO<BR>      IF Unix.gethostname(ADR(hname[0]), BYTESIZE(hname)) # 0 THEN<BR>        IPError.Die ();<BR>      END;<BR>      VAR h := Unetdb.gethostbyname(ADR(hname[0])); BEGIN<BR>        IF h = NIL THEN IPError.Die(); END;<BR>        RETURN GetAddress(h);<BR>      END;<BR>    END;<BR>  END GetHostAddr;<BR><BR>PROCEDURE GetAddress (ent: Unetdb.struct_hostent_star): Address =<BR>  VAR ua: Uin.struct_in_addr;<BR>  BEGIN<BR>    <* ASSERT ent.h_length <= BYTESIZE(Address) *><BR>    ua := LOOPHOLE(ent.h_addr_list,<BR>                    UNTRACED REF UNTRACED REF Uin.struct_in_addr)^^;<BR>    RETURN LOOPHOLE(ua.s_addr, Address);<BR>  END GetAddress;<BR> <BR>gethostbyname is failing.<BR><BR> <BR>Analogous C code also fails:<BR> <BR><BR>[jay@fbsdamd64a /cm3/bin]$ cat ~/5.c<BR>#include <assert.h><BR>#include <netdb.h><BR>#include <stdio.h><BR>#include <errno.h><BR>typedef struct hostent hostent_t;<BR> <BR>int main()<BR>{<BR> char hostname[200];<BR> hostent_t* h;<BR> int i;<BR> i = gethostname(hostname, 200);<BR> assert(i == 0);<BR> printf("hostname: %s\n", hostname);<BR> h = gethostbyname(hostname);<BR> herror("foo");<BR> printf("%p %d %d\n", h, errno, h_errno);<BR> assert(h);<BR> return 0;<BR>}<BR> <BR>herror says "unknown host".<BR><BR>Stack is:<BR>    at ../src/runtime/ex_frame/RTExFrame.m3:58<BR>#13 0x0000000801a7f2b3 in RTHooks__Raise (M3_AJWxb1_ex=Error accessing memory ad<BR>dress 0x8000ffffd278: Bad address.<BR>)<BR>    at ../src/runtime/common/RTHooks.m3:79<BR>#14 0x000000080169c8d3 in IPError__Die () at ../src/common/IPError.m3:27<BR>#15 0x0000000801698a3e in IP__GetHostAddr (M3_BCxjPn__result=Error accessing mem<BR>ory address 0x8000ffffd338: Bad address.<BR>)<BR>    at ../src/POSIX/IP.m3:82<BR>#16 0x00000008012133d0 in XSharedMem__SameHost (M3_AQuuui_trsl=Error accessing m<BR>emory address 0x8000ffffd4d8: Bad address.<BR>)<BR>    at ../src/xvbt/XSharedMem.m3:96<BR>#17 0x0000000801212ab7 in XSharedMem__InitXClient (M3_AQuuui_v=Error accessing m<BR>emory address 0x8000ffffd648: Bad address.<BR>)<BR>    at ../src/xvbt/XSharedMem.m3:29<BR>#18 0x0000000801211819 in XExtensions__InitXClient (M3_AQuuui_xclient=Error acce<BR>ssing memory address 0x8000ffffd7f8: Bad address.<BR>)<BR>    at ../src/xvbt/XExtensions.m3:14<BR>#19 0x00000008012467a4 in XClientF__Connect (M3_Bd56fi_inst=0x1879b,<BR>    M3_AQuuui_trsl=0x6) at ../src/xvbt/XClientF.m3:583<BR>---Type <return> to continue, or q <return> to quit---<BR>(More stack frames follow...)<BR>(gdb)<BR><BR>(* return TRUE if server and client are on same host *)<BR>PROCEDURE SameHost (trsl: XClient.T): BOOLEAN =<BR>  VAR<BR>    display                 := DisplayHost(trsl);<BR>    displayAddr: IP.Address;<BR>  BEGIN<BR>    IF display = NIL THEN RETURN TRUE; END;<BR>    TRY<BR>      IF NOT IP.GetHostByName(display, displayAddr) THEN RETURN FALSE; END;<BR>      RETURN displayAddr = IP.GetHostAddr();<BR>    EXCEPT<BR>    | IP.Error => RETURN FALSE;<BR>    END;<BR>  END SameHost;<BR> <BR>Thoughts?<BR> <BR><BR>Perhaps my network isn't setup well, like I should add the local machine to /etc/hosts.<BR>I think this can be made to fail gracefully though.<BR>It seems like it has nothing to do with AMD64_FREEBSD, but could have to do with FreeBSD.<BR><BR> <BR>Seems like SocketPosix has nearly the exact same code but appears<BR>more forgiving.. IOError instead of Fatal?<BR> <BR><BR>SocketPosix.m3:<BR> <BR><BR>PROCEDURE GetHostAddr (): Address<BR>  RAISES {OSError.E} =<BR>  VAR<BR>    host : ARRAY [0..255] OF CHAR;<BR>    info : Unetdb.struct_hostent_star;<BR>    ua   : Uin.struct_in_addr;<BR>  BEGIN<BR>    IF Unix.gethostname (ADR (host[0]), BYTESIZE (host)) # 0 THEN<BR>      IOError (Unexpected);<BR>    END;<BR>    info := Unetdb.gethostbyname (ADR (host[0]));<BR>    IF info = NIL THEN IOError (Unexpected); END;<BR>    <* ASSERT info.h_length <= BYTESIZE (Address) *><BR>    ua := LOOPHOLE(info.h_addr_list,<BR>                   UNTRACED REF UNTRACED REF Uin.struct_in_addr)^^;<BR>    RETURN LOOPHOLE (ua.s_addr, Address);<BR>  END GetHostAddr;<BR> <BR> <BR>It is again disappointing to see such code duplication.<BR> <BR> <BR>I guess SameHost can duplicate the logic to predict the error state and return false upon error?<BR>Duplicating the logic for a third time. :(<BR> <BR><BR> - Jay<BR><BR><BR></body>
</html>