MonaでJava (8)

FileInputStreamクラスを実装しました。これでJavaからファイル入力ができるようになります。「AUTOEXEC.MSH」を読み込むコードなら、

FileInputStream fis = new FileInputStream("/AUTOEXEC.MSH");
byte[] data = new byte[fis.available()];
fis.read(data);
fis.close();

4行で書けます。更に改行コードで区切るのも、

String[] list = new String(data).split('\n');

1行で書けます。残る難関はスレッドと共有メモリです。

標準出力スレッドの件

これはいまだに残り続けるMonaの暗黒面の1つです。実行中のアプリの標準出力を横取りしたいときはこのようなコードを各アプリごとに書かなければなりません。どう見ても冗長だし、現在のgcjではスレッドに対応していないので、この部分はJava化できません。

static void StdoutMessageLoop() {
    Message::send(my_tid, MSG_SERVER_START_OK);

    for (MessageInfo msg;;) {
        if (Message::receive(&msg) != 0) continue;

        switch (msg.header) {
            case MSG_PROCESS_STDOUT_DATA:
            {
                monapi_call_mouse_set_cursor(0);
                msg.str[127] = '\0';
                syscall_print(msg.str);
                monapi_call_mouse_set_cursor(1);
                Message::reply(&msg);
                break;
            }
        }
    }
}

void grab_stdout() {
    my_tid = syscall_get_tid();
    dword id = syscall_mthread_create
        ((dword)StdoutMessageLoop);
    syscall_mthread_join(id);
    MessageInfo msg, src;
    src.header = MSG_SERVER_START_OK;
    Message::receive(&msg, &src, Message::equalsHeader);
    dword stdout_tid = msg.from;
    dword svr_tid = 
    monapi_get_server_thread_id(ID_PROCESS_SERVER);
    if (svr_tid != THREAD_UNKNOWN) {
        Message::sendReceive(NULL, svr_tid + 1, 
            MSG_PROCESS_GRAB_STDOUT, stdout_tid);
    }
}

とりえあずプロセスサーバー中でStdoutMessageLoopスレッドを同一プロセスにしてみました。