diff -Naur ocaml-unix-3.11.2/LICENSE ocaml-unix-3.12.1/LICENSE
--- ocaml-unix-3.11.2/LICENSE   2007-01-30 11:01:25.000000000 +0100
+++ ocaml-unix-3.12.1/LICENSE   2011-05-13 10:40:05.000000000 +0200
@@ -6,8 +6,9 @@
 and "the Compiler" refers to all files marked "Copyright INRIA" in the
 following directories and their sub-directories:

-  asmcomp, boot, bytecomp, debugger, driver, lex, ocamldoc, parsing,
-  tools, toplevel, typing, utils, yacc
+  asmcomp, boot, build, bytecomp, debugger, driver, lex, man,
+  ocamlbuild, ocamldoc, parsing, testsuite, tools, toplevel, typing,
+  utils, yacc

 The Compiler is distributed under the terms of the Q Public License
 version 1.0 with a change to choice of law (included below).
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/accept.c ocaml-unix-3.12.1/otherlibs/unix/accept.c
--- ocaml-unix-3.11.2/otherlibs/unix/accept.c   2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/accept.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: accept.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: accept.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -50,5 +50,5 @@

 CAMLprim value unix_accept(value sock)
 { invalid_argument("accept not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/addrofstr.c ocaml-unix-3.12.1/otherlibs/unix/addrofstr.c
--- ocaml-unix-3.11.2/otherlibs/unix/addrofstr.c        2004-04-09 15:25:23.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/addrofstr.c        2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: addrofstr.c 6193 2004-04-09 13:25:23Z xleroy $ */
+/* $Id: addrofstr.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <fail.h>
@@ -49,5 +49,5 @@

 CAMLprim value unix_inet_addr_of_string(value s)
 { invalid_argument("inet_addr_of_string not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/bind.c ocaml-unix-3.12.1/otherlibs/unix/bind.c
--- ocaml-unix-3.11.2/otherlibs/unix/bind.c     2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/bind.c     2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: bind.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: bind.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <fail.h>
 #include <mlvalues.h>
@@ -20,7 +20,7 @@
 #ifdef HAS_SOCKETS

 #include "socketaddr.h"
-  
+
 CAMLprim value unix_bind(value socket, value address)
 {
   int ret;
@@ -37,5 +37,5 @@

 CAMLprim value unix_bind(value socket, value address)
 { invalid_argument("bind not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/connect.c ocaml-unix-3.12.1/otherlibs/unix/connect.c
--- ocaml-unix-3.11.2/otherlibs/unix/connect.c  2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/connect.c  2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: connect.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: connect.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <fail.h>
 #include <mlvalues.h>
@@ -40,5 +40,5 @@

 CAMLprim value unix_connect(value socket, value address)
 { invalid_argument("connect not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/cstringv.c ocaml-unix-3.12.1/otherlibs/unix/cstringv.c
--- ocaml-unix-3.11.2/otherlibs/unix/cstringv.c 2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/cstringv.c 2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: cstringv.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: cstringv.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -28,5 +28,3 @@
   res[size] = NULL;
   return res;
 }
-
-  
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/.depend ocaml-unix-3.12.1/otherlibs/unix/.depend
--- ocaml-unix-3.11.2/otherlibs/unix/.depend    2008-10-15 15:13:07.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/.depend    2011-07-04 23:15:01.000000000 +0200
@@ -1,796 +1,457 @@
 accept.o: accept.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 access.o: access.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
   ../../byterun/mlvalues.h unixsupport.h
 addrofstr.o: addrofstr.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/fail.h ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/fail.h ../../byterun/mlvalues.h \
+  unixsupport.h socketaddr.h ../../byterun/misc.h
 alarm.o: alarm.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 bind.o: bind.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h socketaddr.h \
+  ../../byterun/misc.h
 chdir.o: chdir.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 chmod.o: chmod.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 chown.o: chown.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 chroot.o: chroot.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 close.o: close.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 closedir.o: closedir.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h unixsupport.h
+  ../../byterun/misc.h unixsupport.h
 connect.o: connect.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h ../../byterun/signals.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 cst2constr.o: cst2constr.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/fail.h ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h cst2constr.h
+  ../../byterun/misc.h ../../byterun/fail.h ../../byterun/mlvalues.h \
+  cst2constr.h
 cstringv.o: cstringv.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/memory.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/gc.h ../../byterun/mlvalues.h \
-  ../../byterun/major_gc.h ../../byterun/freelist.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/misc.h ../../byterun/minor_gc.h \
-  ../../byterun/misc.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  unixsupport.h
+  ../../byterun/misc.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h unixsupport.h
 dup.o: dup.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 dup2.o: dup2.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 envir.o: envir.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
   ../../byterun/mlvalues.h
 errmsg.o: errmsg.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
   ../../byterun/mlvalues.h
 execv.o: execv.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h unixsupport.h
 execve.o: execve.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h unixsupport.h
 execvp.o: execvp.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h unixsupport.h
 exit.o: exit.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 fchmod.o: fchmod.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 fchown.o: fchown.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 fcntl.o: fcntl.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 fork.o: fork.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h \
+  ../../byterun/debugger.h ../../byterun/mlvalues.h unixsupport.h
 ftruncate.o: ftruncate.c ../../byterun/fail.h \
   ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/mlvalues.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/misc.h ../../byterun/io.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h ../../byterun/io.h unixsupport.h
 getaddrinfo.o: getaddrinfo.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h cst2constr.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h \
+  cst2constr.h socketaddr.h ../../byterun/misc.h
 getcwd.o: getcwd.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h unixsupport.h
 getegid.o: getegid.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h unixsupport.h
+  ../../byterun/misc.h unixsupport.h
 geteuid.o: geteuid.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h unixsupport.h
+  ../../byterun/misc.h unixsupport.h
 getgid.o: getgid.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 getgr.o: getgr.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/fail.h \
+  ../../byterun/mlvalues.h ../../byterun/alloc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 getgroups.o: getgroups.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 gethost.o: gethost.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 gethostname.o: gethostname.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 getlogin.o: getlogin.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  unixsupport.h
 getnameinfo.o: getnameinfo.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 getpeername.o: getpeername.c ../../byterun/fail.h \
   ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/mlvalues.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/misc.h unixsupport.h socketaddr.h
+  ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h socketaddr.h \
+  ../../byterun/misc.h
 getpid.o: getpid.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 getppid.o: getppid.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h unixsupport.h
+  ../../byterun/misc.h unixsupport.h
 getproto.o: getproto.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 getpw.o: getpw.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/fail.h unixsupport.h
 getserv.o: getserv.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 getsockname.o: getsockname.c ../../byterun/fail.h \
   ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/mlvalues.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/misc.h unixsupport.h socketaddr.h
+  ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h socketaddr.h \
+  ../../byterun/misc.h
 gettimeofday.o: gettimeofday.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 getuid.o: getuid.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 gmtime.o: gmtime.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
+initgroups.o: initgroups.c ../../byterun/mlvalues.h \
+  ../../byterun/compatibility.h ../../byterun/config.h \
+  ../../byterun/../config/m.h ../../byterun/../config/s.h \
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 isatty.o: isatty.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 itimer.o: itimer.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 kill.o: kill.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/fail.h \
+  ../../byterun/mlvalues.h unixsupport.h ../../byterun/signals.h
 link.o: link.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 listen.o: listen.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
-lockf.o: lockf.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
   ../../byterun/mlvalues.h unixsupport.h
+lockf.o: lockf.c ../../byterun/fail.h ../../byterun/compatibility.h \
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h ../../byterun/signals.h unixsupport.h
 lseek.o: lseek.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/io.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/io.h ../../byterun/signals.h \
+  unixsupport.h
 mkdir.o: mkdir.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 mkfifo.o: mkfifo.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 nice.o: nice.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 open.o: open.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h
 opendir.o: opendir.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  unixsupport.h
 pipe.o: pipe.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
   ../../byterun/mlvalues.h unixsupport.h
 putenv.o: putenv.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/memory.h ../../byterun/gc.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h \
+  ../../byterun/mlvalues.h unixsupport.h
 read.o: read.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h \
+  ../../byterun/signals.h unixsupport.h
 readdir.o: readdir.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/fail.h ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/fail.h ../../byterun/mlvalues.h \
+  ../../byterun/alloc.h unixsupport.h
 readlink.o: readlink.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 rename.o: rename.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 rewinddir.o: rewinddir.c ../../byterun/fail.h \
   ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/mlvalues.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/misc.h unixsupport.h
+  ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 rmdir.o: rmdir.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 select.o: select.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h
 sendrecv.o: sendrecv.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 setgid.o: setgid.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
+setgroups.o: setgroups.c ../../byterun/mlvalues.h \
+  ../../byterun/compatibility.h ../../byterun/config.h \
+  ../../byterun/../config/m.h ../../byterun/../config/s.h \
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 setsid.o: setsid.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 setuid.o: setuid.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 shutdown.o: shutdown.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
-signals.o: signals.c ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
   ../../byterun/mlvalues.h unixsupport.h
+signals.o: signals.c ../../byterun/alloc.h ../../byterun/compatibility.h \
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/mlvalues.h \
+  ../../byterun/signals.h unixsupport.h
 sleep.o: sleep.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h \
+  ../../byterun/signals.h ../../byterun/mlvalues.h unixsupport.h
 socket.o: socket.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 socketaddr.o: socketaddr.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h \
-  socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/memory.h ../../byterun/gc.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h unixsupport.h \
+  socketaddr.h ../../byterun/misc.h
 socketpair.o: socketpair.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 sockopt.o: sockopt.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/memory.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/gc.h ../../byterun/mlvalues.h \
-  ../../byterun/major_gc.h ../../byterun/freelist.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/misc.h ../../byterun/minor_gc.h \
-  ../../byterun/misc.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h ../../byterun/alloc.h \
+  ../../byterun/fail.h unixsupport.h socketaddr.h ../../byterun/misc.h
 stat.o: stat.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h cst2constr.h ../../byterun/io.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h ../../byterun/alloc.h \
+  unixsupport.h cst2constr.h ../../byterun/io.h
 strofaddr.o: strofaddr.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h socketaddr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h socketaddr.h ../../byterun/misc.h
 symlink.o: symlink.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 termios.o: termios.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/fail.h unixsupport.h
 time.o: time.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
   ../../byterun/mlvalues.h unixsupport.h
 times.o: times.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h unixsupport.h
 truncate.o: truncate.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/fail.h ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/io.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/fail.h ../../byterun/mlvalues.h \
+  ../../byterun/io.h unixsupport.h
 umask.o: umask.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 unixsupport.o: unixsupport.c ../../byterun/mlvalues.h \
   ../../byterun/compatibility.h ../../byterun/config.h \
   ../../byterun/../config/m.h ../../byterun/../config/s.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/compatibility.h ../../byterun/config.h \
-  ../../byterun/alloc.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/callback.h \
-  ../../byterun/compatibility.h ../../byterun/mlvalues.h \
-  ../../byterun/memory.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/gc.h ../../byterun/mlvalues.h \
-  ../../byterun/major_gc.h ../../byterun/freelist.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/misc.h ../../byterun/minor_gc.h \
-  ../../byterun/misc.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/fail.h ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h cst2constr.h
+  ../../byterun/misc.h ../../byterun/alloc.h ../../byterun/mlvalues.h \
+  ../../byterun/callback.h ../../byterun/memory.h ../../byterun/gc.h \
+  ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/fail.h unixsupport.h \
+  cst2constr.h
 unlink.o: unlink.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h unixsupport.h
 utimes.o: utimes.c ../../byterun/fail.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/mlvalues.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/misc.h unixsupport.h
+  ../../byterun/misc.h ../../byterun/config.h ../../byterun/../config/m.h \
+  ../../byterun/../config/s.h ../../byterun/mlvalues.h \
+  ../../byterun/mlvalues.h unixsupport.h
 wait.o: wait.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/alloc.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/fail.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/alloc.h \
+  ../../byterun/mlvalues.h ../../byterun/fail.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/major_gc.h ../../byterun/freelist.h \
+  ../../byterun/minor_gc.h ../../byterun/signals.h unixsupport.h
 write.o: write.c ../../byterun/mlvalues.h ../../byterun/compatibility.h \
   ../../byterun/config.h ../../byterun/../config/m.h \
-  ../../byterun/../config/s.h ../../byterun/compatibility.h \
-  ../../byterun/misc.h ../../byterun/compatibility.h \
-  ../../byterun/config.h ../../byterun/memory.h \
-  ../../byterun/compatibility.h ../../byterun/config.h ../../byterun/gc.h \
-  ../../byterun/mlvalues.h ../../byterun/major_gc.h \
-  ../../byterun/freelist.h ../../byterun/misc.h ../../byterun/mlvalues.h \
-  ../../byterun/misc.h ../../byterun/minor_gc.h ../../byterun/misc.h \
-  ../../byterun/misc.h ../../byterun/mlvalues.h ../../byterun/signals.h \
-  ../../byterun/compatibility.h ../../byterun/misc.h \
-  ../../byterun/mlvalues.h unixsupport.h
-unix.cmi: 
-unixLabels.cmi: unix.cmi 
-unix.cmo: unix.cmi 
-unix.cmx: unix.cmi 
-unixLabels.cmo: unix.cmi unixLabels.cmi 
-unixLabels.cmx: unix.cmx unixLabels.cmi 
+  ../../byterun/../config/s.h ../../byterun/misc.h ../../byterun/memory.h \
+  ../../byterun/gc.h ../../byterun/mlvalues.h ../../byterun/major_gc.h \
+  ../../byterun/freelist.h ../../byterun/minor_gc.h \
+  ../../byterun/signals.h unixsupport.h
+unix.cmi:
+unixLabels.cmi: unix.cmi
+unix.cmo: unix.cmi
+unix.cmx: unix.cmi
+unixLabels.cmo: unix.cmi unixLabels.cmi
+unixLabels.cmx: unix.cmx unixLabels.cmi
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/execv.c ocaml-unix-3.12.1/otherlibs/unix/execv.c
--- ocaml-unix-3.11.2/otherlibs/unix/execv.c    2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/execv.c    2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: execv.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: execv.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -29,4 +29,3 @@
   return Val_unit;                  /* never reached, but suppress warnings */
                                 /* from smart compilers */
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/execve.c ocaml-unix-3.12.1/otherlibs/unix/execve.c
--- ocaml-unix-3.11.2/otherlibs/unix/execve.c   2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/execve.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: execve.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: execve.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -32,4 +32,3 @@
   return Val_unit;                  /* never reached, but suppress warnings */
                                 /* from smart compilers */
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/execvp.c ocaml-unix-3.12.1/otherlibs/unix/execvp.c
--- ocaml-unix-3.11.2/otherlibs/unix/execvp.c   2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/execvp.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: execvp.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: execvp.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -48,4 +48,3 @@
   return Val_unit;                  /* never reached, but suppress warnings */
                                 /* from smart compilers */
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/exit.c ocaml-unix-3.12.1/otherlibs/unix/exit.c
--- ocaml-unix-3.11.2/otherlibs/unix/exit.c     2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/exit.c     2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: exit.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: exit.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include "unixsupport.h"
@@ -22,5 +22,3 @@
   return Val_unit;                  /* never reached, but suppress warnings */
                                     /* from smart compilers */
 }
-
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/fchmod.c ocaml-unix-3.12.1/otherlibs/unix/fchmod.c
--- ocaml-unix-3.11.2/otherlibs/unix/fchmod.c   2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/fchmod.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: fchmod.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: fchmod.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <sys/types.h>
 #include <sys/stat.h>
@@ -31,5 +31,5 @@

 CAMLprim value unix_fchmod(value fd, value perm)
 { invalid_argument("fchmod not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/fchown.c ocaml-unix-3.12.1/otherlibs/unix/fchown.c
--- ocaml-unix-3.11.2/otherlibs/unix/fchown.c   2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/fchown.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: fchown.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: fchown.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <fail.h>
 #include <mlvalues.h>
@@ -30,5 +30,5 @@

 CAMLprim value unix_fchown(value fd, value uid, value gid)
 { invalid_argument("fchown not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/fork.c ocaml-unix-3.12.1/otherlibs/unix/fork.c
--- ocaml-unix-3.11.2/otherlibs/unix/fork.c     2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/fork.c     2010-04-20 17:47:15.000000000 +0200
@@ -11,9 +11,10 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: fork.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: fork.c 10287 2010-04-20 15:47:15Z doligez $ */

 #include <mlvalues.h>
+#include <debugger.h>
 #include "unixsupport.h"

 CAMLprim value unix_fork(value unit)
@@ -21,6 +22,9 @@
   int ret;
   ret = fork();
   if (ret == -1) uerror("fork", Nothing);
+  if (caml_debugger_in_use)
+    if ((caml_debugger_fork_mode && ret == 0) ||
+        (!caml_debugger_fork_mode && ret != 0))
+      caml_debugger_cleanup_fork();
   return Val_int(ret);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/gethost.c ocaml-unix-3.12.1/otherlibs/unix/gethost.c
--- ocaml-unix-3.11.2/otherlibs/unix/gethost.c  2006-09-20 13:14:37.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/gethost.c  2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: gethost.c 7619 2006-09-20 11:14:37Z doligez $ */
+/* $Id: gethost.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <string.h>
 #include <mlvalues.h>
@@ -176,8 +176,8 @@

 CAMLprim value unix_gethostbyaddr(value name)
 { invalid_argument("gethostbyaddr not implemented"); }
-  
+
 CAMLprim value unix_gethostbyname(value name)
 { invalid_argument("gethostbyname not implemented"); }
- 
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/getnameinfo.c ocaml-unix-3.12.1/otherlibs/unix/getnameinfo.c
--- ocaml-unix-3.11.2/otherlibs/unix/getnameinfo.c      2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/getnameinfo.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: getnameinfo.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: getnameinfo.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <string.h>
 #include <mlvalues.h>
@@ -46,7 +46,7 @@
   get_sockaddr(vaddr, &addr, &addr_len);
   opts = convert_flag_list(vopts, getnameinfo_flag_table);
   enter_blocking_section();
-  retcode = 
+  retcode =
     getnameinfo((const struct sockaddr *) &addr.s_gen, addr_len,
                 host, sizeof(host), serv, sizeof(serv), opts);
   leave_blocking_section();
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/getpeername.c ocaml-unix-3.12.1/otherlibs/unix/getpeername.c
--- ocaml-unix-3.11.2/otherlibs/unix/getpeername.c      2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/getpeername.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: getpeername.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: getpeername.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <fail.h>
 #include <mlvalues.h>
@@ -37,5 +37,5 @@

 CAMLprim value unix_getpeername(value sock)
 { invalid_argument("getpeername not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/getproto.c ocaml-unix-3.12.1/otherlibs/unix/getproto.c
--- ocaml-unix-3.11.2/otherlibs/unix/getproto.c 2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/getproto.c 2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: getproto.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: getproto.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -63,7 +63,7 @@

 CAMLprim value unix_getprotobynumber(value proto)
 { invalid_argument("getprotobynumber not implemented"); }
-  
+
 CAMLprim value unix_getprotobyname(value name)
 { invalid_argument("getprotobyname not implemented"); }

diff -Naur ocaml-unix-3.11.2/otherlibs/unix/getserv.c ocaml-unix-3.12.1/otherlibs/unix/getserv.c
--- ocaml-unix-3.11.2/otherlibs/unix/getserv.c  2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/getserv.c  2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: getserv.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: getserv.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -69,7 +69,7 @@

 CAMLprim value unix_getservbyport(value port, value proto)
 { invalid_argument("getservbyport not implemented"); }
-  
+
 CAMLprim value unix_getservbyname(value name, value proto)
 { invalid_argument("getservbyname not implemented"); }

diff -Naur ocaml-unix-3.11.2/otherlibs/unix/getsockname.c ocaml-unix-3.12.1/otherlibs/unix/getsockname.c
--- ocaml-unix-3.11.2/otherlibs/unix/getsockname.c      2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/getsockname.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: getsockname.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: getsockname.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <fail.h>
 #include <mlvalues.h>
@@ -37,5 +37,5 @@

 CAMLprim value unix_getsockname(value sock)
 { invalid_argument("getsockname not implemented"); }
-  
+
 #endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/initgroups.c ocaml-unix-3.12.1/otherlibs/unix/initgroups.c
--- ocaml-unix-3.11.2/otherlibs/unix/initgroups.c       1970-01-01 01:00:00.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/initgroups.c       2009-04-16 09:23:35.000000000 +0200
@@ -0,0 +1,43 @@
+/***********************************************************************/
+/*                                                                     */
+/*                           Objective Caml                            */
+/*                                                                     */
+/*  Copyright 2009 Institut National de Recherche en Informatique et   */
+/*  en Automatique.  All rights reserved.  This file is distributed    */
+/*  under the terms of the GNU Library General Public License, with    */
+/*  the special exception on linking described in file ../../LICENSE.  */
+/*                                                                     */
+/***********************************************************************/
+
+/* Contributed by Stephane Glondu <steph@glondu.net> */
+
+/* $Id: initgroups.c 9235 2009-04-16 07:23:35Z xleroy $ */
+
+#include <mlvalues.h>
+#include <alloc.h>
+#include <fail.h>
+
+#ifdef HAS_INITGROUPS
+
+#include <sys/types.h>
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
+#include <limits.h>
+#include <grp.h>
+#include "unixsupport.h"
+
+CAMLprim value unix_initgroups(value user, value group)
+{
+  if (initgroups(String_val(user), Int_val(group)) == -1) {
+    uerror("initgroups", Nothing);
+  }
+  return Val_unit;
+}
+
+#else
+
+CAMLprim value unix_initgroups(value user, value group)
+{ invalid_argument("initgroups not implemented"); }
+
+#endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/itimer.c ocaml-unix-3.12.1/otherlibs/unix/itimer.c
--- ocaml-unix-3.11.2/otherlibs/unix/itimer.c   2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/itimer.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: itimer.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: itimer.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -56,7 +56,7 @@
     uerror("setitimer", Nothing);
   return unix_convert_itimer(&old);
 }
-     
+
 CAMLprim value unix_getitimer(value which)
 {
   struct itimerval val;
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/libunix.clib ocaml-unix-3.12.1/otherlibs/unix/libunix.clib
--- ocaml-unix-3.11.2/otherlibs/unix/libunix.clib       2007-02-07 10:52:28.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/libunix.clib       2010-01-11 15:27:59.000000000 +0100
@@ -5,11 +5,11 @@
 getaddrinfo.o getcwd.o getegid.o geteuid.o getgid.o
 getgr.o getgroups.o gethost.o gethostname.o getlogin.o
 getnameinfo.o getpeername.o getpid.o getppid.o getproto.o getpw.o
-gettimeofday.o getserv.o getsockname.o getuid.o
-gmtime.o isatty.o itimer.o kill.o link.o listen.o lockf.o lseek.o mkdir.o
-mkfifo.o nice.o open.o opendir.o pipe.o putenv.o read.o
+gettimeofday.o getserv.o getsockname.o getuid.o gmtime.o
+initgroups.o isatty.o itimer.o kill.o link.o listen.o lockf.o lseek.o
+mkdir.o mkfifo.o nice.o open.o opendir.o pipe.o putenv.o read.o
 readdir.o readlink.o rename.o rewinddir.o rmdir.o select.o sendrecv.o
-setgid.o setsid.o setuid.o shutdown.o signals.o
+setgid.o setgroups.o setsid.o setuid.o shutdown.o signals.o
 sleep.o socket.o socketaddr.o
 socketpair.o sockopt.o stat.o strofaddr.o symlink.o termios.o
 time.o times.o truncate.o umask.o unixsupport.o unlink.o
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/lseek.c ocaml-unix-3.12.1/otherlibs/unix/lseek.c
--- ocaml-unix-3.11.2/otherlibs/unix/lseek.c    2002-03-02 10:16:39.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/lseek.c    2010-08-18 14:44:33.000000000 +0200
@@ -11,13 +11,14 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: lseek.c 4474 2002-03-02 09:16:39Z xleroy $ */
+/* $Id: lseek.c 10647 2010-08-18 12:44:33Z doligez $ */

 #include <errno.h>
 #include <sys/types.h>
 #include <mlvalues.h>
 #include <alloc.h>
 #include <io.h>
+#include <signals.h>
 #include "unixsupport.h"

 #ifdef HAS_UNISTD
@@ -39,8 +40,10 @@
 CAMLprim value unix_lseek(value fd, value ofs, value cmd)
 {
   file_offset ret;
+  caml_enter_blocking_section();
   ret = lseek(Int_val(fd), Long_val(ofs),
                        seek_command_table[Int_val(cmd)]);
+  caml_leave_blocking_section();
   if (ret == -1) uerror("lseek", Nothing);
   if (ret > Max_long) unix_error(EOVERFLOW, "lseek", Nothing);
   return Val_long(ret);
@@ -49,9 +52,13 @@
 CAMLprim value unix_lseek_64(value fd, value ofs, value cmd)
 {
   file_offset ret;
-  ret = lseek(Int_val(fd), File_offset_val(ofs),
-                       seek_command_table[Int_val(cmd)]);
+  /* [ofs] is an Int64, which is stored as a custom block; we must therefore
+     extract its contents before dropping the runtime lock, or it might be
+     moved. */
+  file_offset ofs_c = File_offset_val(ofs);
+  caml_enter_blocking_section();
+  ret = lseek(Int_val(fd), ofs_c, seek_command_table[Int_val(cmd)]);
+  caml_leave_blocking_section();
   if (ret == -1) uerror("lseek", Nothing);
   return Val_file_offset(ret);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/Makefile ocaml-unix-3.12.1/otherlibs/unix/Makefile
--- ocaml-unix-3.11.2/otherlibs/unix/Makefile   2007-11-06 16:16:56.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/Makefile   2010-05-20 11:40:41.000000000 +0200
@@ -11,7 +11,7 @@
 #                                                                       #
 #########################################################################

-# $Id: Makefile 8477 2007-11-06 15:16:56Z frisch $
+# $Id: Makefile 10442 2010-05-20 09:40:41Z xleroy $

 # Makefile for the Unix interface library

@@ -26,11 +26,11 @@
   getaddrinfo.o getcwd.o getegid.o geteuid.o getgid.o \
   getgr.o getgroups.o gethost.o gethostname.o getlogin.o \
   getnameinfo.o getpeername.o getpid.o getppid.o getproto.o getpw.o \
-  gettimeofday.o getserv.o getsockname.o getuid.o \
-  gmtime.o isatty.o itimer.o kill.o link.o listen.o lockf.o lseek.o mkdir.o \
-  mkfifo.o nice.o open.o opendir.o pipe.o putenv.o read.o \
+  gettimeofday.o getserv.o getsockname.o getuid.o gmtime.o \
+  initgroups.o isatty.o itimer.o kill.o link.o listen.o lockf.o lseek.o \
+  mkdir.o mkfifo.o nice.o open.o opendir.o pipe.o putenv.o read.o \
   readdir.o readlink.o rename.o rewinddir.o rmdir.o select.o sendrecv.o \
-  setgid.o setsid.o setuid.o shutdown.o signals.o \
+  setgid.o setgroups.o setsid.o setuid.o shutdown.o signals.o \
   sleep.o socket.o socketaddr.o \
   socketpair.o sockopt.o stat.o strofaddr.o symlink.o termios.o \
   time.o times.o truncate.o umask.o unixsupport.o unlink.o \
@@ -38,7 +38,7 @@

 CAMLOBJS=unix.cmo unixLabels.cmo

-HEADERS=unixsupport.h
+HEADERS=unixsupport.h socketaddr.h

 include ../Makefile

diff -Naur ocaml-unix-3.11.2/otherlibs/unix/open.c ocaml-unix-3.12.1/otherlibs/unix/open.c
--- ocaml-unix-3.11.2/otherlibs/unix/open.c     2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/open.c     2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: open.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: open.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -35,7 +35,7 @@
 #endif

 static int open_flag_table[] = {
-  O_RDONLY, O_WRONLY, O_RDWR, O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL, 
+  O_RDONLY, O_WRONLY, O_RDWR, O_NONBLOCK, O_APPEND, O_CREAT, O_TRUNC, O_EXCL,
   O_NOCTTY, O_DSYNC, O_SYNC, O_RSYNC
 };

diff -Naur ocaml-unix-3.11.2/otherlibs/unix/select.c ocaml-unix-3.12.1/otherlibs/unix/select.c
--- ocaml-unix-3.11.2/otherlibs/unix/select.c   2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/select.c   2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: select.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: select.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -62,7 +62,7 @@
   return res;
 }

-CAMLprim value unix_select(value readfds, value writefds, value exceptfds, 
+CAMLprim value unix_select(value readfds, value writefds, value exceptfds,
                            value timeout)
 {
   fd_set read, write, except;
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/setgroups.c ocaml-unix-3.12.1/otherlibs/unix/setgroups.c
--- ocaml-unix-3.11.2/otherlibs/unix/setgroups.c        1970-01-01 01:00:00.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/setgroups.c        2009-04-01 18:50:10.000000000 +0200
@@ -0,0 +1,53 @@
+/***********************************************************************/
+/*                                                                     */
+/*                           Objective Caml                            */
+/*                                                                     */
+/*  Copyright 2009 Institut National de Recherche en Informatique et   */
+/*  en Automatique.  All rights reserved.  This file is distributed    */
+/*  under the terms of the GNU Library General Public License, with    */
+/*  the special exception on linking described in file ../../LICENSE.  */
+/*                                                                     */
+/***********************************************************************/
+
+/* Contributed by Stephane Glondu <steph@glondu.net> */
+
+/* $Id: setgroups.c 9220 2009-04-01 16:50:10Z xleroy $ */
+
+#include <mlvalues.h>
+#include <alloc.h>
+#include <fail.h>
+#include <memory.h>
+
+#ifdef HAS_SETGROUPS
+
+#include <sys/types.h>
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
+#include <limits.h>
+#include <grp.h>
+#include "unixsupport.h"
+
+CAMLprim value unix_setgroups(value groups)
+{
+  gid_t * gidset;
+  mlsize_t size, i;
+  int n;
+
+  size = Wosize_val(groups);
+  gidset = (gid_t *) stat_alloc(size * sizeof(gid_t));
+  for (i = 0; i < size; i++) gidset[i] = Int_val(Field(groups, i));
+
+  n = setgroups(size, gidset);
+
+  stat_free(gidset);
+  if (n == -1) uerror("setgroups", Nothing);
+  return Val_unit;
+}
+
+#else
+
+CAMLprim value unix_setgroups(value groups)
+{ invalid_argument("setgroups not implemented"); }
+
+#endif
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/socketaddr.c ocaml-unix-3.12.1/otherlibs/unix/socketaddr.c
--- ocaml-unix-3.11.2/otherlibs/unix/socketaddr.c       2009-10-18 11:36:13.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/socketaddr.c       2010-01-20 17:26:46.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: socketaddr.c 9377 2009-10-18 09:36:13Z xleroy $ */
+/* $Id: socketaddr.c 9540 2010-01-20 16:26:46Z doligez $ */

 #include <string.h>
 #include <mlvalues.h>
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/sockopt.c ocaml-unix-3.12.1/otherlibs/unix/sockopt.c
--- ocaml-unix-3.11.2/otherlibs/unix/sockopt.c  2008-08-01 15:46:08.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/sockopt.c  2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: sockopt.c 8968 2008-08-01 13:46:08Z xleroy $ */
+/* $Id: sockopt.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -126,10 +126,10 @@
   { SOL_SOCKET, SO_SNDLOWAT } };

 static struct socket_option sockopt_linger[] = {
-  { SOL_SOCKET, SO_LINGER } 
+  { SOL_SOCKET, SO_LINGER }
 };

-static struct socket_option sockopt_timeval[] = { 
+static struct socket_option sockopt_timeval[] = {
   { SOL_SOCKET, SO_RCVTIMEO },
   { SOL_SOCKET, SO_SNDTIMEO }
 };
@@ -226,7 +226,7 @@
   }
 }

-CAMLexport value 
+CAMLexport value
 unix_setsockopt_aux(char * name,
                     enum option_type ty, int level, int option,
                     value socket, value val)
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/stat.c ocaml-unix-3.12.1/otherlibs/unix/stat.c
--- ocaml-unix-3.11.2/otherlibs/unix/stat.c     2003-05-05 16:20:58.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/stat.c     2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: stat.c 5540 2003-05-05 14:20:58Z xleroy $ */
+/* $Id: stat.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <errno.h>
 #include <mlvalues.h>
@@ -137,4 +137,3 @@
   if (ret == -1) uerror("fstat", Nothing);
   return stat_aux(1, &buf);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/termios.c ocaml-unix-3.12.1/otherlibs/unix/termios.c
--- ocaml-unix-3.11.2/otherlibs/unix/termios.c  2005-03-24 18:20:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/termios.c  2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: termios.c 6824 2005-03-24 17:20:54Z doligez $ */
+/* $Id: termios.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -39,7 +39,7 @@
 #define NFIELDS 38

 /* Structure of the terminal_io record. Cf. unix.mli */
-  
+
 static long terminal_io_descr[] = {
   /* Input modes */
   Bool, iflags, IGNBRK,
@@ -314,4 +314,3 @@
 { invalid_argument("tcflow not implemented"); }

 #endif
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/unixLabels.mli ocaml-unix-3.12.1/otherlibs/unix/unixLabels.mli
--- ocaml-unix-3.11.2/otherlibs/unix/unixLabels.mli     2008-08-01 15:46:08.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/unixLabels.mli     2011-03-06 17:15:34.000000000 +0100
@@ -11,7 +11,7 @@
 (*                                                                     *)
 (***********************************************************************)

-(* $Id: unixLabels.mli 8968 2008-08-01 13:46:08Z xleroy $ *)
+(* $Id: unixLabels.mli 10971 2011-03-06 16:15:34Z weis $ *)

 (** Interface to the Unix system.
    To use as replacement to default {!Unix} module,
@@ -146,7 +146,9 @@
   | WSTOPPED of int
         (** The process was stopped by a signal; the argument is the
            signal number. *)
-(** The termination status of a process. *)
+(** The termination status of a process.  See module {!Sys} for the
+    definitions of the standard signal numbers.  Note that they are
+    not the numbers used by the OS. *)


 type wait_flag = Unix.wait_flag =
@@ -167,11 +169,11 @@
    environment to the program executed. *)

 val execvp : prog:string -> args:string array -> 'a
-(** Same as {!UnixLabels.execv} respectively, except that
+(** Same as {!UnixLabels.execv}, except that
    the program is searched in the path. *)

 val execvpe : prog:string -> args:string array -> env:string array -> 'a
-(** Same as {!UnixLabels.execvp} respectively, except that
+(** Same as {!UnixLabels.execve}, except that
    the program is searched in the path. *)

 val fork : unit -> int
@@ -183,7 +185,7 @@
    and termination status. *)

 val waitpid : mode:wait_flag list -> int -> int * process_status
-(** Same as {!UnixLabels.wait}, but waits for the process whose pid is given.
+(** Same as {!UnixLabels.wait}, but waits for the child process whose pid is given.
    A pid of [-1] means wait for any child.
    A pid of [0] means wait for any child in the same process group
    as the current process.
@@ -338,7 +340,7 @@
     st_mtime : float;           (** Last modification time *)
     st_ctime : float;           (** Last status change time *)
   }
-(** The informations returned by the {!UnixLabels.stat} calls. *)
+(** The information returned by the {!UnixLabels.stat} calls. *)

 val stat : string -> stats
 (** Return the information for the named file. *)
@@ -472,7 +474,6 @@
    See {!UnixLabels.set_close_on_exec}.*)


-
 (** {6 Directories} *)


@@ -670,7 +671,6 @@
    the functions {!Sys.signal} and {!Sys.set_signal}.
 *)

-
 val kill : pid:int -> signal:int -> unit
 (** [kill pid sig] sends signal number [sig] to the process
    with id [pid]. *)
@@ -764,7 +764,8 @@
 val utimes : string -> access:float -> modif:float -> unit
 (** Set the last access time (second arg) and last modification time
    (third arg) for a file. Times are expressed in seconds from
-   00:00:00 GMT, Jan. 1, 1970. *)
+   00:00:00 GMT, Jan. 1, 1970.  A time of [0.0] is interpreted as the
+   current time. *)

 type interval_timer = Unix.interval_timer =
     ITIMER_REAL
@@ -823,6 +824,16 @@
 (** Return the list of groups to which the user executing the process
    belongs. *)

+val setgroups : int array -> unit
+  (** [setgroups groups] sets the supplementary group IDs for the
+      calling process. Appropriate privileges are required. *)
+
+val initgroups : string -> int -> unit
+  (** [initgroups user group] initializes the group access list by
+      reading the group database /etc/group and using all groups of
+      which [user] is a member. The additional group [group] is also
+      added to the list. *)
+
 type passwd_entry = Unix.passwd_entry =
   { pw_name : string;
     pw_passwd : string;
@@ -903,7 +914,8 @@
     PF_UNIX                     (** Unix domain *)
   | PF_INET                     (** Internet domain (IPv4) *)
   | PF_INET6                    (** Internet domain (IPv6) *)
-(** The type of socket domains. *)
+(** The type of socket domains.  Not all platforms support
+    IPv6 sockets (type [PF_INET6]). *)

 type socket_type = Unix.socket_type =
     SOCK_STREAM                 (** Stream socket *)
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/unix.ml ocaml-unix-3.12.1/otherlibs/unix/unix.ml
--- ocaml-unix-3.11.2/otherlibs/unix/unix.ml    2008-08-01 15:46:08.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/unix.ml    2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 (*                                                                     *)
 (***********************************************************************)

-(* $Id: unix.ml 8968 2008-08-01 13:46:08Z xleroy $ *)
+(* $Id: unix.ml 9547 2010-01-22 12:48:24Z doligez $ *)

 type error =
     E2BIG
@@ -365,6 +365,8 @@
 external getegid : unit -> int = "unix_getegid"
 external setgid : int -> unit = "unix_setgid"
 external getgroups : unit -> int array = "unix_getgroups"
+external setgroups : int array -> unit = "unix_setgroups"
+external initgroups : string -> int -> unit = "unix_initgroups"

 type passwd_entry =
   { pw_name : string;
@@ -442,7 +444,7 @@
 external bind : file_descr -> sockaddr -> unit = "unix_bind"
 external connect : file_descr -> sockaddr -> unit = "unix_connect"
 external listen : file_descr -> int -> unit = "unix_listen"
-external shutdown : file_descr -> shutdown_command -> unit = "unix_shutdown" 
+external shutdown : file_descr -> shutdown_command -> unit = "unix_shutdown"
 external getsockname : file_descr -> sockaddr = "unix_getsockname"
 external getpeername : file_descr -> sockaddr = "unix_getpeername"

@@ -519,7 +521,7 @@
   let optint = 2
   let float = 3
   let error = 4
-  external get: ('opt, 'v) t -> file_descr -> 'opt -> 'v 
+  external get: ('opt, 'v) t -> file_descr -> 'opt -> 'v
               = "unix_getsockopt"
   external set: ('opt, 'v) t -> file_descr -> 'opt -> 'v -> unit
               = "unix_setsockopt"
@@ -606,7 +608,7 @@
       with Failure _ ->
       try
         [ty, (getservbyname service kind).s_port]
-      with Not_found -> [] 
+      with Not_found -> []
   in
   let ports =
     match !opt_socktype with
@@ -637,7 +639,7 @@
         [] in
   (* Cross-product of addresses and ports *)
   List.flatten
-    (List.map 
+    (List.map
       (fun (ty, port) ->
         List.map
           (fun (addr, name) ->
@@ -893,7 +895,7 @@
     raise(Unix_error(EBADF, fun_name, ""))

 let rec waitpid_non_intr pid =
-  try waitpid [] pid 
+  try waitpid [] pid
   with Unix_error (EINTR, _, _) -> waitpid_non_intr pid

 let close_process_in inchan =
@@ -963,4 +965,3 @@
             exit 0
     | id -> close s; ignore(waitpid_non_intr id) (* Reclaim the son *)
   done
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/unix.mli ocaml-unix-3.12.1/otherlibs/unix/unix.mli
--- ocaml-unix-3.11.2/otherlibs/unix/unix.mli   2009-03-28 17:58:56.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/unix/unix.mli   2011-03-06 17:17:09.000000000 +0100
@@ -11,7 +11,7 @@
 (*                                                                     *)
 (***********************************************************************)

-(* $Id: unix.mli 9200 2009-03-28 16:58:56Z xleroy $ *)
+(* $Id: unix.mli 10972 2011-03-06 16:17:09Z weis $ *)

 (** Interface to the Unix system *)

@@ -338,7 +338,7 @@
     st_mtime : float;           (** Last modification time *)
     st_ctime : float;           (** Last status change time *)
   }
-(** The informations returned by the {!Unix.stat} calls. *)
+(** The information returned by the {!Unix.stat} calls. *)

 val stat : string -> stats
 (** Return the information for the named file. *)
@@ -820,6 +820,16 @@
 (** Return the list of groups to which the user executing the process
    belongs. *)

+val setgroups : int array -> unit
+  (** [setgroups groups] sets the supplementary group IDs for the
+      calling process. Appropriate privileges are required. *)
+
+val initgroups : string -> int -> unit
+  (** [initgroups user group] initializes the group access list by
+      reading the group database /etc/group and using all groups of
+      which [user] is a member. The additional group [group] is also
+      added to the list. *)
+
 type passwd_entry =
   { pw_name : string;
     pw_passwd : string;
@@ -901,7 +911,7 @@
   | PF_INET                     (** Internet domain (IPv4) *)
   | PF_INET6                    (** Internet domain (IPv6) *)
 (** The type of socket domains.  Not all platforms support
-    IPv6 sockets (type [PF_INET6]).  *)
+    IPv6 sockets (type [PF_INET6]). *)

 type socket_type =
     SOCK_STREAM                 (** Stream socket *)
@@ -911,7 +921,9 @@
 (** The type of socket kinds, specifying the semantics of
    communications. *)

-type sockaddr = ADDR_UNIX of string | ADDR_INET of inet_addr * int
+type sockaddr =
+    ADDR_UNIX of string
+  | ADDR_INET of inet_addr * int
 (** The type of socket addresses. [ADDR_UNIX name] is a socket
    address in the Unix domain; [name] is a file name in the file
    system. [ADDR_INET(addr,port)] is a socket address in the Internet
@@ -1260,7 +1272,7 @@
    file descriptor. *)

 type setattr_when =
-  TCSANOW
+    TCSANOW
   | TCSADRAIN
   | TCSAFLUSH

diff -Naur ocaml-unix-3.11.2/otherlibs/unix/unixsupport.c ocaml-unix-3.12.1/otherlibs/unix/unixsupport.c
--- ocaml-unix-3.11.2/otherlibs/unix/unixsupport.c      2005-09-06 14:38:32.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/unixsupport.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: unixsupport.c 7045 2005-09-06 12:38:32Z doligez $ */
+/* $Id: unixsupport.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -252,7 +252,7 @@
   int errconstr;
   value err;

-  errconstr = 
+  errconstr =
       cst_to_constr(errcode, error_table, sizeof(error_table)/sizeof(int), -1);
   if (errconstr == Val_int(-1)) {
     err = alloc_small(1, 0);
@@ -290,4 +290,3 @@
 {
   unix_error(errno, cmdname, cmdarg);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/unix/write.c ocaml-unix-3.12.1/otherlibs/unix/write.c
--- ocaml-unix-3.11.2/otherlibs/unix/write.c    2004-07-13 14:25:21.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/unix/write.c    2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: write.c 6553 2004-07-13 12:25:21Z xleroy $ */
+/* $Id: write.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <errno.h>
 #include <string.h>
@@ -63,7 +63,7 @@
    This problem is avoided in unix_single_write, which is faithful to the
    Unix system call. */

-CAMLprim value unix_single_write(value fd, value buf, value vofs, value vlen) 
+CAMLprim value unix_single_write(value fd, value buf, value vofs, value vlen)
 {
   long ofs, len;
   int numbytes, ret;
@@ -84,4 +84,3 @@
   End_roots();
   return Val_int(ret);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/accept.c ocaml-unix-3.12.1/otherlibs/win32unix/accept.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/accept.c      2006-10-18 10:26:54.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/accept.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: accept.c 7697 2006-10-18 08:26:54Z xleroy $ */
+/* $Id: accept.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -37,7 +37,7 @@
   if (retcode == 0) {
     /* Set sockets to synchronous mode */
     newvalue = SO_SYNCHRONOUS_NONALERT;
-    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, 
+    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
                (char *) &newvalue, sizeof(newvalue));
   }
   addr_len = sizeof(sock_addr);
@@ -47,7 +47,7 @@
   leave_blocking_section();
   if (retcode == 0) {
     /* Restore initial mode */
-    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, 
+    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
                (char *) &oldvalue, oldvaluelen);
   }
   if (snew == INVALID_SOCKET) {
@@ -63,4 +63,3 @@
   End_roots();
   return res;
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/bind.c ocaml-unix-3.12.1/otherlibs/win32unix/bind.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/bind.c        2002-04-30 17:00:48.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/bind.c        2010-01-22 13:48:24.000000000 +0100
@@ -11,12 +11,12 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: bind.c 4765 2002-04-30 15:00:48Z xleroy $ */
+/* $Id: bind.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include "unixsupport.h"
 #include "socketaddr.h"
-  
+
 CAMLprim value unix_bind(socket, address)
      value socket, address;
 {
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/channels.c ocaml-unix-3.12.1/otherlibs/win32unix/channels.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/channels.c    2009-12-07 11:39:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/channels.c    2011-05-09 13:38:43.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: channels.c 9450 2009-12-07 10:39:54Z xleroy $ */
+/* $Id: channels.c 11030 2011-05-09 11:38:43Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -30,6 +30,7 @@
   } else {
     int fd = _open_osfhandle((long) Handle_val(handle), O_BINARY);
     if (fd == -1) uerror("channel_of_descr", Nothing);
+    CRT_fd_val(handle) = fd;
     return fd;
   }
 }
@@ -44,7 +45,7 @@
   if (Descr_kind_val(handle) == KIND_SOCKET)
     chan->flags |= CHANNEL_FLAG_FROM_SOCKET;
   vchan = caml_alloc_channel(chan);
-  CAMLreturn(vchan); 
+  CAMLreturn(vchan);
 }

 CAMLprim value win_outchannel_of_filedescr(value handle)
@@ -58,7 +59,7 @@
   if (Descr_kind_val(handle) == KIND_SOCKET)
     chan->flags |= CHANNEL_FLAG_FROM_SOCKET;
   vchan = caml_alloc_channel(chan);
-  CAMLreturn(vchan); 
+  CAMLreturn(vchan);
 }

 CAMLprim value win_filedescr_of_channel(value vchan)
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/close.c ocaml-unix-3.12.1/otherlibs/win32unix/close.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/close.c       2002-04-30 17:00:48.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/close.c       2011-05-09 13:38:43.000000000 +0200
@@ -11,10 +11,13 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: close.c 4765 2002-04-30 15:00:48Z xleroy $ */
+/* $Id: close.c 11030 2011-05-09 11:38:43Z doligez $ */

 #include <mlvalues.h>
 #include "unixsupport.h"
+#include <io.h>
+
+extern int _close(int);

 CAMLprim value unix_close(value fd)
 {
@@ -24,9 +27,17 @@
       uerror("close", Nothing);
     }
   } else {
-    if (! CloseHandle(Handle_val(fd))) {
-      win32_maperr(GetLastError());
-      uerror("close", Nothing);
+    /* If we have an fd then closing it also closes
+     * the underlying handle. Also, closing only
+     * the handle and not the fd leads to fd leaks. */
+    if (CRT_fd_val(fd) != NO_CRT_FD) {
+      if (_close(CRT_fd_val(fd)) != 0)
+         uerror("close", Nothing);
+    } else {
+      if (! CloseHandle(Handle_val(fd))) {
+        win32_maperr(GetLastError());
+        uerror("close", Nothing);
+      }
     }
   }
   return Val_unit;
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/createprocess.c ocaml-unix-3.12.1/otherlibs/win32unix/createprocess.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/createprocess.c       2009-06-02 15:12:53.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/createprocess.c       2009-07-20 13:51:50.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: createprocess.c 9284 2009-06-02 13:12:53Z xleroy $ */
+/* $Id: createprocess.c 9319 2009-07-20 11:51:50Z doligez $ */

 #include <windows.h>
 #include <mlvalues.h>
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/.depend ocaml-unix-3.12.1/otherlibs/win32unix/.depend
--- ocaml-unix-3.11.2/otherlibs/win32unix/.depend       2001-09-13 11:08:12.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/.depend       2010-01-22 13:48:24.000000000 +0100
@@ -1,5 +1,5 @@
-unix.cmo: unix.cmi 
-unix.cmx: unix.cmi 
-unixLabels.cmo: unix.cmi unixLabels.cmi 
-unixLabels.cmx: unix.cmx unixLabels.cmi 
-unixLabels.cmi: unix.cmi 
+unix.cmo: unix.cmi
+unix.cmx: unix.cmi
+unixLabels.cmo: unix.cmi unixLabels.cmi
+unixLabels.cmx: unix.cmx unixLabels.cmi
+unixLabels.cmi: unix.cmi
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/dllunix.dlib ocaml-unix-3.12.1/otherlibs/win32unix/dllunix.dlib
--- ocaml-unix-3.11.2/otherlibs/win32unix/dllunix.dlib  2008-07-29 10:31:41.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/dllunix.dlib  1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-# Files in this directory
-accept.d.o bind.d.o channels.d.o close.d.o
-close_on.d.o connect.d.o createprocess.d.o dup.d.o dup2.d.o errmsg.d.o
-getpeername.d.o getpid.d.o getsockname.d.o gettimeofday.d.o
-link.d.o listen.d.o lockf.d.o lseek.d.o nonblock.d.o
-mkdir.d.o open.d.o pipe.d.o read.d.o rename.d.o
-select.d.o sendrecv.d.o
-shutdown.d.o sleep.d.o socket.d.o sockopt.d.o startup.d.o stat.d.o
-system.d.o unixsupport.d.o windir.d.o winwait.d.o write.d.o
-winlist.d.o winworker.d.o windbug.d.o
-
-# Files from the ../unix directory
-access.d.o addrofstr.d.o chdir.d.o chmod.d.o cst2constr.d.o
-cstringv.d.o envir.d.o execv.d.o execve.d.o execvp.d.o
-exit.d.o getcwd.d.o gethost.d.o gethostname.d.o getproto.d.o
-getserv.d.o gmtime.d.o putenv.d.o rmdir.d.o
-socketaddr.d.o strofaddr.d.o time.d.o unlink.d.o utimes.d.o
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/dup.c ocaml-unix-3.12.1/otherlibs/win32unix/dup.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/dup.c 2002-04-30 17:00:48.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/dup.c 2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: dup.c 4765 2002-04-30 15:00:48Z xleroy $ */
+/* $Id: dup.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include "unixsupport.h"
@@ -31,4 +31,3 @@
   Descr_kind_val(newfd) = kind;
   return newfd;
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/errmsg.c ocaml-unix-3.12.1/otherlibs/win32unix/errmsg.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/errmsg.c      2003-12-31 01:00:57.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/errmsg.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: errmsg.c 6043 2003-12-31 00:00:57Z doligez $ */
+/* $Id: errmsg.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <stdio.h>
 #include <errno.h>
@@ -26,7 +26,7 @@
 {
   int errnum;
   char buffer[512];
-  
+
   errnum = Is_block(err) ? Int_val(Field(err, 0)) : error_table[Int_val(err)];
   if (errnum > 0)
     return copy_string(strerror(errnum));
@@ -38,7 +38,6 @@
                     sizeof(buffer),
                     NULL))
     return copy_string(buffer);
-  sprintf(buffer, "unknown error #%d", errnum);  
+  sprintf(buffer, "unknown error #%d", errnum);
   return copy_string(buffer);
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/gettimeofday.c ocaml-unix-3.12.1/otherlibs/win32unix/gettimeofday.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/gettimeofday.c        2007-03-01 14:51:24.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/gettimeofday.c        2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: gettimeofday.c 7946 2007-03-01 13:51:24Z xleroy $ */
+/* $Id: gettimeofday.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -31,6 +31,6 @@
     return copy_double((double) initial_time);
   } else {
     return copy_double((double) initial_time +
-                      (double) (tickcount - initial_tickcount) * 1e-3);
+                       (double) (tickcount - initial_tickcount) * 1e-3);
   }
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/link.c ocaml-unix-3.12.1/otherlibs/win32unix/link.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/link.c        2001-12-07 14:41:02.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/link.c        2010-01-22 13:48:24.000000000 +0100
@@ -11,24 +11,24 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: link.c 4144 2001-12-07 13:41:02Z xleroy $ */
+/* $Id: link.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <windows.h>
 #include <mlvalues.h>
 #include <fail.h>
 #include "unixsupport.h"
-  
-typedef  
+
+typedef
 BOOL (WINAPI *tCreateHardLink)(
   LPCTSTR lpFileName,
   LPCTSTR lpExistingFileName,
-  LPSECURITY_ATTRIBUTES lpSecurityAttributes  
+  LPSECURITY_ATTRIBUTES lpSecurityAttributes
 );
-  
+
 CAMLprim value unix_link(value path1, value path2)
-{ 
+{
   HMODULE hModKernel32;
-  tCreateHardLink pCreateHardLink; 
+  tCreateHardLink pCreateHardLink;
   hModKernel32 = GetModuleHandle("KERNEL32.DLL");
   pCreateHardLink =
     (tCreateHardLink) GetProcAddress(hModKernel32, "CreateHardLinkA");
@@ -39,4 +39,4 @@
     uerror("link", path2);
   }
   return Val_unit;
-} 
+}
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/lockf.c ocaml-unix-3.12.1/otherlibs/win32unix/lockf.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/lockf.c       2008-10-08 15:05:48.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/lockf.c       2008-12-03 19:09:09.000000000 +0100
@@ -13,7 +13,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: lockf.c 9078 2008-10-08 13:05:48Z xleroy $ */
+/* $Id: lockf.c 9153 2008-12-03 18:09:09Z doligez $ */

 #include <errno.h>
 #include <fcntl.h>
@@ -71,7 +71,7 @@
   }

   h = Handle_val(fd);
-  
+
   l_len = Long_val(span);

   /* No matter what, we need the current position in the file */
@@ -108,19 +108,19 @@
   switch(Int_val(cmd)) {
   case 0: /* F_ULOCK - unlock */
     if (! UnlockFileEx(h, 0,
-                      lock_len.LowPart, lock_len.HighPart, &overlap))
+                       lock_len.LowPart, lock_len.HighPart, &overlap))
       err = GetLastError();
     break;
   case 1: /* F_LOCK - blocking write lock */
     enter_blocking_section();
     if (! LockFileEx(h, LOCKFILE_EXCLUSIVE_LOCK, 0,
-                    lock_len.LowPart, lock_len.HighPart, &overlap))
+                     lock_len.LowPart, lock_len.HighPart, &overlap))
       err = GetLastError();
     leave_blocking_section();
     break;
   case 2: /* F_TLOCK - non-blocking write lock */
     if (! LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0,
-                    lock_len.LowPart, lock_len.HighPart, &overlap))
+                     lock_len.LowPart, lock_len.HighPart, &overlap))
       err = GetLastError();
     break;
   case 3: /* F_TEST - check whether a write lock can be obtained */
@@ -130,7 +130,7 @@
      * it is not clear the nature of the lock test performed
      * by ocaml (unix) currently. */
     if (LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0,
-                  lock_len.LowPart, lock_len.HighPart, &overlap)) {
+                   lock_len.LowPart, lock_len.HighPart, &overlap)) {
       UnlockFileEx(h, 0, lock_len.LowPart, lock_len.HighPart, &overlap);
     } else {
       err = GetLastError();
@@ -139,13 +139,13 @@
   case 4: /* F_RLOCK - blocking read lock */
     enter_blocking_section();
     if (! LockFileEx(h, 0, 0,
-                    lock_len.LowPart, lock_len.HighPart, &overlap))
+                     lock_len.LowPart, lock_len.HighPart, &overlap))
       err = GetLastError();
     leave_blocking_section();
     break;
   case 5: /* F_TRLOCK - non-blocking read lock */
     if (! LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0,
-                    lock_len.LowPart, lock_len.HighPart, &overlap))
+                     lock_len.LowPart, lock_len.HighPart, &overlap))
       err = GetLastError();
     break;
   default:
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/lseek.c ocaml-unix-3.12.1/otherlibs/win32unix/lseek.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/lseek.c       2005-02-02 16:52:26.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/lseek.c       2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: lseek.c 6774 2005-02-02 15:52:26Z xleroy $ */
+/* $Id: lseek.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <alloc.h>
@@ -52,7 +52,7 @@
   __int64 ret;

   ret = caml_set_file_pointer(Handle_val(fd), Long_val(ofs),
-                             seek_command_table[Int_val(cmd)]);
+                              seek_command_table[Int_val(cmd)]);
   if (ret > Max_long) {
     win32_maperr(ERROR_ARITHMETIC_OVERFLOW);
     uerror("lseek", Nothing);
@@ -65,6 +65,6 @@
   __int64 ret;

   ret = caml_set_file_pointer(Handle_val(fd), Int64_val(ofs),
-                             seek_command_table[Int_val(cmd)]);
+                              seek_command_table[Int_val(cmd)]);
   return copy_int64(ret);
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/Makefile.nt ocaml-unix-3.12.1/otherlibs/win32unix/Makefile.nt
--- ocaml-unix-3.11.2/otherlibs/win32unix/Makefile.nt   2008-07-29 10:31:41.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/Makefile.nt   2010-05-20 11:40:41.000000000 +0200
@@ -11,7 +11,7 @@
 #                                                                       #
 #########################################################################

-# $Id: Makefile.nt 8955 2008-07-29 08:31:41Z xleroy $
+# $Id: Makefile.nt 10442 2010-05-20 09:40:41Z xleroy $

 # Files in this directory
 WIN_FILES = accept.c bind.c channels.c close.c \
@@ -43,7 +43,7 @@
 LDOPTS=-ldopt $(WSOCKLIB)
 EXTRACAMLFLAGS=-nolabels
 EXTRACFLAGS=-I../unix
-HEADERS=unixsupport.h
+HEADERS=unixsupport.h socketaddr.h


 include ../Makefile.nt
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/nonblock.c ocaml-unix-3.12.1/otherlibs/win32unix/nonblock.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/nonblock.c    2003-01-06 17:44:21.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/nonblock.c    2010-05-25 15:01:06.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: nonblock.c 5375 2003-01-06 16:44:21Z xleroy $ */
+/* $Id: nonblock.c 10467 2010-05-25 13:01:06Z xleroy $ */

 #include <mlvalues.h>
 #include <signals.h>
@@ -26,6 +26,7 @@
     win32_maperr(WSAGetLastError());
     uerror("unix_set_nonblock", Nothing);
   }
+  Flags_fd_val(socket) = Flags_fd_val(socket) | FLAGS_FD_IS_BLOCKING;
   return Val_unit;
 }

@@ -38,5 +39,6 @@
     win32_maperr(WSAGetLastError());
     uerror("unix_clear_nonblock", Nothing);
   }
+  Flags_fd_val(socket) = Flags_fd_val(socket) & ~FLAGS_FD_IS_BLOCKING;
   return Val_unit;
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/pipe.c ocaml-unix-3.12.1/otherlibs/win32unix/pipe.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/pipe.c        2009-03-28 16:30:08.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/pipe.c        2009-05-20 13:52:42.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: pipe.c 9196 2009-03-28 15:30:08Z xleroy $ */
+/* $Id: pipe.c 9270 2009-05-20 11:52:42Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/rename.c ocaml-unix-3.12.1/otherlibs/win32unix/rename.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/rename.c      2004-07-13 14:25:21.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/rename.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: rename.c 6553 2004-07-13 12:25:21Z xleroy $ */
+/* $Id: rename.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <stdio.h>
 #include <mlvalues.h>
@@ -31,13 +31,13 @@
   }
   if (supports_MoveFileEx > 0)
     ok = MoveFileEx(String_val(path1), String_val(path2),
-                   MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH |
-                   MOVEFILE_COPY_ALLOWED);
+                    MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH |
+                    MOVEFILE_COPY_ALLOWED);
   else
     ok = MoveFile(String_val(path1), String_val(path2));
   if (! ok) {
     win32_maperr(GetLastError());
     uerror("rename", path1);
-  }     
+  }
   return Val_unit;
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/select.c ocaml-unix-3.12.1/otherlibs/win32unix/select.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/select.c      2008-11-26 14:27:21.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/select.c      2010-05-25 15:01:06.000000000 +0200
@@ -11,14 +11,16 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: select.c 9143 2008-11-26 13:27:21Z xleroy $ */
+/* $Id: select.c 10467 2010-05-25 13:01:06Z xleroy $ */

 #include <mlvalues.h>
 #include <alloc.h>
 #include <memory.h>
+#include <fail.h>
 #include <signals.h>
 #include <winsock2.h>
 #include <windows.h>
+#include <stdio.h>
 #include "unixsupport.h"
 #include "windbug.h"
 #include "winworker.h"
@@ -70,9 +72,7 @@
     hds->nLast++;
   }

-#ifdef DBUG
-  dbug_print("Adding handle %x to set %x", hdl, hds);
-#endif
+  DEBUG_PRINT("Adding handle %x to set %x", hdl, hds);
 }

 BOOL handle_set_mem (LPSELECTHANDLESET hds, HANDLE hdl)
@@ -138,17 +138,18 @@
 typedef struct _SELECTRESULT {
   LIST       lst;
   SELECTMODE EMode;
-  LPVOID     lpOrig;
+  int        lpOrigIdx;
 } SELECTRESULT;

 typedef SELECTRESULT *LPSELECTRESULT;

 /* Data structure for query */
 typedef struct _SELECTQUERY {
-  LIST       lst;
-  SELECTMODE EMode;
-  HANDLE     hFileDescr;
-  LPVOID     lpOrig;
+  LIST         lst;
+  SELECTMODE   EMode;
+  HANDLE       hFileDescr;
+  int          lpOrigIdx;
+  unsigned int uFlagsFd; /* Copy of filedescr->flags_fd */
 } SELECTQUERY;

 typedef SELECTQUERY *LPSELECTQUERY;
@@ -189,13 +190,7 @@
   LPSELECTDATA res;
   DWORD        i;

-  if (!HeapLock(GetProcessHeap()))
-  {
-    win32_maperr(GetLastError());
-    uerror("select", Nothing);
-  }
-  res = (LPSELECTDATA)HeapAlloc(GetProcessHeap(), 0, sizeof(SELECTDATA)); 
-  HeapUnlock(GetProcessHeap());
+  res = (LPSELECTDATA)caml_stat_alloc(sizeof(SELECTDATA)); 

   /* Init common data */
   list_init((LPLIST)res);
@@ -222,9 +217,7 @@
 {
   DWORD i;

-#ifdef DBUG
-  dbug_print("Freeing data of %x", lpSelectData);
-#endif
+  DEBUG_PRINT("Freeing data of %x", lpSelectData);

   /* Free APC related data, if they exists */
   if (lpSelectData->lpWorker != NULL)
@@ -237,17 +230,11 @@
   lpSelectData->nResultsCount = 0;
   lpSelectData->nQueriesCount = 0;

-  if (!HeapLock(GetProcessHeap()))
-  {
-    win32_maperr(GetLastError());
-    uerror("select_data_free", Nothing);
-  };
-  HeapFree(GetProcessHeap(), 0, lpSelectData);
-  HeapUnlock(GetProcessHeap());
+  caml_stat_free(lpSelectData);
 }

 /* Add a result to select data, return zero if something goes wrong. */
-DWORD select_data_result_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, LPVOID lpOrig)
+DWORD select_data_result_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, int lpOrigIdx)
 {
   DWORD res;
   DWORD i;
@@ -257,7 +244,7 @@
   {
     i = lpSelectData->nResultsCount;
     lpSelectData->aResults[i].EMode  = EMode;
-    lpSelectData->aResults[i].lpOrig = lpOrig;
+    lpSelectData->aResults[i].lpOrigIdx = lpOrigIdx;
     lpSelectData->nResultsCount++;
     res = 1;
   }
@@ -266,7 +253,11 @@
 }

 /* Add a query to select data, return zero if something goes wrong */
-DWORD select_data_query_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig)
+DWORD select_data_query_add (LPSELECTDATA lpSelectData, 
+                             SELECTMODE EMode, 
+                             HANDLE hFileDescr, 
+                             int lpOrigIdx,
+                             unsigned int uFlagsFd)
 {
   DWORD res;
   DWORD i;
@@ -277,7 +268,8 @@
     i = lpSelectData->nQueriesCount;
     lpSelectData->aQueries[i].EMode      = EMode;
     lpSelectData->aQueries[i].hFileDescr = hFileDescr;
-    lpSelectData->aQueries[i].lpOrig     = lpOrig;
+    lpSelectData->aQueries[i].lpOrigIdx  = lpOrigIdx;
+    lpSelectData->aQueries[i].uFlagsFd   = uFlagsFd;
     lpSelectData->nQueriesCount++;
     res = 1;
   }
@@ -296,9 +288,7 @@
   res = NULL;

   /* Search for job */
-#ifdef DBUG
-  dbug_print("Searching an available job for type %d", EType);
-#endif
+  DEBUG_PRINT("Searching an available job for type %d", EType);
   res = *lppSelectData;
   while (
       res != NULL
@@ -314,9 +304,7 @@
   /* No matching job found, create one */
   if (res == NULL)
   {
-#ifdef DBUG
-    dbug_print("No job for type %d found, create one", EType);
-#endif
+    DEBUG_PRINT("No job for type %d found, create one", EType);
     res = select_data_new(*lppSelectData, EType);
     *lppSelectData = res;
   }
@@ -337,9 +325,7 @@
   LPSELECTDATA  lpSelectData;
   LPSELECTQUERY lpQuery;

-#ifdef DBUG
-  dbug_print("Waiting for data on console");
-#endif
+  DEBUG_PRINT("Waiting for data on console");

   record;
   waitRes = 0;
@@ -367,7 +353,7 @@
       record.Event.KeyEvent.bKeyDown &&
       record.Event.KeyEvent.uChar.AsciiChar != 0)
     {
-      select_data_result_add(lpSelectData, lpQuery->EMode, lpQuery->lpOrig);
+      select_data_result_add(lpSelectData, lpQuery->EMode, lpQuery->lpOrigIdx);
       lpSelectData->EState = SELECT_STATE_SIGNALED;
       break;
     }
@@ -383,13 +369,17 @@
 }

 /* Add a function to monitor console input */
-LPSELECTDATA read_console_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig)
+LPSELECTDATA read_console_poll_add (LPSELECTDATA lpSelectData, 
+                                    SELECTMODE EMode, 
+                                    HANDLE hFileDescr, 
+                                    int lpOrigIdx,
+                                    unsigned int uFlagsFd)
 {
   LPSELECTDATA res;

   res = select_data_new(lpSelectData, SELECT_TYPE_CONSOLE_READ);
   res->funcWorker = read_console_poll;
-  select_data_query_add(res, SELECT_MODE_READ, hFileDescr, lpOrig);
+  select_data_query_add(res, SELECT_MODE_READ, hFileDescr, lpOrigIdx, uFlagsFd);

   return res;
 }
@@ -401,42 +391,44 @@
 /* Monitor a pipe for input */
 void read_pipe_poll (HANDLE hStop, void *_data)
 {
+  DWORD         res;
   DWORD         event;
   DWORD         n;
   LPSELECTQUERY iterQuery;
   LPSELECTDATA  lpSelectData;
   DWORD         i;
+  DWORD         wait;

   /* Poll pipe */
   event = 0;
   n = 0;
   lpSelectData = (LPSELECTDATA)_data;
+  wait = 1;

-#ifdef DBUG
-  dbug_print("Checking data pipe");
-#endif
+  DEBUG_PRINT("Checking data pipe");
   while (lpSelectData->EState == SELECT_STATE_NONE)
   {
     for (i = 0; i < lpSelectData->nQueriesCount; i++)
     {
       iterQuery = &(lpSelectData->aQueries[i]);
-      if (check_error(
-            lpSelectData, 
-            PeekNamedPipe(
-              iterQuery->hFileDescr, 
-              NULL, 
-              0, 
-              NULL, 
-              &n, 
-              NULL) == 0))
+      res = PeekNamedPipe(
+          iterQuery->hFileDescr, 
+          NULL, 
+          0, 
+          NULL, 
+          &n, 
+          NULL);
+      if (check_error(lpSelectData, 
+            (res == 0) && 
+            (GetLastError() != ERROR_BROKEN_PIPE)))
       {
         break;
       };

-      if (n > 0)
+      if ((n > 0) || (res == 0))
       {
         lpSelectData->EState = SELECT_STATE_SIGNALED;
-        select_data_result_add(lpSelectData, iterQuery->EMode, iterQuery->lpOrig);
+        select_data_result_add(lpSelectData, iterQuery->EMode, iterQuery->lpOrigIdx);
       };
     };

@@ -445,20 +437,32 @@
      */
     if (lpSelectData->EState == SELECT_STATE_NONE)
     {
-      event = WaitForSingleObject(hStop, 10);
+      event = WaitForSingleObject(hStop, wait);
+
+      /* Fast start: begin to wait 1, 2, 4, 8 and then 10 ms.
+       * If we are working with the output of a program there is
+       * a chance that one of the 4 first calls succeed.
+       */
+      wait = 2 * wait;
+      if (wait > 10) 
+      {
+        wait = 10;
+      };
       if (event == WAIT_OBJECT_0 || check_error(lpSelectData, event == WAIT_FAILED))
       {
         break;
       }
     }
   }
-#ifdef DBUG
-  dbug_print("Finish checking data on pipe");
-#endif
+  DEBUG_PRINT("Finish checking data on pipe");
 }

 /* Add a function to monitor pipe input */
-LPSELECTDATA read_pipe_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig)
+LPSELECTDATA read_pipe_poll_add (LPSELECTDATA lpSelectData, 
+                                 SELECTMODE EMode, 
+                                 HANDLE hFileDescr, 
+                                 int lpOrigIdx,
+                                 unsigned int uFlagsFd)
 {
   LPSELECTDATA res;
   LPSELECTDATA hd;
@@ -468,14 +472,12 @@
      worker can handle many pipe. We begin to try to find a worker that is
      polling pipe, but for which there is under the limit of pipe per worker.
      */
-#ifdef DBUG
-  dbug_print("Searching an available worker handling pipe");
-#endif
+  DEBUG_PRINT("Searching an available worker handling pipe");
   res = select_data_job_search(&hd, SELECT_TYPE_PIPE_READ);

   /* Add a new pipe to poll */
   res->funcWorker = read_pipe_poll;
-  select_data_query_add(res, EMode, hFileDescr, lpOrig);
+  select_data_query_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);

   return hd;
 }
@@ -514,6 +516,7 @@
         maskEvents = FD_OOB;
         break;
     }
+
     check_error(lpSelectData,
         WSAEventSelect(
           (SOCKET)(iterQuery->hFileDescr),
@@ -542,20 +545,27 @@
       iterQuery = &(lpSelectData->aQueries[i]);
       if (WaitForSingleObject(aEvents[i], 0) == WAIT_OBJECT_0)
       {
-#ifdef DBUG
-        dbug_print("Socket %d has pending events", (i - 1));
-#endif
+        DEBUG_PRINT("Socket %d has pending events", (i - 1));
         if (iterQuery != NULL)
         {
-          select_data_result_add(lpSelectData, iterQuery->EMode, iterQuery->lpOrig);
+          select_data_result_add(lpSelectData, iterQuery->EMode, iterQuery->lpOrigIdx);
         }
       }
       /* WSAEventSelect() automatically sets socket to nonblocking mode.
          Restore the blocking one. */
-      iMode = 0;
-      check_error(lpSelectData,
-        WSAEventSelect((SOCKET)(iterQuery->hFileDescr), aEvents[i], 0) != 0 ||
-        ioctlsocket((SOCKET)(iterQuery->hFileDescr), FIONBIO, &iMode) != 0);
+      if (iterQuery->uFlagsFd & FLAGS_FD_IS_BLOCKING)
+      {
+        DEBUG_PRINT("Restore a blocking socket");
+        iMode = 1;
+        check_error(lpSelectData,
+          WSAEventSelect((SOCKET)(iterQuery->hFileDescr), aEvents[i], 0) != 0 ||
+          ioctlsocket((SOCKET)(iterQuery->hFileDescr), FIONBIO, &iMode) != 0);
+      }
+      else
+      {
+        check_error(lpSelectData,
+          WSAEventSelect((SOCKET)(iterQuery->hFileDescr), aEvents[i], 0) != 0);
+      };

       CloseHandle(aEvents[i]);
       aEvents[i] = INVALID_HANDLE_VALUE;
@@ -564,7 +574,11 @@
 }

 /* Add a function to monitor socket */
-LPSELECTDATA socket_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig)
+LPSELECTDATA socket_poll_add (LPSELECTDATA lpSelectData, 
+                              SELECTMODE EMode, 
+                              HANDLE hFileDescr, 
+                              int lpOrigIdx,
+                              unsigned int uFlagsFd)
 {
   LPSELECTDATA res;
   LPSELECTDATA hd;
@@ -574,20 +588,14 @@
      need one worker to use it. Try to find if there is already a worker
      handling this kind of request.
      */
-#ifdef DBUG
-  dbug_print("Scanning list of worker to find one that already handle socket");
-#endif
+  DEBUG_PRINT("Scanning list of worker to find one that already handle socket");
   res = select_data_job_search(&hd, SELECT_TYPE_SOCKET);

   /* Add a new socket to poll */
   res->funcWorker = socket_poll;
-#ifdef DBUG
-  dbug_print("Add socket %x to worker", hFileDescr);
-#endif
-  select_data_query_add(res, EMode, hFileDescr, lpOrig);
-#ifdef DBUG
-  dbug_print("Socket %x added", hFileDescr);
-#endif
+  DEBUG_PRINT("Add socket %x to worker", hFileDescr);
+  select_data_query_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
+  DEBUG_PRINT("Socket %x added", hFileDescr);

   return hd;
 }
@@ -597,7 +605,11 @@
 /***********************/

 /* Add a static result */
-LPSELECTDATA static_poll_add (LPSELECTDATA lpSelectData, SELECTMODE EMode, HANDLE hFileDescr, LPVOID lpOrig)
+LPSELECTDATA static_poll_add (LPSELECTDATA lpSelectData, 
+                              SELECTMODE EMode, 
+                              HANDLE hFileDescr, 
+                              int lpOrigIdx,
+                              unsigned int uFlagsFd)
 {
   LPSELECTDATA res;
   LPSELECTDATA hd;
@@ -607,8 +619,8 @@
   res = select_data_job_search(&hd, SELECT_TYPE_STATIC);

   /* Add a new query/result */
-  select_data_query_add(res, EMode, hFileDescr, lpOrig);
-  select_data_result_add(res, EMode, lpOrig);
+  select_data_query_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
+  select_data_result_add(res, EMode, lpOrigIdx);

   return hd;
 }
@@ -661,30 +673,26 @@
 }

 /* Choose what to do with given data */
-LPSELECTDATA select_data_dispatch (LPSELECTDATA lpSelectData, SELECTMODE EMode, value fd)
+LPSELECTDATA select_data_dispatch (LPSELECTDATA lpSelectData, SELECTMODE EMode, value fd, int lpOrigIdx)
 {
   LPSELECTDATA    res;
   HANDLE          hFileDescr;
-  void           *lpOrig;
   struct sockaddr sa;
   int             sa_len;
   BOOL            alreadyAdded;
+  unsigned int    uFlagsFd;

   CAMLparam1(fd);

   res          = lpSelectData;
   hFileDescr   = Handle_val(fd);
-  lpOrig       = (void *)fd;
   sa_len       = sizeof(sa);
   alreadyAdded = FALSE;
+  uFlagsFd     = Flags_fd_val(fd);
+
+  DEBUG_PRINT("Begin dispatching handle %x", hFileDescr);

-#ifdef DBUG
-  dbug_print("Begin dispatching handle %x", hFileDescr);
-#endif
-
-#ifdef DBUG
-  dbug_print("Waiting for %d on handle %x", EMode, hFileDescr);
-#endif
+  DEBUG_PRINT("Waiting for %d on handle %x", EMode, hFileDescr);

   /* There is only 2 way to have except mode: transmission of OOB data through
      a socket TCP/IP and through a strange interaction with a TTY.
@@ -693,88 +701,71 @@
   switch(get_handle_type(fd))
   {
     case SELECT_HANDLE_DISK:
-#ifdef DBUG
-      dbug_print("Handle %x is a disk handle", hFileDescr);
-#endif
+      DEBUG_PRINT("Handle %x is a disk handle", hFileDescr);
       /* Disk is always ready in read/write operation */
       if (EMode == SELECT_MODE_READ || EMode == SELECT_MODE_WRITE)
       {
-        res = static_poll_add(res, EMode, hFileDescr, lpOrig);
+        res = static_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       };
       break;

     case SELECT_HANDLE_CONSOLE:
-#ifdef DBUG
-      dbug_print("Handle %x is a console handle", hFileDescr);
-#endif
+      DEBUG_PRINT("Handle %x is a console handle", hFileDescr);
       /* Console is always ready in write operation, need to check for read. */
       if (EMode == SELECT_MODE_READ)
       {
-        res = read_console_poll_add(res, EMode, hFileDescr, lpOrig);
+        res = read_console_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       }
       else if (EMode == SELECT_MODE_WRITE)
       {
-        res = static_poll_add(res, EMode, hFileDescr, lpOrig);
+        res = static_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       };
       break;

     case SELECT_HANDLE_PIPE:
-#ifdef DBUG
-      dbug_print("Handle %x is a pipe handle", hFileDescr);
-#endif
+      DEBUG_PRINT("Handle %x is a pipe handle", hFileDescr);
       /* Console is always ready in write operation, need to check for read. */
       if (EMode == SELECT_MODE_READ)
       {
-#ifdef DBUG
-        dbug_print("Need to check availability of data on pipe");
-#endif
-        res = read_pipe_poll_add(res, EMode, hFileDescr, lpOrig);
+        DEBUG_PRINT("Need to check availability of data on pipe");
+        res = read_pipe_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       }
       else if (EMode == SELECT_MODE_WRITE)
       {
-#ifdef DBUG
-        dbug_print("No need to check availability of data on pipe, write operation always possible");
-#endif
-        res = static_poll_add(res, EMode, hFileDescr, lpOrig);
+        DEBUG_PRINT("No need to check availability of data on pipe, write operation always possible");
+        res = static_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       };
       break;

     case SELECT_HANDLE_SOCKET:
-#ifdef DBUG
-      dbug_print("Handle %x is a socket handle", hFileDescr);
-#endif
+      DEBUG_PRINT("Handle %x is a socket handle", hFileDescr);
       if (getsockname((SOCKET)hFileDescr, &sa, &sa_len) == SOCKET_ERROR)
       {
         if (WSAGetLastError() == WSAEINVAL)
         {
           /* Socket is not bound */
-#ifdef DBUG
-          dbug_print("Socket is not connected");
-#endif
+          DEBUG_PRINT("Socket is not connected");
           if (EMode == SELECT_MODE_WRITE || EMode == SELECT_MODE_READ)
           {
-            res = static_poll_add(res, EMode, hFileDescr, lpOrig);
+            res = static_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
             alreadyAdded = TRUE;
           }
         }
       }
       if (!alreadyAdded)
       {
-        res = socket_poll_add(res, EMode, hFileDescr, lpOrig);
+        res = socket_poll_add(res, EMode, hFileDescr, lpOrigIdx, uFlagsFd);
       }
       break;

     default:
-#ifdef DBUG
-      dbug_print("Handle %x is unknown", hFileDescr);
-#endif
-      caml_failwith("Unknown handle");
+      DEBUG_PRINT("Handle %x is unknown", hFileDescr);
+      win32_maperr(ERROR_INVALID_HANDLE);
+      uerror("select", Nothing);
       break;
   };

-#ifdef DBUG
-  dbug_print("Finish dispatching handle %x", hFileDescr);
-#endif
+  DEBUG_PRINT("Finish dispatching handle %x", hFileDescr);

   CAMLreturnT(LPSELECTDATA, res);
 }
@@ -792,6 +783,38 @@
   CAMLreturnT(DWORD, res);
 }

+static value find_handle(LPSELECTRESULT iterResult, value readfds, value writefds, value exceptfds)
+{
+  CAMLparam3(readfds, writefds, exceptfds);
+  CAMLlocal2(result, list);
+  int i;
+
+  switch( iterResult->EMode )  
+  {
+    case SELECT_MODE_READ:
+      list = readfds;
+      break;
+    case SELECT_MODE_WRITE:
+      list = writefds;
+      break;
+    case SELECT_MODE_EXCEPT:
+      list = exceptfds;
+      break;
+  };
+
+  for(i=0; list != Val_unit && i < iterResult->lpOrigIdx; ++i ) 
+  {
+    list = Field(list, 1);
+  }
+
+  if (list == Val_unit) 
+    failwith ("select.c: original file handle not found");
+
+  result = Field(list, 0);
+
+  CAMLreturn( result );
+}
+
 #define MAX(a, b) ((a) > (b) ? (a) : (b))

 CAMLprim value unix_select(value readfds, value writefds, value exceptfds, value timeout)
@@ -837,9 +860,7 @@
   CAMLlocal5 (read_list, write_list, except_list, res, l);
   CAMLlocal1 (fd);

-#ifdef DBUG
-  dbug_print("in select");
-#endif
+  DEBUG_PRINT("in select");

   nEventsCount   = 0;
   nEventsMax     = 0;
@@ -855,23 +876,12 @@
   exceptfds_len  = caml_list_length(exceptfds);
   hdsMax         = MAX(readfds_len, MAX(writefds_len, exceptfds_len));

-  if (!HeapLock(GetProcessHeap()))
-  {
-    win32_maperr(GetLastError());
-    uerror("select", Nothing);
-  }
-  hdsData = (HANDLE *)HeapAlloc(
-      GetProcessHeap(), 
-      0, 
-      sizeof(HANDLE) * hdsMax);
-  HeapUnlock(GetProcessHeap());
+  hdsData = (HANDLE *)caml_stat_alloc(sizeof(HANDLE) * hdsMax);

   if (Double_val(timeout) >= 0.0)
   {
     milliseconds = 1000 * Double_val(timeout);
-#ifdef DBUG
-    dbug_print("Will wait %d ms", milliseconds);
-#endif
+    DEBUG_PRINT("Will wait %d ms", milliseconds);
   }
   else
   {
@@ -880,82 +890,65 @@


   /* Create list of select data, based on the different list of fd to watch */
-#ifdef DBUG
-  dbug_print("Dispatch read fd");
-#endif
+  DEBUG_PRINT("Dispatch read fd");
   handle_set_init(&hds, hdsData, hdsMax);
+  i=0;
   for (l = readfds; l != Val_int(0); l = Field(l, 1))
   {
     fd = Field(l, 0);
     if (!handle_set_mem(&hds, Handle_val(fd)))
     {
       handle_set_add(&hds, Handle_val(fd));
-      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_READ, fd);
+      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_READ, fd, i++);
     }
     else
     {
-#ifdef DBUG
-      dbug_print("Discarding handle %x which is already monitor for read", Handle_val(fd));
-#endif
+      DEBUG_PRINT("Discarding handle %x which is already monitor for read", Handle_val(fd));
     }
   }
   handle_set_reset(&hds);

-#ifdef DBUG
-  dbug_print("Dispatch write fd");
-#endif
+  DEBUG_PRINT("Dispatch write fd");
   handle_set_init(&hds, hdsData, hdsMax);
+  i=0;
   for (l = writefds; l != Val_int(0); l = Field(l, 1))
   {
     fd = Field(l, 0);
     if (!handle_set_mem(&hds, Handle_val(fd)))
     {
       handle_set_add(&hds, Handle_val(fd));
-      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_WRITE, fd);
+      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_WRITE, fd, i++);
     }
     else
     {
-#ifdef DBUG
-      dbug_print("Discarding handle %x which is already monitor for write", Handle_val(fd));
-#endif
+      DEBUG_PRINT("Discarding handle %x which is already monitor for write", Handle_val(fd));
     }
   }
   handle_set_reset(&hds);

-#ifdef DBUG
-  dbug_print("Dispatch exceptional fd");
-#endif
+  DEBUG_PRINT("Dispatch exceptional fd");
   handle_set_init(&hds, hdsData, hdsMax);
+  i=0;
   for (l = exceptfds; l != Val_int(0); l = Field(l, 1))
   {
     fd = Field(l, 0);
     if (!handle_set_mem(&hds, Handle_val(fd)))
     {
       handle_set_add(&hds, Handle_val(fd));
-      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_EXCEPT, fd);
+      lpSelectData = select_data_dispatch(lpSelectData, SELECT_MODE_EXCEPT, fd, i++);
     }
     else
     {
-#ifdef DBUG
-      dbug_print("Discarding handle %x which is already monitor for exceptional", Handle_val(fd));
-#endif
+      DEBUG_PRINT("Discarding handle %x which is already monitor for exceptional", Handle_val(fd));
     }
   }
   handle_set_reset(&hds);

   /* Building the list of handle to wait for */
-#ifdef DBUG
-  dbug_print("Building events done array");
-#endif
+  DEBUG_PRINT("Building events done array");
   nEventsMax   = list_length((LPLIST)lpSelectData);
   nEventsCount = 0;
-  if (!HeapLock(GetProcessHeap()))
-  {
-    win32_maperr(GetLastError());
-    uerror("select", Nothing);
-  }
-  lpEventsDone = (HANDLE *)HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLE) * nEventsMax);
-  HeapUnlock(GetProcessHeap());
+  lpEventsDone = (HANDLE *)caml_stat_alloc(sizeof(HANDLE) * nEventsMax);

   iterSelectData = lpSelectData;
   while (iterSelectData != NULL)
@@ -977,18 +970,14 @@
         worker_job_submit(
             iterSelectData->funcWorker,
             (void *)iterSelectData);
-#ifdef DBUG
-      dbug_print("Job submitted to worker %x", iterSelectData->lpWorker); 
-#endif
+      DEBUG_PRINT("Job submitted to worker %x", iterSelectData->lpWorker); 
       lpEventsDone[nEventsCount] = worker_job_event_done(iterSelectData->lpWorker);
       nEventsCount++;
     };
     iterSelectData = LIST_NEXT(LPSELECTDATA, iterSelectData);
   };

-#ifdef DBUG
-  dbug_print("Need to watch %d workers", nEventsCount);
-#endif
+  DEBUG_PRINT("Need to watch %d workers", nEventsCount);

   /* Processing select itself */
   enter_blocking_section();
@@ -998,9 +987,7 @@
     /* Waiting for event */
     if (err == 0 && !hasStaticData)
     {
-#ifdef DBUG
-      dbug_print("Waiting for one select worker to be done");
-#endif
+      DEBUG_PRINT("Waiting for one select worker to be done");
       switch (WaitForMultipleObjects(nEventsCount, lpEventsDone, FALSE, milliseconds))
       {
         case WAIT_FAILED:
@@ -1008,23 +995,17 @@
           break;

         case WAIT_TIMEOUT:
-#ifdef DBUG
-          dbug_print("Select timeout");
-#endif
+          DEBUG_PRINT("Select timeout");
           break;

         default:
-#ifdef DBUG
-          dbug_print("One worker is done");
-#endif
+          DEBUG_PRINT("One worker is done");
           break;
       };
     }

     /* Ordering stop to every worker */
-#ifdef DBUG
-    dbug_print("Sending stop signal to every select workers");
-#endif
+    DEBUG_PRINT("Sending stop signal to every select workers");
     iterSelectData = lpSelectData;
     while (iterSelectData != NULL)
     {
@@ -1035,9 +1016,7 @@
       iterSelectData = LIST_NEXT(LPSELECTDATA, iterSelectData);
     };

-#ifdef DBUG
-    dbug_print("Waiting for every select worker to be done");
-#endif
+    DEBUG_PRINT("Waiting for every select worker to be done");
     switch (WaitForMultipleObjects(nEventsCount, lpEventsDone, TRUE, INFINITE))
     {
       case WAIT_FAILED:
@@ -1045,9 +1024,7 @@
         break;

       default:
-#ifdef DBUG
-        dbug_print("Every worker is done");
-#endif
+        DEBUG_PRINT("Every worker is done");
         break;
     }
   }
@@ -1058,15 +1035,11 @@
   }
   leave_blocking_section();

-#ifdef DBUG
-  dbug_print("Error status: %d (0 is ok)", err);
-#endif
+  DEBUG_PRINT("Error status: %d (0 is ok)", err);
   /* Build results */
   if (err == 0)
   {
-#ifdef DBUG
-    dbug_print("Building result");
-#endif
+    DEBUG_PRINT("Building result");
     read_list = Val_unit;
     write_list = Val_unit;
     except_list = Val_unit;
@@ -1078,7 +1051,7 @@
       {
         iterResult = &(iterSelectData->aResults[i]);
         l = alloc_small(2, 0);
-        Store_field(l, 0, (value)iterResult->lpOrig);
+        Store_field(l, 0, find_handle(iterResult, readfds, writefds, exceptfds));
         switch (iterResult->EMode)
         {
         case SELECT_MODE_READ:
@@ -1105,9 +1078,7 @@
   }

   /* Free resources */
-#ifdef DBUG
-  dbug_print("Free selectdata resources");
-#endif
+  DEBUG_PRINT("Free selectdata resources");
   iterSelectData = lpSelectData;
   while (iterSelectData != NULL)
   {
@@ -1118,38 +1089,24 @@
   lpSelectData = NULL;

   /* Free allocated events/handle set array */
-#ifdef DBUG
-  dbug_print("Free local allocated resources");
-#endif
-  if (!HeapLock(GetProcessHeap()))
-  {
-    win32_maperr(GetLastError());
-    uerror("select", Nothing);
-  }
-  HeapFree(GetProcessHeap(), 0, lpEventsDone);
-  HeapFree(GetProcessHeap(), 0, hdsData);
-  HeapUnlock(GetProcessHeap());
-
-#ifdef DBUG
-  dbug_print("Raise error if required");
-#endif
+  DEBUG_PRINT("Free local allocated resources");
+  caml_stat_free(lpEventsDone);
+  caml_stat_free(hdsData);
+
+  DEBUG_PRINT("Raise error if required");
   if (err != 0)
   {
     win32_maperr(err);
     uerror("select", Nothing);
   }

-#ifdef DBUG
-  dbug_print("Build final result");
-#endif
+  DEBUG_PRINT("Build final result");
   res = alloc_small(3, 0);
   Store_field(res, 0, read_list);
   Store_field(res, 1, write_list);
   Store_field(res, 2, except_list);

-#ifdef DBUG
-  dbug_print("out select");
-#endif
+  DEBUG_PRINT("out select");

   CAMLreturn(res);
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/socket.c ocaml-unix-3.12.1/otherlibs/win32unix/socket.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/socket.c      2002-04-30 17:00:48.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/socket.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: socket.c 4765 2002-04-30 15:00:48Z xleroy $ */
+/* $Id: socket.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include "unixsupport.h"
@@ -36,7 +36,7 @@
   if (retcode == 0) {
     /* Set sockets to synchronous mode */
     newvalue = SO_SYNCHRONOUS_NONALERT;
-    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, 
+    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
                (char *) &newvalue, sizeof(newvalue));
   }
   s = socket(socket_domain_table[Int_val(domain)],
@@ -44,7 +44,7 @@
                    Int_val(proto));
   if (retcode == 0) {
     /* Restore initial mode */
-    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, 
+    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
                (char *) &oldvalue, oldvaluelen);
   }
   if (s == INVALID_SOCKET) {
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/startup.c ocaml-unix-3.12.1/otherlibs/win32unix/startup.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/startup.c     2008-07-29 10:31:41.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/startup.c     2010-05-25 15:01:06.000000000 +0200
@@ -28,8 +28,6 @@
   int i;
   HANDLE h;

-  DBUG_INIT;
-
   (void) WSAStartup(MAKEWORD(2, 0), &wsaData);
   DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
                   GetCurrentProcess(), &h, 0, TRUE,
@@ -48,7 +46,5 @@

   (void) WSACleanup();

-  DBUG_CLEANUP;
-
   return Val_unit;
 }
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/stat.c ocaml-unix-3.12.1/otherlibs/win32unix/stat.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/stat.c        2009-03-28 17:39:50.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/stat.c        2009-05-20 13:52:42.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: stat.c 9199 2009-03-28 16:39:50Z xleroy $ */
+/* $Id: stat.c 9270 2009-05-20 11:52:42Z doligez $ */

 #include <errno.h>
 #include <mlvalues.h>
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/system.c ocaml-unix-3.12.1/otherlibs/win32unix/system.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/system.c      2006-09-21 10:03:56.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/system.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: system.c 7626 2006-09-21 08:03:56Z xleroy $ */
+/* $Id: system.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -42,6 +42,3 @@
   Field(st, 0) = Val_int(ret);
   return st;
 }
-
-
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/unix.ml ocaml-unix-3.12.1/otherlibs/win32unix/unix.ml
--- ocaml-unix-3.11.2/otherlibs/win32unix/unix.ml       2008-08-01 15:46:08.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/unix.ml       2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 (*                                                                     *)
 (***********************************************************************)

-(* $Id: unix.ml 8968 2008-08-01 13:46:08Z xleroy $ *)
+(* $Id: unix.ml 9547 2010-01-22 12:48:24Z doligez $ *)

 (* Initialization *)

@@ -145,7 +145,7 @@
 external getpid : unit -> int = "unix_getpid"

 let fork () = invalid_arg "Unix.fork not implemented"
-let wait () = invalid_arg "Unix.wait not implemented" 
+let wait () = invalid_arg "Unix.wait not implemented"
 let getppid () = invalid_arg "Unix.getppid not implemented"
 let nice prio = invalid_arg "Unix.nice not implemented"

@@ -435,6 +435,8 @@
 let setgid id = invalid_arg "Unix.setgid not implemented"

 let getgroups () = [|1|]
+let setgroups _ = invalid_arg "Unix.setgroups not implemented"
+let initgroups _ _ = invalid_arg "Unix.initgroups not implemented"

 type passwd_entry =
   { pw_name : string;
@@ -513,7 +515,7 @@
 external bind : file_descr -> sockaddr -> unit = "unix_bind"
 external connect : file_descr -> sockaddr -> unit = "unix_connect"
 external listen : file_descr -> int -> unit = "unix_listen"
-external shutdown : file_descr -> shutdown_command -> unit = "unix_shutdown" 
+external shutdown : file_descr -> shutdown_command -> unit = "unix_shutdown"
 external getsockname : file_descr -> sockaddr = "unix_getsockname"
 external getpeername : file_descr -> sockaddr = "unix_getpeername"

@@ -590,7 +592,7 @@
   let optint = 2
   let float = 3
   let error = 4
-  external get: ('opt, 'v) t -> file_descr -> 'opt -> 'v 
+  external get: ('opt, 'v) t -> file_descr -> 'opt -> 'v
               = "unix_getsockopt"
   external set: ('opt, 'v) t -> file_descr -> 'opt -> 'v -> unit
               = "unix_setsockopt"
@@ -676,7 +678,7 @@
       with Failure _ ->
       try
         [ty, (getservbyname service kind).s_port]
-      with Not_found -> [] 
+      with Not_found -> []
   in
   let ports =
     match !opt_socktype with
@@ -707,7 +709,7 @@
         [] in
   (* Cross-product of addresses and ports *)
   List.flatten
-    (List.map 
+    (List.map
       (fun (ty, port) ->
         List.map
           (fun (addr, name) ->
@@ -770,7 +772,7 @@
 let create_process_env prog args env fd1 fd2 fd3 =
   win_create_process prog (make_cmdline args)
                      (Some(String.concat "\000" (Array.to_list env) ^ "\000"))
-                     fd1 fd2 fd3 
+                     fd1 fd2 fd3

 external system: string -> process_status = "win_system"

diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/unixsupport.c ocaml-unix-3.12.1/otherlibs/win32unix/unixsupport.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/unixsupport.c 2009-12-07 11:39:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/unixsupport.c 2010-05-25 15:01:06.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: unixsupport.c 9450 2009-12-07 10:39:54Z xleroy $ */
+/* $Id: unixsupport.c 10467 2010-05-25 13:01:06Z xleroy $ */

 #include <stddef.h>
 #include <mlvalues.h>
@@ -53,6 +53,7 @@
   Handle_val(res) = h;
   Descr_kind_val(res) = KIND_HANDLE;
   CRT_fd_val(res) = NO_CRT_FD;
+  Flags_fd_val(res) = 0;
   return res;
 }

@@ -62,6 +63,7 @@
   Socket_val(res) = s;
   Descr_kind_val(res) = KIND_SOCKET;
   CRT_fd_val(res) = NO_CRT_FD;
+  Flags_fd_val(res) = 0;
   return res;
 }

diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/unixsupport.h ocaml-unix-3.12.1/otherlibs/win32unix/unixsupport.h
--- ocaml-unix-3.11.2/otherlibs/win32unix/unixsupport.h 2009-12-07 11:39:54.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/unixsupport.h 2010-05-25 15:01:06.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: unixsupport.h 9450 2009-12-07 10:39:54Z xleroy $ */
+/* $Id: unixsupport.h 10467 2010-05-25 13:01:06Z xleroy $ */

 #define WIN32_LEAN_AND_MEAN
 #include <wtypes.h>
@@ -26,15 +26,17 @@
   union {
     HANDLE handle;
     SOCKET socket;
-  } fd;
+  } fd;                   /* Real windows handle */
   enum { KIND_HANDLE, KIND_SOCKET } kind;
-  int crt_fd;
+  int crt_fd;             /* C runtime descriptor */
+  unsigned int flags_fd;  /* See FLAGS_FD_* */
 };

 #define Handle_val(v) (((struct filedescr *) Data_custom_val(v))->fd.handle)
 #define Socket_val(v) (((struct filedescr *) Data_custom_val(v))->fd.socket)
 #define Descr_kind_val(v) (((struct filedescr *) Data_custom_val(v))->kind)
 #define CRT_fd_val(v) (((struct filedescr *) Data_custom_val(v))->crt_fd)
+#define Flags_fd_val(v) (((struct filedescr *) Data_custom_val(v))->flags_fd)

 /* extern value win_alloc_handle_or_socket(HANDLE); */
 extern value win_alloc_handle(HANDLE);
@@ -50,4 +52,11 @@
 extern void uerror (char * cmdname, value arg);
 extern value unix_freeze_buffer (value);

+/* Information stored in flags_fd, describing more precisely the socket
+ * and its status. The whole flags_fd is initialized to 0.
+ */
+
+/* Blocking or nonblocking.  By default a filedescr is in blocking state */
+#define FLAGS_FD_IS_BLOCKING (1<<0)
+
 #define UNIX_BUFFER_SIZE 16384
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/windbug.c ocaml-unix-3.12.1/otherlibs/win32unix/windbug.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/windbug.c     2008-11-26 14:41:01.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/windbug.c     2010-05-25 15:01:06.000000000 +0200
@@ -11,41 +11,22 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: windbug.c 9144 2008-11-26 13:41:01Z xleroy $ */
+/* $Id: windbug.c 10467 2010-05-25 13:01:06Z xleroy $ */

-#include <windows.h>
-#include <stdio.h>
-#include <stdarg.h>
 #include "windbug.h"

-#ifdef DBUG
-
-static int dbug = 0;
-
-void dbug_init (void)
-{
-  dbug = (getenv("OCAMLDBUG") != NULL);
-}
-
-void dbug_cleanup (void)
+int debug_test (void)
 {
-}
+  static int debug_init = 0;
+  static int debug = 0;

-int dbug_test (void)
-{
-  return dbug;
-}
+#ifdef DEBUG
+  if (!debug_init)
+  {
+    debug = (getenv("OCAMLDEBUG") != NULL);
+    debug_init = 1;
+  };
+#endif 

-void dbug_print(const char * fmt, ...)
-{
-  va_list ap;
-  if (dbug) {
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    fprintf(stderr, "\n");
-    fflush(stderr);
-    va_end(ap);
-  }
+  return debug;
 }
-
-#endif
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/windbug.h ocaml-unix-3.12.1/otherlibs/win32unix/windbug.h
--- ocaml-unix-3.11.2/otherlibs/win32unix/windbug.h     2008-11-26 14:27:21.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/windbug.h     2010-05-25 15:01:06.000000000 +0200
@@ -11,27 +11,28 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: windbug.h 9143 2008-11-26 13:27:21Z xleroy $ */
+/* $Id: windbug.h 10467 2010-05-25 13:01:06Z xleroy $ */

-/*#define DBUG*/
+#ifdef DEBUG

-#ifdef DBUG
+#include <stdio.h>
+#include <windows.h>

-/* Initialize and cleanup dbug variable */
-void dbug_init    (void);
-void dbug_cleanup (void);
+#define DEBUG_PRINT(fmt, ...) \
+  do \
+  { \
+    if (debug_test()) \
+    { \
+      fprintf(stderr, "DBUG (pid:%d, tid: %d): ", GetCurrentProcessId(), GetCurrentThreadId()); \
+      fprintf(stderr, fmt, __VA_ARGS__); \
+      fprintf(stderr, "\n"); \
+      fflush(stderr); \
+    }; \
+  } while(0)

 /* Test if we are in dbug mode */
-int  dbug_test    (void);
-
-/* Print if we are in dbug mode */
-void dbug_print (const char * fmt, ...);
-
-#define DBUG_INIT    dbug_init()
-#define DBUG_CLEANUP dbug_cleanup()
+int  debug_test    (void);

 #else
-#define DBUG_INIT
-#define DBUG_CLEANUP
+#define DEBUG_PRINT(fmt, ...)
 #endif
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/windir.c ocaml-unix-3.12.1/otherlibs/win32unix/windir.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/windir.c      2002-07-23 16:12:03.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/windir.c      2010-01-22 13:48:24.000000000 +0100
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: windir.c 5029 2002-07-23 14:12:03Z doligez $ */
+/* $Id: windir.c 9547 2010-01-22 12:48:24Z doligez $ */

 #include <mlvalues.h>
 #include <memory.h>
@@ -77,4 +77,3 @@
   }
   return Val_unit;
 }
-
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/winworker.c ocaml-unix-3.12.1/otherlibs/win32unix/winworker.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/winworker.c   2008-11-26 14:41:01.000000000 +0100
+++ ocaml-unix-3.12.1/otherlibs/win32unix/winworker.c   2010-05-25 15:01:06.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: winworker.c 9144 2008-11-26 13:41:01Z xleroy $ */
+/* $Id: winworker.c 10467 2010-05-25 13:01:06Z xleroy $ */

 #include "winworker.h"
 #include "winlist.h"
@@ -47,30 +47,25 @@
 DWORD    nWorkersCurrent = 0;
 DWORD    nWorkersMax     = 0;
 HANDLE   hWorkersMutex   = INVALID_HANDLE_VALUE;
-HANDLE   hWorkerHeap     = INVALID_HANDLE_VALUE;

 DWORD WINAPI worker_wait (LPVOID _data)
 {
   BOOL     bExit;
   LPWORKER lpWorker;
- 
+
   lpWorker = (LPWORKER )_data;
   bExit    = FALSE;

-#ifdef DBUG
-  dbug_print("Worker %x starting", lpWorker);
-#endif
+  DEBUG_PRINT("Worker %x starting", lpWorker);
   while (
-      !bExit 
+      !bExit
       && SignalObjectAndWait(
-        lpWorker->hWorkerReady, 
+        lpWorker->hWorkerReady,
         lpWorker->hCommandReady,
-        INFINITE, 
+        INFINITE,
         TRUE) == WAIT_OBJECT_0)
   {
-#ifdef DBUG
-    dbug_print("Worker %x running", lpWorker);
-#endif
+    DEBUG_PRINT("Worker %x running", lpWorker);
     switch (lpWorker->ECommand)
     {
       case WORKER_CMD_NONE:
@@ -90,9 +85,7 @@
         break;
     }
   };
-#ifdef DBUG
-  dbug_print("Worker %x exiting", lpWorker);
-#endif
+  DEBUG_PRINT("Worker %x exiting", lpWorker);

   return 0;
 }
@@ -101,13 +94,7 @@
 {
   LPWORKER lpWorker = NULL;

-  if (!HeapLock(hWorkerHeap))
-  {
-    win32_maperr(GetLastError());
-    uerror("worker_new", Nothing);
-  };
-  lpWorker = (LPWORKER)HeapAlloc(hWorkerHeap, 0, sizeof(WORKER));
-  HeapUnlock(hWorkerHeap);
+  lpWorker = (LPWORKER)caml_stat_alloc(sizeof(WORKER));
   list_init((LPLIST)lpWorker);
   lpWorker->hJobStarted  = CreateEvent(NULL, TRUE, FALSE, NULL);
   lpWorker->hJobStop     = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -117,11 +104,11 @@
   lpWorker->hCommandReady      = CreateEvent(NULL, FALSE, FALSE, NULL);
   lpWorker->ECommand           = WORKER_CMD_NONE;
   lpWorker->hThread = CreateThread(
-    NULL, 
-    THREAD_WORKERS_MEM, 
-    worker_wait, 
-    (LPVOID)lpWorker, 
-    0, 
+    NULL,
+    THREAD_WORKERS_MEM,
+    worker_wait,
+    (LPVOID)lpWorker,
+    0,
     NULL);

   return lpWorker;
@@ -130,18 +117,14 @@
 void worker_free (LPWORKER lpWorker)
 {
   /* Wait for termination of the worker */
-#ifdef DBUG
-  dbug_print("Shutting down worker %x", lpWorker);
-#endif
+  DEBUG_PRINT("Shutting down worker %x", lpWorker);
   WaitForSingleObject(lpWorker->hWorkerReady, INFINITE);
   lpWorker->ECommand = WORKER_CMD_STOP;
   SetEvent(lpWorker->hCommandReady);
   WaitForSingleObject(lpWorker->hThread, INFINITE);

   /* Free resources */
-#ifdef DBUG
-  dbug_print("Freeing resources of worker %x", lpWorker);
-#endif
+  DEBUG_PRINT("Freeing resources of worker %x", lpWorker);
   if (lpWorker->hThread != INVALID_HANDLE_VALUE)
   {
     CloseHandle(lpWorker->hThread);
@@ -181,13 +164,7 @@
     lpWorker->hCommandReady = INVALID_HANDLE_VALUE;
   }

-  if (!HeapLock(hWorkerHeap))
-  {
-    win32_maperr(GetLastError());
-    uerror("worker_new", Nothing);
-  };
-  HeapFree(hWorkerHeap, 0, lpWorker);
-  HeapUnlock(hWorkerHeap);
+  caml_stat_free(lpWorker);
 };

 LPWORKER worker_pop (void)
@@ -203,12 +180,10 @@
   }
   nWorkersCurrent++;
   nWorkersMax = (nWorkersCurrent > nWorkersMax ? nWorkersCurrent : nWorkersMax);
-#ifdef DBUG
-  dbug_print("Workers running current/runnning max/waiting: %d/%d/%d",
+  DEBUG_PRINT("Workers running current/runnning max/waiting: %d/%d/%d",
       nWorkersCurrent,
       nWorkersMax,
       list_length((LPLIST)lpWorkers));
-#endif
   ReleaseMutex(hWorkersMutex);

   if (lpWorkerFree == NULL)
@@ -236,34 +211,24 @@
   bFreeWorker = TRUE;

   WaitForSingleObject(hWorkersMutex, INFINITE);
-#ifdef DBUG
-  dbug_print("Testing if we are under the maximum number of running workers");
-#endif
+  DEBUG_PRINT("Testing if we are under the maximum number of running workers");
   if (list_length((LPLIST)lpWorkers) < THREAD_WORKERS_MAX)
   {
-#ifdef DBUG
-    dbug_print("Saving this worker for future use");
-#endif
-#ifdef DBUG
-    dbug_print("Next: %x", ((LPLIST)lpWorker)->lpNext);
-#endif
+    DEBUG_PRINT("Saving this worker for future use");
+    DEBUG_PRINT("Next: %x", ((LPLIST)lpWorker)->lpNext);
     lpWorkers = (LPWORKER)list_concat((LPLIST)lpWorker, (LPLIST)lpWorkers);
     bFreeWorker = FALSE;
   };
   nWorkersCurrent--;
-#ifdef DBUG
-  dbug_print("Workers running current/runnning max/waiting: %d/%d/%d",
+  DEBUG_PRINT("Workers running current/runnning max/waiting: %d/%d/%d",
       nWorkersCurrent,
       nWorkersMax,
       list_length((LPLIST)lpWorkers));
-#endif
   ReleaseMutex(hWorkersMutex);

   if (bFreeWorker)
   {
-#ifdef DBUG
-    dbug_print("Freeing worker %x", lpWorker);
-#endif
+    DEBUG_PRINT("Freeing worker %x", lpWorker);
     worker_free(lpWorker);
   }
 }
@@ -275,18 +240,11 @@
   /* Init a shared variable. The only way to ensure that no other
      worker will be at the same point is to use a critical section.
      */
-#ifdef DBUG
-  dbug_print("Allocating mutex for workers");
-#endif
+  DEBUG_PRINT("Allocating mutex for workers");
   if (hWorkersMutex == INVALID_HANDLE_VALUE)
   {
     hWorkersMutex = CreateMutex(NULL, FALSE, NULL);
   }
-
-  if (hWorkerHeap == INVALID_HANDLE_VALUE)
-  {
-    hWorkerHeap = HeapCreate(0, sizeof(WORKER) * THREAD_WORKERS_MAX * 4, 0);
-  }
 }

 void worker_cleanup(void)
@@ -300,22 +258,18 @@
   if (hWorkersMutex != INVALID_HANDLE_VALUE)
   {
     WaitForSingleObject(hWorkersMutex, INFINITE);
-#ifdef DBUG
-    dbug_print("Freeing global resource of workers");
-#endif
+    DEBUG_PRINT("Freeing global resource of workers");
     /* Empty the queue of worker worker */
     while (lpWorkers != NULL)
     {
       ReleaseMutex(hWorkersMutex);
       lpWorker = worker_pop();
-#ifdef DBUG
-      dbug_print("Freeing worker %x", lpWorker);
-#endif
+      DEBUG_PRINT("Freeing worker %x", lpWorker);
       WaitForSingleObject(hWorkersMutex, INFINITE);
       worker_free(lpWorker);
     };
     ReleaseMutex(hWorkersMutex);
-    
+
     /* Destroy associated mutex */
     CloseHandle(hWorkersMutex);
     hWorkersMutex = INVALID_HANDLE_VALUE;
@@ -326,24 +280,18 @@
 {
   LPWORKER lpWorker = worker_pop();

-#ifdef DBUG
-  dbug_print("Waiting for worker to be ready");
-#endif
+  DEBUG_PRINT("Waiting for worker to be ready");
   enter_blocking_section();
   WaitForSingleObject(lpWorker->hWorkerReady, INFINITE);
   ResetEvent(lpWorker->hWorkerReady);
   leave_blocking_section();
-#ifdef DBUG
-  dbug_print("Worker is ready");
-#endif
+  DEBUG_PRINT("Worker is ready");

   lpWorker->hJobFunc      = f;
   lpWorker->lpJobUserData = user_data;
   lpWorker->ECommand      = WORKER_CMD_EXEC;

-#ifdef DBUG
-  dbug_print("Call worker (func: %x, worker: %x)", f, lpWorker);
-#endif
+  DEBUG_PRINT("Call worker (func: %x, worker: %x)", f, lpWorker);
   SetEvent(lpWorker->hCommandReady);

   return (LPWORKER)lpWorker;
@@ -356,20 +304,14 @@

 void worker_job_stop (LPWORKER lpWorker)
 {
-#ifdef DBUG
-  dbug_print("Sending stop signal to worker %x", lpWorker);
-#endif
+  DEBUG_PRINT("Sending stop signal to worker %x", lpWorker);
   SetEvent(lpWorker->hJobStop);
-#ifdef DBUG
-  dbug_print("Signal sent to worker %x", lpWorker);
-#endif
+  DEBUG_PRINT("Signal sent to worker %x", lpWorker);
 }

 void worker_job_finish (LPWORKER lpWorker)
 {
-#ifdef DBUG
-  dbug_print("Finishing call of worker %x", lpWorker);
-#endif
+  DEBUG_PRINT("Finishing call of worker %x", lpWorker);
   enter_blocking_section();
   WaitForSingleObject(lpWorker->hJobDone, INFINITE);
   leave_blocking_section();
diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/winworker.h ocaml-unix-3.12.1/otherlibs/win32unix/winworker.h
--- ocaml-unix-3.11.2/otherlibs/win32unix/winworker.h   2008-07-31 14:09:18.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/winworker.h   2010-01-22 13:48:24.000000000 +0100
@@ -11,19 +11,19 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: winworker.h 8961 2008-07-31 12:09:18Z xleroy $ */
+/* $Id: winworker.h 9547 2010-01-22 12:48:24Z doligez $ */
 #ifndef _WINWORKER_H
 #define _WINWORKER_H

 #define _WIN32_WINNT 0x0400
 #include <windows.h>

-/* Pool of worker threads. 
+/* Pool of worker threads.
  *
  * These functions help to manage a pool of worker thread and submit task to
  * the pool. It helps to reduce the number of thread creation.
  *
- * Each worker are started in alertable wait state and jobs are submitted as 
+ * Each worker are started in alertable wait state and jobs are submitted as
  * APC (asynchronous procedure call).
  */

@@ -42,16 +42,16 @@
  */
 typedef void (*WORKERFUNC) (HANDLE, void *);

-/* Initialize global data structure for worker 
+/* Initialize global data structure for worker
  */
 void worker_init (void);

-/* Free global data structure for worker 
+/* Free global data structure for worker
  */
 void worker_cleanup (void);

 /* Submit a job to worker. Use returned data to synchronize with the procedure
- * submitted. 
+ * submitted.
  */
 LPWORKER worker_job_submit (WORKERFUNC f, void *data);

@@ -63,7 +63,7 @@
  */
 void worker_job_stop (LPWORKER);

-/* End a job submitted to worker. 
+/* End a job submitted to worker.
  */
 void worker_job_finish (LPWORKER);

diff -Naur ocaml-unix-3.11.2/otherlibs/win32unix/write.c ocaml-unix-3.12.1/otherlibs/win32unix/write.c
--- ocaml-unix-3.11.2/otherlibs/win32unix/write.c       2009-07-15 14:19:12.000000000 +0200
+++ ocaml-unix-3.12.1/otherlibs/win32unix/write.c       2009-09-25 17:03:06.000000000 +0200
@@ -11,7 +11,7 @@
 /*                                                                     */
 /***********************************************************************/

-/* $Id: write.c 9315 2009-07-15 12:19:12Z xleroy $ */
+/* $Id: write.c 9359 2009-09-25 15:03:06Z weis $ */

 #include <errno.h>
 #include <string.h>