You're right about the Windows BSD socket functions working on a SOCKET type, not HANDLE -- my mistake :] Though, in Winsock 2 the SOCKET seems to be a typedef of the HANDLE type:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx
So when I create a SOCKET with socket(), I then _open_osfhandle() it to get the associated file descriptor -- AND THEN I go _fdopen() it to get the FILE*. Only then can I assign into a luaL_Stream object. :-)
Segway into seek()'ing: I haven't really considered how working on a file descriptor and then working through the FILE object might desync. I wonder if you write to the file descriptor if the offset of where the file is being written to needs to be updated in the FILE object. I mean if you lseek() an fd, do you need to fseek() the file to the same position to keep them "together"? Or can you have two independant offsets to write from? Can you write to the fd at the associated offset and also at the offset tracked by the FILE object? Hmm. In my socket binding project I actually have an available sendfile() on Linux and I believe you do need to update the offset in the Lua file handle with :seek(), which is why I return how many bytes were written out to the stream.
Anyway, it was a crapload of work to understand the Windows side of things... but I had fun figuring it out (yay obsession! \o/). It'll be a greater payoff when I see it compiling in VS though.
There was a really good book I read, I think it was mentioned earlier by Sean -- UNIX Network Programming: Sockets and XTI by Richard Stevens? This book helped SO MUCH in figuring out how to make the BSD sockets API on Windows and Linux behave relatively the same.
Essentially in Windows you have SOCKET, in Linux you have int for the file descriptors. In Windows if socket() fails you check for INVALID_SOCKET returned by socket(), in Linux you check for a return value of < 0. If an operation fails on a socket (like recv()) you check for that by comparing the return code on Windows against SOCKET_ERROR, on Linux you check for a return of < 0 (again). The more specific error code to feed to strerror() is retrieved with WSAGetLastError() on Windows -- on Linux you copy out errno. It's at least great that both Windows and Linux have strerror() -- though it's still weird as hell that the function isn't thread-safe. I don't see a point to strerror_r() existing, would be nice if POSIX made more changes..
I definitely need to get rid of all my abusive #defines, I've been forced to take C++ classes at my college and I'm sure it would look nicer if I make this a little more object-oriented and cleanly with inline functions. When I wrote my project I was madly in love with C89 -- base denominator and all that. :]
Wouldn't mind taking a look at your project, I'm sure it's not stupid like you say :-)