<概要> OS(Linux,Windows)でfork,exec族のシステムコールを用いた実装した簡単なコマンドインタープリタのプログラムを作成を行った。 設定ファイル(.path)をもとにコマンドサーチパスを指定できる。 設定ファイルに適切なパスが記述されていない、もしくはそのパスにないコマンドを入力した場合は、エラーメッセージが表示される。 myth.cを実行すると、 "myprompt> "と表示され、ユーザがコマンドを入力することでコマンドインタープリタとして扱える。 このプログラムは以下の機能も実装している。 パイプを利用した複数のコマンド入力の結合 コマンド入力中にCtrl+Cの入力で現在のコマンドの実行を中断、次のコマンド入力を待機する。 リダイレクションを使用してコマンドへの入力をファイルから得たり、ファイルへ出力したりすることが出来る。 exit入力でコマンドインタープリタを終了する。 ---------------------------------------------------------------------------------------- <必要ファイル> ・mysh.c fork,exec族のシステムコールを用いた実装した簡単なコマンドインタープリタのプログラム ・.path パスを指定する設定ファイル、このファイルに書き込むことでコマンドサーチパスを指定することができるが、 各自で環境をあわせることが必要。 ----------------------------------------------------------------------------------------- <mysh.cについて> コンパイル方法 gcc -o mysh mysh.c 実行方法 (.txtファイルを引数にする) ./mysh 関数郡 (1) main関数 始めにCtrl+C入力によるシグナルの処理、pathの設定処理関数を呼び、コマンドサーチパスの指定による前準備を行っている。 次にgetstr関数により標準入力ストリームにコマンドを入れ、入力が一定以上の場合、適宜discardline関数によって 改行までの読み捨てを行い、次に読み込んだコマンドがエンターキーのみの入力か、”exit”入力かの判定。 この次に、入出力の切り替え処理を行う。ここではリダイレクションで用いる“<”, ”>”, “|” の判定で入出力ファイルを判定、 子プロセスを作成、パイプ処理という流れで実装した。ちなみにここでは利用者の入力用ベクタとexecvpに渡すベクタで分けるために、 それぞれプログラムでui配列、p_av二次元配列を用いて分かりやすくしている。 (2) ouch関数 コマンド実行中にCtrl+Cを入力するとシグナルを受け取り、命令を中断する処理を行う。 (3) Set_Path関数 設定パスを開き読み込む。setenv関数を用いて環境を設定し、コマンドサーチパスを指定できるように実現している。 (4) unite_pipe関数 シェルのパイプの実装をここで行う。標準入力のリダイレクションを伴うため、dup2を使って、入出力の切り替えを行っている。 これにより、2つのコマンドが入力されたときに、子、親プロセスに分けて処理を行い、配列で渡された引数をexecvpで実行することで実現している。 (5) strtovec関数 文字列を読んでベクタの作成を行う。この操作でコマンドインタープリタに入力された文字列をコマンドごとに読んでベクタとして扱うことを可能にしている。 (6) discardline関数 入力が一定以上であった文字列のうち、改行までの読み捨てを行うことのできる関数で、 getc関数でストリームの終端まで読み進め、改行があった場合に読み込みを終えるという処理を行っている。 (7) getstr関数 文字列を標準入力ストリームへ落とし込むための関数で、引数として*promptを与えているが ここを”myprompt> ”と文字列を与えることで毎回、左端にmyprompt> と表示させている。 次に文字列を1行読んで、標準入力ストリームへ取り込む操作を行う。 ----------------------------------------------------------------------------------------- <結果1.jpg、結果2.jpg> プログラムの実行結果を示している。行った順番を示す。 (1) Enter-Keyのみの入力による単なる改行 (2) ls –l による単一コマンドの実行 (3) hoge によるコマンドパスにないコマンドの実行 (4) ls –l | grep result でパイプによる入出力の結合 (5) cat result.txtによるresultの中身の表示 (6) cat 123.txt による123.txtの中身の表示 (7) grep waseda < 123.txt > result.txtによる、リダイレクションによる入出力の変更 (8) そのresult.txtの表示 (9) ./loopで実行中(無限ループ)にCtrl-C入力で動作の停止処理 (10) pwdの実行 (11) exitの入力によるmyshの終了 -------------------------------------------------------------------------------------------