PDAのコンテンツ 関係で、私的には、PDA の中で Tiki を動かしたい。
そうすると Ruby がないとダメということになる。Tiki を動かす前提で Ruby が必要とする リソースというのは何?
mod_ruby ? を良く知らないのだが ... たぶんそれでも 機能が多すぎる。 .. ファイルシステムなんて可能ならなしにしたいぐらいだから ... モジュールのロードなんてのも 当然 できないだろう。
xxx_ruby が必要とするサービスを全部ならべて、それらをサポートするか 必要としないようにしていく。
そういうことをしていかないと いけないのかなぁ。
まずは、mod_ruby を知らないから、知らないといけない。 mod_ruby の ホームページ
よおくみると、ruby が必要って書いてある。ruby から取り出してきたもの ではない?
ruby 自体を調べないといけなさそうだ。ここでは、ruby-1.6.6 を対象として調査。
普通にコンパイルする。top ディレクトリの .o に対して nm してみる。
nm *.o |less
そこで 気が付いたこと ...
こういったのを除けていっても undefined なシンボルが 100 以上ある。
あと Tiki だと NKF 使っている。... これって どうせ nkf を動かしている だけだから 使えない。-- NKF 下位互換のクラスを作れば良いか。
所感:
Ruby を自分の定義した環境で動かす .. というのは不可能ではなさそうだ。
プロセス なくてもなんとかなりそうだし。pipe や system ってのは、
まあ、Thread で 下位互換なものは作れるかも知れない。
といっても
たれに対応する プログラムを仕込んでおかないといけないだろう。
perl を パイプでつなぐとか ... そういうものは無理。
とりあえず、外してしまって、困ったら考えるスタンスがよさそうだ。
ファイル に 相当する概念は必要。wrap することはできそうだが、 結局 wrap すべき API は、POSIX/UNIX 的なものが適切そうだ。
さて、どうやっていこうか ... libc を自分で作るなんてことは、 たいへんにたいへん。
をみると dietlibc newlib とかいろいろある。
いろいろ見てみたが、minix + αが良さげ。
で、どうやっていこうか。
ruby (thread) ----------------------- OS API minix lib v7 fs --------------------------------------------- HOST OS | | | | socket file op stdin/stdout session memory malloc/free TCP/IP
とかいう階層にすれば良さそうか。
ライブラリ および inlucde は、 MINIX-2.0.3 ベースで いくことにした。
または、
必要な分とは ...
LICENSE include lib/ansi lib/math lib/stdio lib/other
あたりか。
とりあえず ...
minlib-base.tgz にまとめてみた。150143 バイト。
そいつらを make してみる。
SRCS= xxx.c .... OBJS= $(SRCS=.c=.o) CFLAGS= -nostdinc -I.. -I../include -D_POSIX_SOURCE -D_EM_WSIZE=4 all: $(OBJS)
という テンプレートで Makefile を作る。
これで make できないやつはとりあえず 外す。
できたら、TOPDIR で
ar ruc minlib.a */*.o
として ライブラリを作っておく。
今度は ruby 。1.6.6 を普通に configure する。
で、できた config.h に対し 次のものを 削除。
< #define HAVE_SYS_FILE_H 1 < #define HAVE_SYS_SELECT_H 1 < #define HAVE_SYS_TIME_H 1 < #define HAVE_SYS_PARAM_H 1 < #define HAVE_SYS_RESOURCE_H 1 < #define HAVE_ST_BLKSIZE 1 < #define HAVE_ST_BLOCKS 1 < #define HAVE_SETITIMER 1 < #define HAVE_GETPRIORITY 1 < #define HAVE_GETRLIMIT 1 < #define HAVE_DLOPEN 1 < #define HAVE_SIGPROCMASK 1 < #define HAVE_TM_ZONE 1 < #define POSIX_SIGNAL 1
で、ruby の TOPDIR から *.c *.h *.y を全部とってきて ruby-box とか適当に もってくる。(必要性はないんだけども)
これらに対して 上の オプションつけて make
typedef int fd_set; #define FD_SET(n, p) (*(p) |= (1 << (n))) #define FD_CLR(n, p) (*(p) &= ~(1 << (n))) #define FD_ISSET(n, p) (*(p) & (1 << (n))) #define FD_ZERO(p) (*(p) = 0) #define FD_COPY(f, t) (*(t) = *(f))
#define NSIG _NSIG の追加 #define SIGEMT 7 /* obsolete */ #define SIGBUS 10 /* obsolete */ を削除。
上の問題を解決するとコンパイルが通る。
で minlib とくっつけてみると .... undefine が出る。
__exit _brksize _close _creat _dup2 _execl_f _print _fcntl _fork _getpid _isatty _kill _lseek _open _penviron _pipe _read _sendrec _sigaction _sigemptyset _waitpid _write sigmask dln_find_exe dln_find_file dln_load ReadDataPending
これをベースにして、改造していく予定。
make できたところから、nm とか見ながら 、修正していく。
random
minix は、srand/rand しかもっていない。
config.h から
#define HAVE_DRAND48 1 #define HAVE_RANDOM 1
を削る。
floating 関係
何を使っているかみてみる。
atan math/atan.c atan2 math/atan2.c ceil math/ceil.c cos math/sin.c exp math/exp.c fmod math/fmod.c frexp --- (math/frexp.s) isinf --- isnan --- ldexp math/ldexp.c log math/log.c log10 math/log10.c modf --- (math/modf.s) pow math/pow.c sin math/sin.c sqrt math/sqrt.c tan math/tan.c floor math/floor.c
string , memory 関係
strcasecmp --- strcat ansi/strcat.c strchr ansi/strchr.c strcmp ansi/strcmp.c strcpy ansi/strcpy.c strerror ansi/strerror.c strftime ansi/strftime.c strlen ansi/strlen.c strncat ansi/strncat.c strncmp ansi/strncmp.c strncpy ansi/strncpy.c strrchr ansi/strrchr.c strstr ansi/strstr.c strtod --- strtok ansi/strtok.c strtoul ansi/strtoul.c sys_nerr ansi/sterror.c memcmp ansi/memcmp.c memcpy ansi/memcpy.c memmove ansi/memmove.c memset ansi/memset.c
stdio 関係
__fillbuf stdio __flushbuf stdio __stderr stdio __stdin stdio __stdout stdio fclose stdio fdopen --- fflush stdio fopen stdio fprintf stdio fputc stdio fputs stdio fread stdio freopen stdio fseek stdio ftell stdio fwrite stdio printf stdio snprintf stdio sprintf stdio ungetc stdio vsnprintf stdio
time 関係
asctime ansi gettimeofday --- (ansi/misc.c _gettimeofday) gmtime ansi localtime ansi
ctype atox 関係
__ctype isprint isspace tolower ansi/tolower.c toupper ansi/toupper.c atoi ansi/atoi.c
その他
crypt other/crypt.c _setjmp --- _longjmp ---
上で出て来たものを除いていくと ... どれだけ残るか ...
次の 81 個。こいつらは、用意するか、使わないようにするか、ごまかすか。 ホストOS のものを使うか しないといけない。
それぞれちゃんと決めないと ... うーんたいへんだ。
とりあえず、host os にスルーするプリミティブに host という 印を付ける。 V7 ベースの internal filesystem でサポートできるのは、v7 。
Process _exit abort exit execl execv fork vfork waitpid times sleep setpgrp undef HAVE_SETPGRP getpgrp undef HAVE_GETPGRP setpgid undef HAVE_SETPGID getpgid undef HAVE_GETPGID setregid undef HAVE_SETREGID setreuid undef HAVE_SETREUID setsid undef HAVE_SETSID getpid getppid change process.c (same as NT) getegid geteuid getgid getgroups undef HAVE_GETGROUPS getuid kill Dir opendir (v7 ?) readdir (v7 ?) rewinddir (v7 ?) seekdir (v7 ?) telldir (v7 ?) closedir (v7 ?) File access v7 chdir v7 chmod v7 chown v7 chroot v7 close v7 dup (v7) dup2 (v7) fchmod (v7) fchown (v7) flock truncate (v7) umask v7 unlink v7 utimes v7 write v7 link v7 lstat (v7) read v7 symlink undef HAVE_SYMLINK readlink undef HAVE_READLINK rename v7 rmdir v7 select getcwd v7 mkdir v7 open v7 fstat v7 ftruncate (v7) stat v7 isatty (常に false) pipe Memory realloc host malloc host free host User/... getpwnam other/getpwent.c endpwent other/getpwent.c Signal signal sigsetmask pause sigblock Environment environ host errno getenv host Others fcntl undef HAVE_FCNTL ioctl syscall not support time host
整理
どのようなものを作ろうとしているか 整理してみる。
tiki httpd ------------------------ ruby [Thread] ----------------------- ライブラリ(Minix) ------------------------ <<<<< VOS API Virtual OS [FileSystem] ------------------------ <<<<< Host OS API Host OS
それだけなら、適当に wrapper を作ってもよさそうだが、
という要件も付け加える。
という路線で進めている。
さて、VOS API と HOST OS API はともに ANSI/POSIX/UNIX 的な API となる。namespace がぶつかるわけだ。
Host OS の方を変更するのは無理として... VOS API の方に __vos_ プレフィックスを付けることにした。
なかなか面倒だが、この作業は だいぶ進んだ。以下 その状況をまとめる。
environ errno malloc realloc free の5つ。 まだうまくいっていなくてごまかしているのが ReadDataPending dln_find_exe dln_find_file dln_load sigmask の5つ。
うまく できていないもの _f_print _penviron File: 33 個 __vos_access __vos_chdir __vos_chmod __vos_chown __vos_chroot __vos_close __vos_creat __vos_dup __vos_dup2 __vos_fchmod __vos_fchown __vos_fcntl __vos_flock __vos_fstat __vos_ftruncate __vos_ioctl __vos_isatty __vos_link __vos_lseek __vos_lstat __vos_mkdir __vos_open __vos_pipe __vos_read __vos_rename __vos_rmdir __vos_select __vos_stat __vos_truncate __vos_umask __vos_unlink __vos_utimes __vos_write Dir: 6個 __vos_closedir __vos_opendir __vos_readdir __vos_rewinddir __vos_seekdir __vos_telldir Time: 2 個 __vos_time __vos_gettimeofday Context: 12 個 __vos_getcwd __vos_getpid __vos_getegid __vos_geteuid __vos_getgid __vos_getuid __vos_setegid __vos_seteuid __vos_setgid __vos_setuid __vos_longjmp __vos_setjmp Process: 9 個 __vos__exit __vos_execl __vos_execv __vos_fork __vos_kill __vos_times __vos_vfork __vos_waitpid __vos_sleep Signal: 5 個 __vos_sigaction __vos_sigblock __vos_sigemptyset __vos_sigsetmask __vos_pause Others: 5個 __vos_frexp __vos_isinf __vos_modf __vos_strtod __vos_syscall
ここまでは、
にいれてある。
その後の変更はテーブルで
#define POSIX_SIGNAL 1 を復活 __vos_sigaction __vos_sigemptyset __vos_sigdelset __vos_sigprocmask __vos_sigfillset という5つの関数をサポートすることに決めた。 sigmask と sigblock はなしに。
オリジナルは、sun の libm 自由に使える。isinf.c は、 NetBSD オリジナル のようだが、Public domain と書いてある。
MINIX は、V7 と完全に同じだった。MINIX の sys/stat.h をそのまま使って も問題ない。 ファイルシステムを持たずに HOST OS の FS を使うときは、 __voo_stat は アーギュメントを変換する必要がある。 ちなみに、シグナル番号や fdset_t も エラー番号も 違うから、要注意。 HOST OS にスルーなんてできなくて、全部変換してやる必要があるわけだ。
V7 がサポートするファイル名は、14 文字。これでは Tiki が動かない。 Minix の struct dirent に合わせて V7 側を変更。 とりあえず、60 文字 までのファイルが作れるはず。 ただ、Tiki のファイル名とか見たら 128 文字を越えていたりする ものがある。 エスケープしないで EUC でそのまま入れることに すれば まあ良いか。 上のようにしたんで、readdir とか ファイルをじかに読んで返すことにする。 fopen して、fread 。これでメモリに載るから、その buf のアドレスを返してしまう。
v7em-003 を取り込む。 インターフェイスがちょっと違う。 * getcwd -- getwd を元に作成。 * direct 関係するもの v7-tar,v7-mkfs, v7-ls も 修正。 * これで 元の PDP11 とは互換性がなくなった。 * euid,egid という概念がない。set はできないようにして、 get は、uid/gid を返すようにする。 HAVE_SETEUID,HAVE_SETEGID を undef * lstat も 作らない。HAVE_LSTAT を undef サポートしたのは、 __vos_access() __vos_chdir() __vos_chown() __vos_chroot() __vos_close() __vos_creat() __vos_dup() __vos_dup2() __vos_link() __vos_open() __vos_lseek() __vos_mkdir() __vos_fstat() __vos_utime() __vos_read() __vos_rename() -- link して 元を unlink するだけの簡易バージョン __vos_rmdir() __vos_stat() __vos_umask() __vos_unlink() __vos_write() __vos_chmod() __vos_getcwd() __vos_getegid() --- getgid() と同じ __vos_geteuid() --- getuid() と同じ __vos_getgid() __vos_getuid() __vos_setgid() -- チェックなし __vos_setuid() -- チェックなし これで 一気に stub が 減った。 残っているのは結構厄介。 ioctl, isatty, flock, fcntl ,select flock,fcntl は 作るだけで良いが ioctl,isatty,select というものは、ちゃんと ストリーミング I/O を サポートして、その上で... ということになる。
このへんでスナップショットを 置いておく。