[PATCH] Glib.Io + socket on win32 on Windows
Enrico Tassi <[email protected]> Tue, 10 Dec 2013 16:15:51 +0100
| Newsgroups | gmane.comp.lang.ocaml.lib.gtk |
|---|---|
| Message-ID | <[email protected]> |
--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hello, while porting CoqIDE to windows I had to write a patch for the
Glib.Io module. The function to get an Io.channel on windows is not
the same, and it also depends on the nature of the descriptor
(pipe/file v.s. socket).
I had to add the channel_of_descr_socket variant, that under unix is
just an alias for g_io_channel_unix_new, but that on windows calls
g_io_channel_win32_new_socket instead of g_io_channel_win32_new_fd.
I'm attaching my patch, and a small interactive test (one has to netcat
to the printed port and see if the server correctly reacts when some
data is sent).
According to my tests, if one uses g_io_channel_win32_new_fd on sockets
things go wrong. Also using add_watch on a pipe (on which one can
call g_io_channel_win32_new_fd) does not work.
Best,
--
Enrico Tassi
--cWoXeonUoKmBZSoM
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="io-channels.diff"
--- lablgtk-2.18.0/src/glib.mli 2013-10-01 01:31:50.000000000 -0700
+++ lablgtk-2.18.0.new/src/glib.mli 2013-12-06 11:57:34.203675200 -0800
@@ -75,6 +75,7 @@
type condition = [ `ERR | `HUP | `IN | `NVAL | `OUT | `PRI]
type id
val channel_of_descr : Unix.file_descr -> channel
+ val channel_of_descr_socket : Unix.file_descr -> channel
val add_watch :
cond:condition list -> callback:(condition list -> bool) -> ?prio:int -> channel -> id
val remove : id -> unit
--- lablgtk-2.18.0/src/glib.ml 2013-10-01 01:31:50.000000000 -0700
+++ lablgtk-2.18.0.new/src/glib.ml 2013-12-06 11:57:53.070804800 -0800
@@ -72,6 +72,8 @@
type id
external channel_of_descr : Unix.file_descr -> channel
= "ml_g_io_channel_unix_new"
+ external channel_of_descr_socket : Unix.file_descr -> channel
+ = "ml_g_io_channel_unix_new_socket"
external remove : id -> unit = "ml_g_source_remove"
external add_watch :
cond:condition list -> callback:(condition list -> bool) -> ?prio:int -> channel -> id
--- lablgtk-2.18.0/src/ml_glib.c 2013-10-01 01:31:50.000000000 -0700
+++ lablgtk-2.18.0.new/src/ml_glib.c 2013-12-10 02:03:33.940371800 -0800
@@ -25,6 +25,8 @@
#include <string.h>
#include <locale.h>
#ifdef _WIN32
+/* to kill a #warning: include winsock2.h before windows.h */
+#include <winsock2.h>
#include "win32.h"
#include <wtypes.h>
#include <io.h>
@@ -38,6 +40,11 @@
#include <caml/callback.h>
#include <caml/threads.h>
+#ifdef _WIN32
+/* for Socket_val */
+#include <caml/unixsupport.h>
+#endif
+
#include "wrappers.h"
#include "ml_glib.h"
#include "glib_tags.h"
@@ -325,14 +332,23 @@
#ifndef _WIN32
ML_1 (g_io_channel_unix_new, Int_val, Val_GIOChannel_noref)
+CAMLprim value ml_g_io_channel_unix_new_socket (value arg1) {
+ return Val_GIOChannel_noref (g_io_channel_unix_new (Int_val (arg1)));
+}
#else
CAMLprim value ml_g_io_channel_unix_new(value wh)
{
return Val_GIOChannel_noref
- (g_io_channel_unix_new
+ (g_io_channel_win32_new_fd
(_open_osfhandle((long)*(HANDLE*)Data_custom_val(wh), O_BINARY)));
}
+
+CAMLprim value ml_g_io_channel_unix_new_socket(value wh)
+{
+ return Val_GIOChannel_noref
+ (g_io_channel_win32_new_socket(Socket_val(wh)));
+}
#endif
static gboolean ml_g_io_channel_watch(GIOChannel *s, GIOCondition c,
--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="test.ml"
let main () =
let s = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
Unix.bind s (Unix.ADDR_INET (Unix.inet_addr_loopback,0));
Unix.listen s 1;
let host, port =
match Unix.getsockname s with
| Unix.ADDR_INET(host, port) ->
Unix.string_of_inet_addr host, string_of_int port
| _ -> assert false in
prerr_endline ("connect to " ^ host^" "^port);
let cs, _ = Unix.accept s in
prerr_endline "nc connected";
let ch = Glib.Io.channel_of_descr_socket cs in
let print_cond = function
| `IN -> "IN"
| `ERR -> "ERR"
| `OUT -> "OUT"
| `PRI -> "PRI"
| `NVAL -> "NVAL"
| `HUP -> "HUP"
in
let watch conds =
prerr_endline "something happened";
List.iter prerr_endline (List.map print_cond conds);
true
in
let _ = Glib.Io.add_watch ~cond:[`IN] ~callback:watch ch in
GMain.main ();
exit 0
;;
main ()
--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Lablgtk-list mailing list
[email protected]
https://lists.ocamlcore.org/cgi-bin/listinfo/lablgtk-list
--cWoXeonUoKmBZSoM--