mingw port status

socketサポートのコンパイルを一応通した。変更点は数行。まだ動かないけど道のりは近い。
問題点 :

  • Winsockではerrnoが使えない - 少なくともこれに対処する必要が有る
    • errno参照をWSAGetLastErrorに置き換え(defineで良い)、比較を行うなら対象も変更する errnoと互換するのかは謎。
    • → 単純にGetLastErrorにする方法も有る(どちらもいわゆるWin32 error codeを返す)。
    • http://msdn.microsoft.com/en-us/library/ms737828.aspx
  • os-constantsでエクスポートされる値を生成するポータブルな方法が無い
    • Windows版のconstants定義を分けて持つ? (そもそも両者でポータブルでないもの*1は使わせないのが望ましい)
  • WSAStartupを入れる必要が有る。DLLの読み込み等を伴うので、毎回起動時ではなく、socketを利用した初回で行うべき。staticでフラグを持つ?(このフラグはプロセスで唯一で無ければならない)
  • gai_strerrorがUnicode版になる(Mingw固有?, 日本語が返るかもしれないので、一応UTF-8対応のアレで。)
  • shutdownが無い。TCP的に言うとFINを送る明確な手段が無いことになる。(不要?)
  • 切断のようなイベントを検出する手法が無い。BSD Socketでは予期しない切断イベントにSIGPIPEを受け取るので例外を生成できるが、Winsockには相当する機能が無い(!)ので単にエラーになる。(逆に言えば、BSD SocketではSIGPIPEを処理しないと予期しないタイミングで死ぬことになる。)

意外と最近のWinsock事情って纏まっていないのかもしれない。Winsock programmer's FAQはかなり揃った文書で参考になる( http://tangentsoft.net/wskfaq/ )。日本語訳はそれなりに古い( http://www.kt.rim.or.jp/~ksk/wskfaq-ja/ )。そもそも、WindowsTCPスタックにおける歴史的事情に明るくないと誤解を招くかもしれない。
Mingw版は今後WinXP SP2以降専用。テスト環境が無い。

Index: configure.ac
===================================================================
--- configure.ac        (revision 1651)
+++ configure.ac        (working copy)
@@ -225,8 +225,8 @@
          MOSH_LDADD_ARCH="-lpthread"
          ;;
        *mingw*)
-        MOSH_OPTS="$MOSH_GENERIC_OPTS -DMOSH_MINGW32 -D_UNICODE -DUNICODE -DWINVER=0x500 -D_WIN32_WINNT=0x500"
-         MOSH_LDADD_ARCH="-lshlwapi"
+        MOSH_OPTS="$MOSH_GENERIC_OPTS -DMOSH_MINGW32 -D_UNICODE -DUNICODE -DWINVER=0x501 -D_WIN32_WINNT=0x501"
+         MOSH_LDADD_ARCH="-lshlwapi -lws2_32"
          ;;
         *)
           MOSH_OPTS="-O3 -momit-leaf-frame-pointer -fomit-frame-pointer -march=$host_cpu" # -mfpmath=sse -msse3 -march=$host_cpu
Index: OSCompat.cpp
===================================================================
--- OSCompat.cpp        (revision 1651)
+++ OSCompat.cpp        (working copy)
@@ -30,7 +30,7 @@
  */
 
 
-#ifndef _MSC_VER
+#ifndef _WIN32
 #include <dirent.h>
 #include <sys/socket.h>
 #endif
Index: OSCompat.h
===================================================================
--- OSCompat.h  (revision 1651)
+++ OSCompat.h  (working copy)
@@ -68,7 +68,11 @@
     Transcoder* nativeConsoleTranscoder();
     Transcoder* nativeTranscoder();
 
+#ifdef _WIN32
+    ucs4string getLastErrorMessageInternal(DWORD e);
+#else
     ucs4string getLastErrorMessageInternal(int e);
+#endif
 
     void initOSConstants();
     Object getOSConstant(Object key, bool& found);
Index: OSCompatSocket.cpp
===================================================================
--- OSCompatSocket.cpp  (revision 1651)
+++ OSCompatSocket.cpp  (working copy)
@@ -29,9 +29,16 @@
  *  $Id: OSCompatSocket.cpp 183 2008-07-04 06:19:28Z higepon $
  */
 
+#define _WIN32_WINNT 0x501
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#endif
 #include <unistd.h>
 
 #include "scheme.h"
@@ -105,7 +112,7 @@
     MOSH_ASSERT(isOpen());
 
     for (;;) {
-        const int ret = recv(socket_, data, size, flags);
+        const int ret = recv(socket_, (char *)data, size, flags);
         if (ret == -1 && errno == EINTR) {
             continue;
         }
@@ -128,7 +135,7 @@
     int rest = size;
     int ret = 0;
     while (rest > 0) {
-        ret = ::send(socket_, data, size, flags);
+        ret = ::send(socket_, (const char*)data, size, flags);
         if (ret == -1) {
             setLastError();
             return ret;
@@ -173,7 +180,9 @@
 
     if (ret != 0) {
         isErrorOccured = true;
-        errorMessage = ucs4string::from_c_str(gai_strerror(ret));
+
+        errorMessage = ucs4string::from_c_str("oh, something wrong..");
+        //errorMessage = ucs4string::from_c_str(gai_strerror(ret));
         return NULL;
     }

*1:WindowsのsocketはBluetoothIrDAもつかえる