システムプログラミング 第6回、7回

27
シシシシシシシシシシシ シシ シ シ 6、7 シシシシシ シシ シ main シシシシシ usage シシシシシ シシシシシシシシシシシシシシシシ シシシシ

Upload: dasan

Post on 06-Feb-2016

43 views

Category:

Documents


0 download

DESCRIPTION

システムプログラミング 第6回、7回. main 関数の引数 usage メッセージ システムコールのエラーメッセージ ファイル. 情報工学科 篠埜 功. 今日からの内容. Linux のシステムコールを用いた C プログラムの作成 今日の内容 C プログラムの main 関数の引数について Usage メッセージについて システムコールのエラーメッセージについて. C の main 関数の引数について. /* コマンド名および引数を表示 */ #include< stdio.h > - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: システムプログラミング 第6回、7回

システムプログラミング第6回、7回

情報工学科 篠埜 功

main 関数の引数usage メッセージシステムコールのエラーメッセージファイル

Page 2: システムプログラミング 第6回、7回

今日からの内容• Linux のシステムコールを用いた C プログ

ラムの作成• 今日の内容

– C プログラムの main 関数の引数について– Usage メッセージについて– システムコールのエラーメッセージについて

Page 3: システムプログラミング 第6回、7回

C の main 関数の引数について/* コマンド名および引数を表示 */#include<stdio.h>int main (int argc, char *argv[ ]) { for ( ; *argv; argv++) printf ("%s\n", *argv); return 0;}

$ gcc 1.c$ ./a.out abc 234./a.outabc234$

(実行例)

Page 4: システムプログラミング 第6回、7回

main 関数の第3引数 main 関数は第3引数に環境変数の情報の配列が渡される場合がある。( ISO 規格で定められているわけではなく、処理系依存。)

#include<stdio.h>int main (int argc, char *argv[ ], char *envp[ ]) { for ( ; *envp; envp++) printf ("%s\n", *envp); return 0;}

演習室の環境では第3引数を受け取れる。第3引数はなくてもよい。環境変数はライブラリ関数 getenv() で取得できるのでそれを使えばよい。

Page 5: システムプログラミング 第6回、7回

スタートアップルーチンC 言語プログラムは、実行形式ファイルにするときにスタートアップルーチンとリンクされる。スタートアップルーチンは、 /usr/lib/crt1.o にある。 $ nm /usr/lib/crt1.oで確認。この出力結果に U mainという行が含まれており、スタートアップルーチンがmain 関数を呼び出していることがここに反映されている。スタートアップルーチン部分で引数の個数、引数の文字列配列、環境変数配列を main 関数に渡す。

Page 6: システムプログラミング 第6回、7回

コマンドのオプションについて• オプションはハイフンのあとに1文字 (-o など )• オプションのあとにオプションの引数があることも

ある– (例) gcc –o main main.c など。

• いくつかのオプションをまとめて記述することもある– 例 ls -la は、 ls -l -a をまとめて書いたものである。

• --help のように、ハイフンが2つの場合もある。(これは -h -e -l -p を -help と書いた場合との区別のため)

Page 7: システムプログラミング 第6回、7回

Usage メッセージ(1)オプションが正しく与えられなかった場

合(2) コマンドの引数に過不足があった場合このような場合にメッセージを出すのが普

通。これを Usage メッセージという。例えば、 $ cp のように cp コマンドを引数

無しで実行すると、 Usage メッセージが表示される。

Page 8: システムプログラミング 第6回、7回

例(打ち込んで確認)

/* Usage メッセージを表示するだけのプログラム */#include<stdio.h>int main (int argc, char * argv[]) { if (argc!=2) fprintf (stderr, "Usage: %s filename\n", argv[0]); return 0;}

(実行例)$ gcc usage.c$ ./a.outUsage: ./a.out filename

Page 9: システムプログラミング 第6回、7回

システムコールについて• システムコールとは、カーネル内のコードを呼び出

すための C 関数• ファイル、ネットワーク、キーボード等、ハード

ウェアとのやりとりはすべてカーネルが行う。ユーザはシステムコールを通じてカーネルにハードウェア操作を依頼する。

• 例えば、ファイルからデータを読み出す場合、 getc, fgetc などのライブラリ関数を呼ぶが、どんなライブラリ関数を呼んだとしても、最終的にはread システムコールが呼ばれ、カーネル内部のコードが実行される。

Page 10: システムプログラミング 第6回、7回

システムコールの実装システムコールは、 C の関数であり、ライブラリファイル /usr/lib/libc.a に入っている。システムコールである C の関数の中で、ハードウェア割り込みを起こす命令(トラップ命令)が実行される。これにより、カーネルの割り込み処理部分に制御が移る。トラップ命令実行時にシステムコールの番号を伝え、それによってそれぞれのシステムコールに対応するカーネルのコードに制御が移ることになる。

$ ar t /usr/lib/libc.a | lessで libc.a の中身のオブジェクトファイルリストが表示される。 write.o, read.o などが入っている。

Page 11: システムプログラミング 第6回、7回

システムコールの番号1 exit2 fork3 read4 write5 open6 close7 wait8 creat9 link10 unlink11 exec12 chdir…

今後の講義でシステムコールを少しずつ紹介する。各システムコールの C 関数が番号の設定を行うので番号は知らなくてよい。

Page 12: システムプログラミング 第6回、7回

システムコールのマニュアルシステムコールは man コマンドでマニュアルを表示できる。例えば、 $ man -S 2 writeで write システムコールのマニュアルが表示される。 $ man writeとすると、 write コマンドのマニュアルが表示される。 $ man –a writeとすると、 write の名前のマニュアルがすべて (PAGER がless の場合は q を押すごとに ) 順番に表示される。man コマンドの -S の引数には分類番号を入れる。 1 はコマンド、 2 はシステムコール、 3 はライブラリ関数となっている。

Page 13: システムプログラミング 第6回、7回

システムコールのエラーメッセージ

• システムコールがエラーになった場合、エラー番号が errno という外部変数に代入されている。この番号を用いてエラーメッセージを出力するライブラリ関数 perror があるのでそれを用いる。( errnoを直接使うプログラムは書かないほうがよい。)

• 例えば、 $ ls aaa のように、 ls コマンドで存在しないファイル名を指定した場合に、そのようなファイルは存在しないといったメッセージが出力される。ここでは perror 関数が用いられている。(そのように ls コマンドが実装されている。)

Page 14: システムプログラミング 第6回、7回

ライブラリ関数 perror

void perror (char *s)

ライブラリ関数 perror は文字列( char へのポインタ)を引数として受け取り、それを出力し、コロンと空白を出力したあとにシステムコールのエラーメッセージを表示する。

Page 15: システムプログラミング 第6回、7回

ファイルの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;}

Page 16: システムプログラミング 第6回、7回

演習課題さきほどのプログラムを参考にして、テキストファイルの2文字目まで表示するプログラムを open システムコール , read システムコールを使って作成せよ。(さきほどと同様、 printf は使うことにする。)

Page 17: システムプログラミング 第6回、7回

ファイル、プロセス• OS(Linux) は、ファイルとプロセスを木構

造で管理する。• まず、ファイルの木構造について学習する。

Page 18: システムプログラミング 第6回、7回

ファイル操作のシステムコールファイルは OS(Linux) が管理している。ファイルの操作等を行うためのシステムコールが提供される。

open, creat, close, read, write, lseek, dup, dup2 等がある。

今日は open, close, read, write の解説を行う。この前に、まず、ファイルの基本事項の説明を行う。

Page 19: システムプログラミング 第6回、7回

ファイルとはUNIX 系 OS ではファイルは1つの木構造で管理される。ルートディレクトリ以外は、すべてのファイルには親(ディレクトリ)がある。

ディレクトリもファイルの一種であり、そのディレクトリの子供のファイルの名前を保持しているファイルである。ディレクトリファイルも、(ルートディレクトリ以外は)何らかのディレクトリの子供である。

すべてのファイルはルートディレクトリから親子関係を辿ることによって到達できる。

Page 20: システムプログラミング 第6回、7回

デバイスファイルUNIX では、端末、ディスク、磁気テープ、プリンタなどの周辺機器やメモリなどの装置のそれぞれに対応するファイルがある。特殊ファイル、あるいはスペシャルファイルとも呼ばれる。デバイスドライバに対するインタフェースであり、ファイルを扱うシステムコールで操作できる。これらのファイルは通常 /dev ディレクトリ以下にある。デバイスは次の2種類に分けられる。• キャラクタデバイス --- 端末やプリンタなど、文字単位で入出力を行う装置• ブロックデバイス --- ディスクや磁気テープ装置など、データをある程度まとまったブロック単位で処理する装置

Page 21: システムプログラミング 第6回、7回

ファイル名、パス名• ファイルには、名前がある。それをファイル

名という。ディレクトリが違えば同じファイル名であっても別のファイルである。

• パス名は、経路(パス)をファイル名の前につけたものである。

• ファイル名は 255 文字以内、パス名は 4095 文字以内。大文字、小文字、数字、ピリオド、ハイフン、アンダーバーが使える。ファイル名に日本語は使えるが、現状では使わないのが無難。

Page 22: システムプログラミング 第6回、7回

絶対パス、相対パス• 絶対パス --- ルートディレクトリから下向

きに辿るパス• 相対パス --- 現在のディレクトリからの相

対的な経路で表すパス名、上に行くこともある。

• ピリオド --- 現在のディレクトリ (current directory) を表す。

• ピリオド2つ --- 親ディレクトリを表す。(例) ../.. は2つ上の親のディレクトリを

表す。

Page 23: システムプログラミング 第6回、7回

ピリオドの役割ピリオド . はカレントディレクトリを表す。カレントディレクトリの実行形式ファイルを実行するとき、 $ ./testのようにして実行する。単にファイル名を $ testのように打った場合は、 test という実行形式ファイルを、シェル ( 例えば tcsh) が、シェル変数 PATH に格納されているディレクトリを順番に探すことになる。 PATH に . が指定されていない場合は、カレントディレクトリに test があっても実行できない。また、 test という名前の実行ファイルがシェルの内部コマンドだったり(実際は違うが)、他の PATH の(順番が先になっている)ディレクトリにあると、そちらが実行される。 ( 実際に、 /usr/bin/test が存在する。 )

Page 24: システムプログラミング 第6回、7回

ホームディレクトリログイン時のディレクトリをホームディレクトリという。通常、 /home の下に作成される。( root というユーザ(スーパーユーザ)のホームディレクトリは /root である)。演習室では、(私 sasano の場合) /home/sitの下にある。ディレクトリを変更するコマンドが cd (シェルの内部コマンド)であり、これは chdir システムコールを使って実現されている。ホームディレクトリはチルダ ~ で表される。

Page 25: システムプログラミング 第6回、7回

ファイルの保護ファイルを他人(他のユーザ)に見られないように、 permission の指定ができる。 $ ls –alで確認できる。 d rwx rwx rwxの最初の桁以外は変更できる。最初が d だとディレクトリ、 - は一般のファイル。そのあとは、 owner, group, other に対する読み書き実行の許可を表す。(例) -rw-r—r-- だと、一般ファイルで、所有者は読み書き、グループメンバーとその他のユーザは読み出しのみ許可。

Page 26: システムプログラミング 第6回、7回

Permission の変更Permission の変更は chmod コマンドで行う。 $ chmod モード ファイル名

モードは、 rwx の組を 3桁の 2進数と考え、これを 8進1桁で表わし、 8進3桁で指定することができる。例えば、 rw-r--r-- にしたい場合は 644 とする。

chmod は、 chmod システムコールを使って実現されている。

Page 27: システムプログラミング 第6回、7回

ファイルの所有者ファイルには所有者、グループが関連づけられている。 $ ls –lで確認できる。

ファイルの所有者の変更は chown コマンド、グループの変更は chgrp コマンドで行う。これらは chown システムコールを使って実現されている。ただし、所有者とスーパーユーザ以外は変更できない。