[MLton] bug in MLton and bug in basis

Wesley W. Terpstra terpstra@gmail.com
Thu, 18 Aug 2005 11:43:58 +0200


--Apple-Mail-3-22150699
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed

First, the easy bug: in net/socket.sml, MLton uses LSB order even
on powerpc. This makes the Ctl.* methods return the result from
system calls with the endian backwards. It has gone unnoticed
because most of the operations there return/take a bool.

Next, whoever wrote the standard clearly did not understand what
Ctl.getERROR should do. It should return an OS.SysErr option, not
a bool! That system call tells you WHAT the last error was, not if there
was an error on the last operation (which you can infer if the last
error had a value of 0). The most common use of this system call is
to determine the return code from a previous non-blocking connect.
As one approach to agree with the standard in definition, but disagree
in spirit, I propose that getERROR raise the appropriate OS.SysErr
if there is an error, otherwise return false.

Clearly, this change is subject to debate.

I have attached a patch which addresses both of these issues.

--Apple-Mail-3-22150699
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="socket.patch"
Content-Disposition: attachment;
	filename=socket.patch

Index: basis-library/net/socket.sml
===================================================================
--- basis-library/net/socket.sml	(revision 3974)
+++ basis-library/net/socket.sml	(working copy)
@@ -85,8 +85,9 @@
       type level = Prim.Ctl.level
       type optname = Prim.Ctl.optname
       type request = Prim.Ctl.request
-      (* host byte order (LSB) *)
-      structure PW = PackWord32Little
+      
+      (* host byte order *)
+      structure PW = PackWord32Host
 
       val wordLen = PW.bytesPerElem
       fun unmarshalWord (wa, _, s): word = 
@@ -215,7 +216,12 @@
       val setRCVBUF = setSockOptInt (Prim.Ctl.SOCKET, Prim.Ctl.RCVBUF)
       fun getTYPE s =
 	 Prim.SOCK.fromInt (getSockOptInt (Prim.Ctl.SOCKET, Prim.Ctl.TYPE) s)
-      val getERROR = getSockOptBool (Prim.Ctl.SOCKET, Prim.Ctl.ERROR)
+      fun getERROR s = 
+      	 let
+      	    val errno = getSockOptInt (Prim.Ctl.SOCKET, Prim.Ctl.ERROR) s
+      	 in
+      	    if errno = 0 then false else Error.raiseSys errno
+      	 end
       local
 	 fun getName (s, f: Prim.sock * pre_sock_addr * int ref -> int) =
 	    let
Index: basis-library/integer/pack-word32.sml
===================================================================
--- basis-library/integer/pack-word32.sml	(revision 3974)
+++ basis-library/integer/pack-word32.sml	(working copy)
@@ -60,3 +60,5 @@
 
 structure PackWord32Big = PackWord32 (val isBigEndian = true)
 structure PackWord32Little = PackWord32 (val isBigEndian = false)
+structure PackWord32Host = 
+   PackWord32(val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian)

--Apple-Mail-3-22150699--