最終更新: 2001/08/31 17:36:24
このページは、筑波大学
情報学類
3年生を対象とした
計算機システム実験の、
テーマ K-3 (システム・プログラム)
のためのページ(新城担当部分)です。この実験には、
課題が2つあり、シェルとftpのプログラムを作成します。
このページでは、シェルの作成に関連した追加情報を掲載します。
科目番号:
- 情報科学実験I,II
- L41 1903, L41 2003
- 計算機システム実験I,II
- L51 1903, L51 2003
- 知能情報メディア実験I,II
- L61 1903, L51 2003
- ソフトウェア工学実験I,II
- L11 1613, L11 1623
- 情報処理工学実験
- L21 1213, L21 1223
実験時間:水3・4、金4・5
実験テキスト:
2学期は、最初の時間、9月5日水曜日に、説明をやります。3C113計算
機室に集まって下さい。
実験を取っている人のメーリング・リストを作りました。最初のメールは送り
ました。届いていない人は、新城まで連絡してください。
この課題では、何回か中間報告を出してもらいます。
2001年2学期では、次の日時までに課題を仕上げて指定された方法で提出
してください。
- 9月12日水曜日
- シェルの課題1−1を行い、電子メールで新城まで提出する。
ただし、図については、付けなくてもよい。テキスト部分だけでよい。
(最終的なレポートには必ず図を付けること。)
- 10月5日金曜日
- 残り課題1−2、1−3を行い、課題1−1も含めて全て紙に印刷して
新城に提出する。
電子メール:<yas@is.tsukuba.ac.jp>
新城の教官室:3F829
この実験を取る人は、関連した講義を取るように
してください。1学期の講義の中でも、実験に関連した話をします。
この実験テーマを取ることが確定した人は、各学期の最初の実験の日に新城に
電子メールで連絡してください。
利用者が打ち込んだ行を、シェルの構文に従って解析し、解析木を出力するよ
うなプログラムを用意しました。この実験では、シェルの構文解析の部分につ
いては、このプログラムを利用してもかまいません。
プログラムは、次の場所にあります。
~yas/slab-syspro-2001/myshparse2/
cp -rp などでコピーして使ってください。必要な部分は、次のファイルです。
command.c
- command構造体操作
command.h
- command構造体データ構造
lexer.c
- 字句解析器
lexer.h
- 字句解析器データ構造
parser.c
- 構文解析器
parser.h
- 構文解析器データ構造
ここもっとも重要な関数が、parse()
です。これは、引数で与
えられた1行を解析し、commandという構造体からなる木構造を返します。
次の3つのファイルがサンプルです。
mysh.c
- mainプログラム。1行読み込み。
executer.c
- 実行部分
executer.h
- 実行部分データ構造
このサンプルは、command構造体からなる木構造の内容を画面に表示するよう
になっています。
次のような手順で、execute_command() を書き換えていくとよいでしょう。
- 1行として簡単なもの(パイプも入出力の切り替えもなし)を与えたと
きに、どのような木構造になるか調べる。id がどうなるか、argc, argv がど
うなるか、sinfile, soutfile,out_mode, comm1, comm2 がどうなるかを
調べる。
- do_simple() でコマンドを実行する。この時、内部コマンドなら自分自
身で実行する。外部コマンドなら、fork()システムコールと execve() システ
ムコール(またはexecv() や execvp() )を使って実行する。
リターンバリューとして、PID を返す。
- fork() した場合、親プロセス側は、親は、wait(0), wait3() などで子
供が終了することを待たなければならない。どこで wait すべきかをよく考え
る。必ずしも fork() をした関数で wait しなければならいことはない。
- 標準入力の切り替え(<)を与えた時に command 構造体が
どうなるかを調べる。
- 標準入力を切り替えを実現する。open() システム・コールとdup() (ま
たは、dup2())システム・コール、close() システム・コールを用いる。
- 標準出力の切り替え(>)、標準エラーの切り替え
(>&)について、標準入力の切り替えと同様のことを行う。
out_mode にも注意する。
- パイプ(|)が打ち込まれた時に command 構造体がどうなるかを調べる。
- パイプ(|)を実現する。まず、pipe() システム・コールでパイプを作成
し、fork() してから親子で左右の枝を分担して再起する。fork() した後、パ
イプの不要な口を閉じることを忘れないようにする。
- パイプラインでは、一番最後のコマンドだけを一番外側で wait すれば
よい。
do_シリーズの関数には、引数を追加する必要がでてくるでしょう。
ファイル記述子を付け加えたり、fork すべきかどうかのフラグを
付け加えたりする必要がでてくるでしょう。
fork() のタイミングには注意してください。内部コマンドの場合、fork() を
してはいけません。ただし、標準出力がパイプの場合、まずパイプを作成して
からfork() する必要があります。fork() すべきかどうかを、木を先読みして
調べる方法もあります。
木構造の探索については、2年生の教科書を読み返して復習して下さい。木構
造を手繰る時に、fork() しながら同時に左右2つの枝を降りていくようにし
ます。戻ってくる必要がないので、ある意味では、逐次のアルゴリズムよりは
自然です。
Last updated: 2001/08/31 17:36:24
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>