情報学類主専攻実験/システムプログラム (2004年)

最終更新: 2004/12/17 14:40:00

このページは、筑波大学 情報学類 3年生を対象とした 情報学類主専攻実験の、 テーマ K-3 (システム・プログラム) のためのページ(新城担当部分)です。この実験には、課題が2つあります。

  1. シェル、または、ディレクトリ・ブラウザ(どちらか1つ選択)
  2. MiniFtp
このページでは、シェル、または、ディレクトリ・ブラウザに関連した追加情 報を掲載します。

実験テキスト:

■連絡事項

必ず電子メールを読んで下さい。

◆説明会

2003年度2学期は、最初の時間、9月1日水曜日 12:15 から、説明をやります。 3C113端末室の adonis9 の近くに集まって下さい。

◆中間報告

この課題では、何回か中間報告を出してもらいます。

2004年2学期では、次の日時までに課題を仕上げて指定された方法で提出 してください。

9月8日水曜日 17:00:00
課題1−1、または、課題2−1を行い、電子メールで新城まで提出す る。電子メール図については、付けなくてもよい。(最終的なレポートには必 ず図をつける。)
10月1日金曜日 17:00:00
残り課題を行い、課題1−1、または、課題2−1も含めて全て紙に印 刷して所定のレポート提出箱に提出する(電子メールは不可)。
        July                  August                September      
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa 
             1  2  3    1  2  3  4  5  6  7             1  2  3  4
 4  5  6  7  8  9 10    8  9 10 11 12 13 14    5  6  7  8  9 10 11
11 12 13 14 15 16 17   15 16 17 18 19 20 21   12 13 14 15 16 17 18
18 19 20 21 22 23 24   22 23 24 25 26 27 28   19 20 21 22 23 24 25
25 26 27 28 29 30 31   29 30 31               26 27 28 29 30

       October               November               December       
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa 
                1  2       1  2  3  4  5  6             1  2  3  4
 3  4  5  6  7  8  9    7  8  9 10 11 12 13    5  6  7  8  9 10 11
10 11 12 13 14 15 16   14 15 16 17 18 19 20   12 13 14 15 16 17 18
17 18 19 20 21 22 23   21 22 23 24 25 26 27   19 20 21 22 23 24 25
24 25 26 27 28 29 30   28 29 30               26 27 28 29 30 31

■注意

この実験を取る人は、関連した講義を取るように してください。1学期の講義の中でも、実験に関連した話をします。

■シェル用構文解析器

■シェル用構文解析器

利用者が打ち込んだ行を、シェルの構文に従って解析し、解析木を出力するよ うなプログラムを用意しました。この実験では、シェルの構文解析の部分につ いては、このプログラムを利用してください。

プログラムは、次の場所にあります。

~yas/slab-syspro/shell/

cp -rp などでコピーして使ってください。必要な部分は、次のファイルです。

command.c
command構造体操作
command.h
command構造体データ構造
lexer.c
字句解析器
lexer.h
字句解析器データ構造
parser.c
構文解析器
parser.h
構文解析器データ構造
executer.c
プログラムの実行(画面に表示)
executer.h
そのインタフェース
mysh.c
シェルのmainプログラム
mysh.c では、1行読み込み、parse() を読んで解析しています。 関数は、parse() 構文解析器で、引数で与えられた1行を解析 し、pl_list, pipe_line, single_command という構造体からなる木構造を返 します。

parse() が返した木構造を解析して実行(画面に表示)するものが、 executer.c に含まれている関数です。 このサンプルは、木構造の内容を画面に表示するようになっています。

次のような手順で、executer.c を書き換えていくとよいでしょう。

  1. 1行として簡単なもの(パイプも入出力の切り替えもなし)を与えたと きに、どのような木構造になるか調べる。id がどうなるか、argc, argv がど うなるか、sinfile, soutfile, out_mode がどうなるかを調べる。
  2. execute_single_command() でコマンドを実行する。fork()システムコー ルと execve() システムコール(またはexecv() や execvp() )を使って実行す る。リターンバリューとして、PID を返す。
  3. fork() した場合、親プロセス側は、親は、wait(0), wait3() などで子 供が終了することを待たなければならない。どこで wait すべきかをよく考え る。必ずしも fork() をした関数やループで wait しなければならいことはない。
  4. 標準入力の切り替え(<)を与えた時に command 構造体が どうなるかを調べる。
  5. 標準入力を切り替えを実現する。open() システム・コールとdup() (ま たは、dup2())システム・コール、close() システム・コールを用いる。
  6. 標準出力の切り替え(>)、標準エラーの切り替え (>&)について、標準入力の切り替えと同様のことを行う。 out_mode にも注意する。
  7. パイプ(|)が打ち込まれた時に command 構造体がどうなるかを調べる。
  8. パイプ(|)を実現する。まず、pipe() システム・コールでパイプを作成 し、fork() してから親子で左右の枝を分担して再起、または、ループする。 fork() した後、パイプの不要な口を閉じることを忘れないようにする。
  9. パイプラインでは、一番最後のコマンドだけを wait すればよい。
これらの関数には、引数を追加する必要がでてくるでしょう。ファイル記述子 (標準入力、標準出力など)を付け加えたり、fork すべきかどうかのフラグ を付け加えたりする必要がでてくるでしょう。

fork() のタイミングには注意してください。内部コマンドの場合、fork() を してはいけません。ただし、標準出力がパイプの場合、まずパイプを作成して からfork() する必要があります。fork() すべきかどうかを、木を先読みして 調べる方法もあります。

配列と木構造の探索については、2年生の教科書を読み返して復習して下さい。 配列の場合には、「ループ」することが基本です。パイプラインは、再帰では なくループを使った方が簡単に実現できるようになっています。構造体の場合には、 関数呼び出し(場合によっては再帰呼び出し)を使います。 fork() する時には、2重に検索実行しないように気をつける必要があります。

ループの数は、1つとは限りません。2つのループを使った方が簡単な場合も あります。2つのループとは、2重ループではなくて、1つのループを2回や るものです。

    for( i=0 ; i < n; i++ )
    {
    }
    ...
    for( i=0 ; i < n; i++ )
    {
    }

■パイプラインの作り方

課題1−1では、プロセスの親子関係を中心に調べなさい。これを調べるには、 自分が作成するシェルの参考にするためです。同じ方法を使ってもよいし、独 自の方法を使ってもかまいません。

親子関係を調べるには、ps コマンドを使います。この時、意味はありません が、ps コマンドには、X ウインドウ関係のプログラム(すぐには終了しない) を使うとよいようです。

% csh [←]
% emacs | ps -l [←]
% emacs | kterm | ps -l [←]
% sh [←]
$ emacs | ps -l[←]
$ emacs | kterm | ps -l[←]
$ []
本格的に調べるには、strace コマンドを使います。
% strace -f -o sh.log sh [←]
$ ls[←]
$ ls | head[←]
$ exit[←]
% less sh.log [←]
% egrep 'fork|pie|dup|exec|close|exit|wait' sh.log | less [←]
% egrep 'fork|pie|dup|exec|exit|wait' sh.log | less [←]
% []
プロセスが実行していく過程でどのようにシステムコールを発行していったか の「足跡」をプロセスのトレース(trace)といいます。 strace (Linux) は、プロセスのトレースを表示するコマンドです。-f で、 fork() を越えて子プロセスまで追跡します。-o file で、画面(標準エラー) の代りに、ファイルに結果を落とすことができます。

詳しくは、man strace を見てください。

■ディレクトリ・ブラウザ

◆Ruby/GTK版

Ruby/GTK で途中まで記述したものが、次の場所にあります。
~yas/slab-syspro/dir/dir-browser.rb
C言語で GTK+ (Gimp ToolKit) を直接使っても似たような外観になります。 GTK+ 以外の Tool Kit を使ってもかまいません。

ウインドウの親子関係。table を使ってレイアウトしている。 @table.attach() の引数は、グリッドの左、右、上、下の座標。

window (DirListLong < Gtk::Window)
      table (Gtk::Table)
	    scrollClist (Gtk::ScrolledWindow)
	       clist (DirListLongClist < Gtk::CList)
	    label (Gtk::Label)
	    entry (Gtk::Entry)
	    open_button (Gtk::Button)
	    quit_button (Gtk::Button)

class DirListLongClist < Gtk::CList
Gtk::CList を継承して、ls -l 風の内容を保存するための Clist をつくる。
Dir.new(".")
ディレクトリを開く
dir.each
ディレクトリの各内容についての処理
File.lstat
lstat() システムコール。リンクの先をたどらない。ls -l で lrwxrwxrwx と 表示するには、必要。
clist.signal_connect
クリックされた時の処理を記述する。set_text で、 テキストを設定している。
open_button.signal_connect
Open ボタンが押された時の処理。ここで新しいディレクトリを 開くようにすればよい。
Ruby/GTK については、次の本に詳しく記述されています。
三並 慶佐: Ruby/GTKプログラミング入門,技術評論社 (2002年). ISBN: 4774114685
この本のサンプル・プログラムが次の場所にあります。
~yas/ruby/gtk/book/program/
7_8_2.rb と fileselection.rb が参考になります。

◆java版

Java で途中まで記述したものが、次の場所にあります。
~yas/slab-syspro/dir/DirBrowser.java

ウインドウの親子関係は以下のようになっている。window (JPanel) に縦方向 に流し込んでレイアウトしている。ボタンを横に並べている所は、buttonPart でグループ化している。

this (DirBrowser extends JFrame)
	window (JPanel)
		scrollTable (JScrollPane)
			table (JTable)
		textField
		dirInfoBar (JLabel)
		buttonPart (JPanel)
			openButton (JButton)
			quitButton (JButton)

class DirBrowser extends JFrame
File dir=new File(location); String[] fileList=dir.list();
ディレクトリの内容一覧を得る
file.isDirectory(), file.isFile()
ファイルの型を調べる。
file.canRead(), file.canWrite()
ファイルが読み書きできるかを調べる。
table.addMouseListener()
ファイル名の行がクリックされた時の処理を記述する。 textField.setText() で、textField にテキストを設定している。
openButton.addActionListener()
Open ボタンが押された時の処理。ここで新しいディレクトリを開くよう にすればよい。

■関連ページ


Last updated: 2004/12/17 14:40:00
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>