On Thu, Nov 08, 2007 at 04:20:28PM -0500, Nick Mathewson <[EMAIL PROTECTED]> wrote: > It's kind of a mess, actually. Unfortunately, if you want to do > portable network programming on win32, it's about the best you can do.
since I was told its also a confusing mess, here's a small primer regarding the issues of fds and socket handles on windows (win nt and upwards only, the summary for win 95 and upwards is: its broken, avoid). 1. socket handles are windows file handles. this means that most functions simply do work when passed a socket handle as opposed to a file or other handle (e.g ReadFileEx, which is behind the read() crt function/macro). 2. there is no way to interchange bsd sockets api and winsock api programs without a compatibility layer. this is mostly because close() (actually _close, but the headers hide this fact) works on fds, and socket() does not return an fd. the incompatibility between socket and close requires either to wrap socket, or to wrap the close call (or do something weird and vastly more complex :) one would also need to wrap recv and send (or alternatively read/write/ioctl and so on) to make all this compatible. 3. read/write/close and so on work when given fds that correspond to socket handles internally. --- as implementation strategy, its usually far easier to wrap socket/recv/send than to wrap all the other functions (close/read/write/errno(!) etc.), as wrapping them is trivial (of course, one would use more error checking in reality): #define socket(a,b,c) _open_osfhandle (socket (a, b, c), O_RDWR | O_BINARY) #define recv(a,b,c,d) recv (_get_osfhandle (a), b, c, d) this makes program using fds under unix "magically work" in the majority of cases, with minimal changes. there is another strategy, overriding the others: #define close(a) closesocket(a) #define read(a,b,c) recv(a,b,c,0) But this only works when the program doesn't use fds for anything besides sockets, or majorly complicates the wrappers. some people avoid read/write calls in their code completely, which makes the latter alternative more viable, you only need to wrap close + ioctl, but wrapping close still suffers from the problem that it is valid to call close on non-socket fds, which wouldn't be supported. summary: when using fds, read/write/close works transparently on sockets, allowing you to compile bsd sockets code without problems. when using handles, you need to use the correct data type and also need to wrap at least close (which is hard to do correctly). a more-or-less thin layer is required for all applications. --- relevance to libev: the above is why I choose the fd interface for libev: it not only follows the documentation and uses the right datatypes, it usually allows easier portable programming by encouraging support for important read/write/close functions (and errno) on socket fds. It also allows transparent extensions to libevent to non-socket handles in the future. of course, programs could also use different code paths for windows vs. posix platforms and then expect libevent to also offer this much flexibility, but I don't think libev should foster this when a portable and easier alternative exists. > Right; I'm not proposing that libev should accept Windows HANDLEs > right now -- libevent sure doesn't. but it does, in effect, a subset of windows HANDLEs :) regarding the libevent compatibility layer, I am not sure, but I can imagine that it is possible to use the crt fd management also for converting handles to fds internally. More research would be required for this. but i would still feel very uneasy about the fact that libevent uses int instead of a handle. -- The choice of a Deliantra, the free code+content MORPG -----==- _GNU_ http://www.deliantra.net ----==-- _ generation ---==---(_)__ __ ____ __ Marc Lehmann --==---/ / _ \/ // /\ \/ / [EMAIL PROTECTED] -=====/_/_//_/\_,_/ /_/\_\ _______________________________________________ Libevent-users mailing list Libevent-users@monkey.org http://monkeymail.org/mailman/listinfo/libevent-users