/etc/rc init
お次はこれ
if [ $1x = autobootx ] then 〜〜 fi
$1はシェル変数で、シェルに与えられた第一引数を意味する
ちなみに$0はシェルのファイル名
処理は、/etc/rcの第一引数がautobootかどうかtestをすると解釈できる
ここで、/etc/rcがどこで呼び出されているか調べてみると、
ftp://ftp.irisa.fr/pub/OpenBSD/src/sbin/init/init.c
にOpenBSDとNetBSDの昔のinitのソースが有ったので参考に読んでみた
#define DEFAULT_STATE runcom enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; /* * The mother of all processes. */ int main(int argc, char *argv[]) 〜〜 while ((c = getopt(argc, argv, "sf")) != -1) switch (c) { case 's': requested_transition = single_user; break; case 'f': runcom_mode = FASTBOOT; break; default: warning("unrecognized flag '-%c'", c); break; }
ここで、「init」がどの引数をつけて呼ばれたか調べている
sはシングルユーザーモード
fはFASTBOOT
/* * Start the state machine. */ transition(requested_transition);
ここで、/etc/rcを起動するための大きなループに入る
さらに
void transition(state_t s) { for (;;) s = (state_t) (*s)(); }
で関数ポインタ?の機能を使って関数を実行する。
s=シングルユーザーだと
/* * Bring the system up single user. */ state_func_t single_user(void)
で
fだと、デフォルトの
/* * Run the system startup script. */ state_func_t runcom(void)
で、さらにruncom()関数の中で、
if ((pid = fork()) == 0) { memset(&sa, 0, sizeof sa); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; (void) sigaction(SIGTSTP, &sa, NULL); (void) sigaction(SIGHUP, &sa, NULL); setctty(_PATH_CONSOLE); argv[0] = "sh"; argv[1] = _PATH_RUNCOM; argv[2] = runcom_mode == AUTOBOOT ? "autoboot" : 0; argv[3] = 0; sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); setprocresources(RESOURCE_RC); execv(_PATH_BSHELL, argv);
子プロセスで、/etc/rcを(やっと)実行している
execv(_PATH_BSHELL, argv);
ね。
ま、この辺しっかり勉強すると、力になるんだろうなぁ。
仕事だとCOBOLと埋め込みSQLのプログラムしか書かないから、Cは全然読めないよぅ。
まぁ、FASTBOOTって何のために実装したんだろうね?
いつか使う日が来るのだろうか?
それと、
if [ $1x = autobootx ]が
なぜ
if [ $1 = autoboot ]
でないのかわからない。
xは何のために有るんだろうか?
あ、それと、/etc/rcがどこに有るかの設定は
paths.h
にかいてあるよ〜