システムプログラミング 第6回
DESCRIPTION
システムプログラミング 第6回. システムコールのエラーメッセージ ファイルシステム. 情報工学科 篠埜 功. 今日からの内容. Linux のシステムコールを用いた C プログラムの作成 今日の内容 システムコールのエラーメッセージについて ファイルシステム. システムコールについて. システムコールとは、カーネル内のコードを呼び出すための C 言語の関数 ファイル、ネットワーク、キーボード等、ハードウェアとのやりとりはすべてカーネルが行う。ユーザはシステムコールを通じてカーネルにハードウェア操作を依頼する。 - PowerPoint PPT PresentationTRANSCRIPT
システムコールについて• システムコールとは、カーネル内のコードを呼び出
すための C 言語の関数• ファイル、ネットワーク、キーボード等、ハード
ウェアとのやりとりはすべてカーネルが行う。ユーザはシステムコールを通じてカーネルにハードウェア操作を依頼する。
• 例えば、ファイルからデータを読み出す場合、 getc, fgetc などのライブラリ関数を呼ぶが、どんなライブラリ関数を呼んだとしても、最終的にはread システムコールが呼ばれ、カーネル内部のコードが実行される。
システムコールの実装システムコールは、 C の関数であり、ライブラリファイル /usr/lib64/libc.a に入っている。$ gcc -print-file-name=libc.a で表示される。システムコールである C の関数の中で、ハードウェア割り込みを起こす命令(トラップ命令)が実行される。これにより、カーネルの割り込み処理部分に制御が移る。トラップ命令実行時にシステムコールの番号を伝え、それによってそれぞれのシステムコールに対応するカーネルのコードに制御が移ることになる。 $ ar t /usr/lib64/libc.a | less
で libc.a の中身のオブジェクトファイルリストが表示される。 write.o, read.o などが入っている。
システムコールの番号1 exit2 fork3 read4 write5 open6 close7 wait8 creat9 link10 unlink11 exec12 chdir…
今後の講義でシステムコールを少しずつ紹介する。各システムコールの C 関数が番号の設定を行うので番号は知らなくてよい。
システムコールのマニュアルシステムコールは man コマンドでマニュアルを表示できる。例えば、 $ man -S 2 writeで write システムコールのマニュアルが表示される。 $ man writeとすると、 write コマンドのマニュアルが表示される。 $ man –a writeとすると、 write の名前のマニュアルがすべて (PAGER がless の場合は q を押すごとに ) 順番に表示される。man コマンドの -S の引数には分類番号を入れる。 1 はコマンド、 2 はシステムコール、 3 はライブラリ関数となっている。
システムコールのエラーメッセージ
• システムコールがエラーになった場合、エラー番号が errno という外部変数に代入されている。この番号を用いてエラーメッセージを出力するライブラリ関数 perror があるのでそれを用いる。( errnoを直接使うプログラムは書かないほうがよい。)
• 例えば、 $ ls aaa のように、 ls コマンドで存在しないファイル名を指定した場合に、そのようなファイルは存在しないといったメッセージが出力される。ここでは perror 関数が用いられている。(そのように ls コマンドが実装されている。)
ライブラリ関数 perror
void perror (char *s)
ライブラリ関数 perror は文字列( char へのポインタ)を引数として受け取り、それを出力し、コロンと空白を出力したあとにシステムコールのエラーメッセージを表示する。
ファイルの1文字目を表示する例(入力して実行、後で詳述)
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#define ERR -1int main (void) { int fd, n; char c; if ((fd = open ("test", O_RDONLY)) == ERR) { perror ("open"); exit(1);}
/* 続き */ if ( (n = read (fd, &c, 1) ) > 0 ) printf ("1 文字目は %c です。\n", c); if (n==ERR) { perror ("read"); exit(1); } if (close (fd) == ERR) { perror ("close"); exit(1); } return 0;}
演習課題さきほどのプログラムを参考にして、テキストファイルの2文字目まで表示するプログラムを open システムコール , read システムコールを使って作成せよ。(さきほどと同様、 printf は使うことにする。)
ファイル操作のシステムコールファイルは OS(Linux) が管理している。ファイルの操作等を行うためのシステムコールが提供される。
open, creat, close, read, write, lseek, dup, dup2 等がある。
今日は open, close, read, write の解説を行う。この前に、まず、ファイルの基本事項の説明を行う。
ファイルとはUNIX 系 OS ではファイルは1つの木構造で管理される。ルートディレクトリ以外は、すべてのファイルには親(ディレクトリ)がある。
ディレクトリもファイルの一種であり、そのディレクトリの子供のファイルの名前を保持しているファイルである。ディレクトリファイルも、(ルートディレクトリ以外は)何らかのディレクトリの子供である。
すべてのファイルはルートディレクトリから親子関係を辿ることによって到達できる。
デバイスファイルUNIX では、端末、ディスク、磁気テープ、プリンタなどの周辺機器やメモリなどの装置のそれぞれに対応するファイルがある。特殊ファイル、あるいはスペシャルファイルとも呼ばれる。デバイスドライバに対するインタフェースであり、ファイルを扱うシステムコールで操作できる。これらのファイルは通常 /dev ディレクトリ以下にある。デバイスは次の2種類に分けられる。• キャラクタデバイス --- 端末やプリンタなど、文字単位で入出力を行う装置• ブロックデバイス --- ディスクや磁気テープ装置など、データをある程度まとまったブロック単位で処理する装置
ファイル名、パス名• ファイルには、名前がある。それをファイル
名という。ディレクトリが違えば同じファイル名であっても別のファイルである。
• パス名は、経路(パス)をファイル名の前につけたものである。
• ファイル名は 255 文字以内、パス名は 4095 文字以内。大文字、小文字、数字、ピリオド、ハイフン、アンダーバーが使える。ファイル名に日本語は使えるが、現状では使わないのが無難。
絶対パス、相対パス• 絶対パス --- ルートディレクトリから下向
きに辿るパス• 相対パス --- 現在のディレクトリからの相
対的な経路で表すパス名で、上に行くこともある。
• ピリオド --- 現在のディレクトリ (current directory) を表す。
• ピリオド2つ --- 親ディレクトリを表す。(例) ../.. は2つ上の親のディレクトリを
表す。
ピリオドの役割ピリオド . はカレントディレクトリを表す。カレントディレクトリの実行形式ファイルを実行するとき、 $ ./testのようにして実行する。単にファイル名を $ testのように打った場合は、 test という実行形式ファイルを、環境変数 PATH に格納されているディレクトリの中から順番に探すことになる。 PATH に . が指定されていない場合は、カレントディレクトリに test があっても実行できない。また、 test がシェルの内部コマンドだったり(実際はそうではないが)、 PATH のディレクトリにある実行ファイルだと、そちらが実行される。 ( 実際に、 /usr/bin/test が存在しており、 /usr/bin は(設定を変えてなければ) PATHに入っている。 )
ホームディレクトリログイン時のディレクトリをホームディレクトリという。通常、 /home の下に作成される。( root というユーザ(スーパーユーザ)のホームディレクトリは /root である)。演習室では、(私 sasano の場合) /home/sitの下にある。ディレクトリを変更するコマンドが cd (シェルの内部コマンド)であり、これは chdir システムコールを使って実現されている。ホームディレクトリはチルダ ~ で表される。
ファイルの保護ファイルを他人(他のユーザ)に見られないように、 permission の指定ができる。 $ ls –alで確認できる。 d rwx rwx rwxの最初の桁以外は変更できる。最初が d だとディレクトリ、 - は一般のファイル。そのあとは、 owner, group, other に対する読み書き実行の許可を表す。(例) -rw-r—r-- だと、一般ファイルで、所有者は読み書き、グループメンバーとその他のユーザは読み出しのみ許可。
Permission の変更Permission の変更は chmod コマンドで行う。 $ chmod モード ファイル名
モードは、 rwx の組を 3桁の 2進数と考え、これを 8進1桁で表わし、 8進3桁で指定することができる。例えば、 rw-r--r-- にしたい場合は 644 とする。
chmod は、 chmod システムコールを使って実現されている。