UNIXシステムコールプログラミングのページ(仮)

第2回

プログラム例

  1. 標準入力から入力したテキストを加工して標準出力に出力するプログラムいろいろ
    • 入出力にC標準ライブラリを使用
      • vanilla0.c そのまま
      • lemon0.c アルファベット大文字をすべて対応する小文字に変換する
      • chocolate0.c 各行の行末に $ を追加する
      • peach0.c 空行を除去する
    • 入出力にUNIXシステムコールを使用
      • vanilla.c そのまま
      • lemon.c アルファベット大文字をすべて対応する小文字に変換する
      • chocolate.c 各行の行末に $ を追加する
      • peach.c 空行を除去する
  2. (欠番)
  3. openシステムコールの使用例
    • コマンドライン引数で指定したファイルの中身をそのまま標準出力に出力するプログラム。
      • strawberry.c(2018年7月12日:vanilla.cに合わせて微修正)
    • 標準入力からの入力を、コマンドライン引数で名前(正確にはパス)を指定したファイルに出力するプログラム。
      1. mikan.c 指定した名前のファイルが存在しなければ作成し、存在すれば上書きする。
      2. iyokan.c 指定した名前のファイルが存在しなければ作成し、存在すればファイル末尾に追記する。
      3. kinkan.c 指定した名前のファイルが存在しなければ作成し、存在すればエラーとする。
    • 指定されたアクセス権で空ファイルを作成するプログラム
      • umask値を一時的に0にしてopenシステムコールを呼び出すプログラムudon.c
      • openシステムコールでmodeが0のファイルを生成したのちにそのファイルのパーミッションを修正するプログラムsomen.c(2018年7月20日修正しました)
      注意1
      somen.c の方法は、ファイルを作成した後でアクセス権を緩める方向に変更するので、セキュリティの問題は生じない。 緩いアクセス権で作成してから厳しいアクセス権に変更すると、open()の後でfchmod()の前のわずかの時間に、他のプロセスがファイルに予期せぬアクセスをする危険が生じる。
      注意2
      somen.c で、アクセス権の変更を chmod()で行うと、セキュリティの問題が生じる。 open()の後でchmod()の前のわずかの時間に、他のプロセスがファイル名を変更する危険がある。

readシステムコールの使用上の注意

read()は読み込みに失敗しなければ返値として実際に読み込んだバイト数を返します。 したがって、入力したバイト列を操作することは、readの返値を変数に代入しておき、 その値までくりかえすループを書くことで実現できます。 たとえば、chocolate.cstrawberry.cで行っている次のようなコードをよく書きます。

while ((len = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
	for (j = 0; j < (size_t)len; j ++) {
		(略)
	}
	(略)
}
	  

注意すべきことがいくつかあります。

課題

  1. 標準入力からテキストを入力し、コマンドラインオプションに応じて以下の加工を行って出力するプログラムを書け。

    -e
    出力の各行の行末に $ を追加する
    -l
    アルファベット大文字をすべて対応する小文字に変換する
    -p
    空行を除去する
    1. 入出力にC標準ライブラリを使用せよ。

    2. 入出力にUNIXシステムコールを使用せよ。

  2. 標準入力からテキストを入力し、表示文字(isprint()が真を返す文字)の総文字数を標準出力に出力し、さらに、コマンドラインオプションに応じて以下も出力するプログラムを書け。

    -a
    アルファベット(isalphaが真を返す文字)の総文字数
    -d
    数字(isdigitが真を返す文字)の総文字数
    -p
    区切り文字(ispunctが真を返す文字)の総文字数

    複数の値を出力する場合は、空白区切で一行で出力し、順序は上記のとおりとする。

    1. 入出力にC標準ライブラリのgetcharputcharを使用せよ。

    2. 入出力にUNIXシステムコールのreadwriteを使用せよ。

    ヒント
    aもbもprintfは使用不可だがsnprintfは使用可。
    1. 以下のプログラムを、入出力にC標準ライブラリを使わずUNIXシステムコールを使って書け。
      1. vanilla.cstrawberry.cの機能を併せ持つプログラムを書け。ファイル名が指定されていればそのファイルから入力し、いなければ標準入力から入力せよ。
      2. mikan.ciyokan.ckinkan.c の機能を併せ持つプログラムを書け。オプション -a があれば iyokan.c と同様の動作をし、オプション -c があれば kinkan.c と同様の動作をし、どちらもなければ mikan.c と同様の動作をするようにせよ。両方が同時に指定されていればエラーとせよ。
    2. コマンドラインの第三引数で指定されたパス名のファイルを、第一引数の八進数で指定されたアクセス権で作成し、第二引数で指定された文字列を書き込むプログラムを書け。 該当のファイル名のファイルがすでに存在する時は、書き込みは行わずエラー終了する。 入力と出力にはシステムコールを直接使用すること。

奈良女子大学生活環境学部情報衣環境学科生活情報通信科学コース
数学科出身だけどプログラミングを教えている人