DZ—X 流プログラミング イルからは読み込みたいバイト数を読み込めるので、戻 り値は引数に指定した読み込むバイト数と同しになりま す。しかし、ファイルの末尾に近い辺りを読み込む場合 はちょっと違ってきます。読み込もうとするバイト数が、 ファイルに残っていないこともあり得ます。 そういう場合、 read システムコールは読み込めるだ け ( つまりファイルの終りまで ) を読み込んで、読み込 んだバイト数を返します。 図 1 を見てください。 /tmp/foo というファイルに は、 16 バイトの文字か書かれています。最初に read シ ステムコールで 10 バイトを読み込もうとしたときは、 123456789 という文字列とその後ろの改行文字を読み 込み 10 という値を返します。その結果、ファイルには 12345 という文字列 ( と改行文字 ) しか残っていないの で、次に 10 バイトを読み込もうとしても実際には 6 バ イトしか読み込めません。また、最後の read システム コールの呼出しでは、 1 文字も読み込めないので 0 が 返されています。普通のファイルを読み込む場合にも、 読み込もうとしたバイト数を読み込めないこともあるの です。 ところで、いったん EOF に達してしまい、 read シ ステムコールが 0 を返したあとでファイルに文字列か書 き加えられて、さらに読み込めるようになった場合には どうなるのでしようか。これも実験してみましよう。 図 2 のプログラムは、図 1 の readtest とほは、同しも のです。 read システムコールが 0 を返すまで、つまり EOF に達するまで読込みをおこない、そのあとで、 echo 12345 > > /tmp/foo というコマンドを system 関数で実行し、 /tmp/foo に 前回は、低水準入出力として open 、 close 、 write 、 書き加えています。そして、再度ファイルから読込みを read システムコールを紹介しました。システムコール おこないます。 でエラーか起こったときに、それを判定したり出力する ファイルに新たに文字列が書き加えられた場合も、 ための errno 外部変数と perror 関数についても解説し read システムコールは正しく読み出せるようです。 ました。 今月は、 read システムコールの戻り値についてもう tail-f コマンド すこし説明を続け、後半では前回の約束どおり select システムコールを紹介します。 ト述の read システムコールの性質を利用すると、 tail コマンドに一 f オプションを付けたときの動作を実現す read システムコールの戻り値 ることができます。 tail コマンドに一 f オプションを指定して引数にファ 則回、 read システムコールは、戻り値として実際に イルを指定すると、そのファイルを監視し続け、新たに 読み込んだバイト数を返すと説明しました。通常、ファ 文字列か書き加えられたときにその文字列を標準出力に 48 今泉貴史 168 UNIX MAGAZINE 1994 ユ 0
て、いずれかのファイル・ディスクリプタから読込みが 可能になるまで待っています。 その後ろは、リスト 2 とあまり変わっていません。ま す、 FD-ISSET を使って現在注目しているファイル・ ディスクリプタから読込みができるかどうかを調べてい ます。もし読込みができなければ、次のファイル・ディ スクリプタを調べにいきます。そのはかに処理が加えら れているのは、 EOF を読んだとき ( 最後の else 節 ) で す。このときには、 pid の値を 0 にするとともに、 wait システムコールを実行して子プロセスが終了したことを 石忍しています。ここで pid を 0 にしているので、最初 の while ループで子プロセスか了したことを確認でき い方を紹介しておきましよう。それは、次のようなもの 山斷変に、 select システムコ usleep 関数 ます。 ールのちょっと変わった使 176 成すると、次のようになります。 システムコールを使って usleep 関数と同様の関数を作 あれは、このような問題は起きません。ためしに、 select select システムコールで usleep 関数を実現するので ムでは用いることができません。 て、タイマー関係のシグナルを捕まえるようなプログラ がって、ほかにも setitimer システムコールを使ってい いうシステムコールを利用して実現されています。した usleep という関数もあります。こちらは setitimer と マイクロ秒単位で休眠時間を指定できるものには、 れば、マイクロ秒単位てイ木眠時間を指定できます。 単位でしか時間を指定できません。しかし select を用い てプロセスを休ませました。 sleep 関数の引数には、秒 「 tail-f コマンドの拡張」の節では、 sleep 関数を用い ができるのです。 timeout で指定した時間だけプロセスを休ませること 時間か経過しなけれは呼出しは終了しません。つまり、 終了はありません。したがって、 timeout で指定した プタか準備できたことによる select システムコールの タが何も指定されていないので、ファイル・ディスクリ この呼出しでは、調べるべきファイル・ディスクリプ select ( 0 、 , NULL , NULL, NULL, &timeout) usleep(ms) uns igned int struct timeval tv; tv . tv—sec = ms / 1000000 ; tv . tv-usec = ms % 1000000 ; se1ect(), NULL, NULL, NULL, &tv) ; ただし、シグナルか起きたときの処理など、 usleep 関 数のはうが優れている部分もあります。プロセスか休眠 している状態で、 usleep 関数はシグナルが発生しても処 理に影響は出ませんが、 select を利用しているとその段 階で処理カ鮗了してしまいます。どちらを使ってもかま いませんが、時間がとくに重要な場合には、 usleep 関数 のほうがよいかもしれません。 マイクロ秒単位で時間を指定できると述べましたが、 select も usleep も実際にはそれほど細かな時間で処理 をおこなうわけではありません。どの程度の間隔で処理 をおこなうかはシステムのクロックなどに依存し、実 際の処理の時間はある程度の値に丸められます。 では、指定できるのがマイクロ秒単位ということではな く、 1 秒よりも短い間隔で時間を指定できることが重要 なのです。 今回は、 read システムコールが実際に読み込むバイ ト数が、要求したバイト数と異なる場合について例を示 して解説しました。また、複数の入出力を操作するとき に必要となる、 select システムコールについても説明 しました。これまでこの連載でとりあげた話題の範囲で select システムコールを説明するのはなかなか困難でし たが、理解していただけたでしようか ? select システム コールが本来の力を発揮するのは、ネットワーク・プロ グラミングをおこなったときです。その際には、きっと 今回の知識か彳殳立つでしよう。 select システムコールはいかにも UNIX らしいシス テムコールだと思うのですが、皆さんはどう感しました か ? UNIX MAGAZINE 1994 ユ 0 ( いまいすみ・たかし東泉工業大学 )
リスト 1 tail-f コマンド #include く stdio . h> #include く fc Ⅱ tl . 五 > #include く unistd . h> #include く string ・ h> int main()c , av) int char char char int char int *myname ; *fname ; fd; buf [BUFSIZ] ; len; strrchr (*av , if ( (myname } else { if (ac 十十 ; myname = *av; myname 十十 ; fprintf (stderr , exit(l); if ( ()d = open((fname = fprintf (stderr, perror (fname) ; exit(l); fO て ( ; "Usage : %s filename\n" , myname) ; *av) , O-RDONLY , 0644 ) ) く 0 Ⅱ lseek(fd, OL, SEEK—END) く 0 ) { myname ) ; if ((len = read(fd, buf, BUFSIZ—I)) く 0 ) { break ; } else if (len > の { buf [len] fputs (buf , stdout) ; exit(l); 書き出します。これは、システムのログファイルなどの、 いっ書き加えられるか分からないファイルを監視するの によく使われます。 この tail コマンドに -f オプションを付けたのと同 しような動きをする tail ー f コマンドを作成してみましょ う。ただし、処理を簡単にするためにコマンド起重加に は出力をせす、起重圻刻こファイルに書き込まれた文字列 だけを出力します ( リスト 1 ) 。 このプログラムで重要なのは、最後の for ループの部 分です。 read システムコールの戻り値が 0 未満の場合 には、エラーを示しているのでプログラムを終了するた めにループを抜けています。一方、 0 よりも大きな値が 返されたときには、文字列を読み込んでいるのでそれを 出力しています。 0 が返された、つまり EOF に達すると、それを無視 170 してもう 1 度 read システムコールを呼び出しています。 EOF に達したときにも繰り返し read システムコールを 呼び出すことにより、ファイルに文字列か書き加えられ てもそれを読み込んで出力できるのです。 tail-f コマンドの拡張 いったん EOF まで読み込んでしまった場合、書込 みがおこなわれるまて無限ループになっている for ルー プでは、引数として指定されたファイルに対して、 read システムコールカ髞り返し呼び出されています。この呼 出しでは、ファイルに新たに文字列か書き加えられてい ないので、 read システムコールはすっと 0 を返し続け ます。 このガ去では、読み込むべき文字列がなくてもファイ UNIX MAGAZINE 1994 ユ 0
ミング 48 ルを読み込もうとし続けます。何も処理をおこなわない のに、 CPU の資源を喰い潰しているわけです。これは いかにもむだです。 1 文字も読めなかった場合にすこしだけプロセスを休 ませると、この状況はかなり改善されます。 tail-f コマ ンドの出力は人間が見るためのものなので、気にならな い程度の短い時間だけ休ませるのであれば、たいして間 題はありません。人間にとっては瞬間でも、プロセスに はかなりの時間になります。 EOF を読んだときに 1 秒イ木むようにしたバージョン は、最後の f 。 r ループのところ以外はリスト 1 のものと 変わりません。変更する部分だけを以下に示します。 for ( ; read(fd, buf , BUFSIZ—I)) if ( (len コマンド 1 : コマンド 1 : コマンド 1 : コマンド 2 : コマンド 2 : コマンド 1 : コマンド 1 : コマンド 2 : LJN Ⅸ流プログラ コマンド 1 の出力 コマンド 1 の出力 コマンド 1 の出力 コマンド 2 の出力 コマンド 2 の出力 コマンド 1 の出力 コマンド 1 の出力 コマンド 2 の出力 くの { break; } else if (len > 0 ) { buf [len] fputs(buf , stdout) ; sleep(l) ; } else { 変更といっても、 2 行加えただけです。 これだけの変 更でも、 CPU の負担はかなり改善されます。 sleep ライプラリ関数は、引数に秒数を指定し、指定 された時間だけプロセスを休眠させます。 1 秒はちょっ と長いような気もしますが、実際に使ってみてもとくに 問題は感しません。イ民している時間をもっと短くした いという人は、彳主する usleep 関数などを使ってくだ ptail コマンド tail - f ではファイルに書き加えられる文字列を出力し ましたが、次にパイプから読み込んだコマンドの出力を 画面に表示するコマンドを作ってみましよう。しかし、 たんにコマンドの出力を画面に表示するのであれば、そ のコマンドを実行するだけなので、出力行の先頭に実行 しているコマンド名を表示するようにします。また、 1 つだけではおもしろくないので、 2 つのコマンドを実行 しながら双方の出力を監視するようにしてみましよう。 作成するコマンドは ptail です。これは、 ptail ”コマンド 1 " ”コマンド 2 ” という形式で用い、その出力は、 UNIX MAGAZINE 1994 ユ 0 となるようにします。 171 消してみましよう。 今回は、 select システムコールを用いてこの問題を解 います。 処理を加えると、さらにプログラムが複雑になってしま る方法については、まだ説明していません。しかもこの いファイル・ディスクリプタに対してこのフラグを立て す。しかし、 open システムコールでオープンしていな 紹介した O-NDELAY フラグが立っていれば回避できま ルが待ってしまうのは、前回 open システムコールで 読み込むべきデータがない場合に read システムコー 理を考えてみてください。 のマニュアルページを参照したり、シグナルを使った処 します。正確な子プロセスの終了を調べたけれは、 wait 今回は子プロセスの終了を簡単に扱うためにこれで判定 されても子プロセスが終了したわけではありませんが、 たときです。厳密には、書込み側の標準出力がクローズ EOF を返すのは、書込み側の標準出力がクローズされ EOF を返したかを調べれば判定できます。パイプが 起動したコマンドの終了は、 read システムコールが 待ってしまう。 ときには、 read システムコールがデータがくるまで ・パイプから読み込む場合、読み込むべきデータがない も、 ptail コマンド自体は終了しない。 ・ ptail のなかから起動した 2 つのコマンドか了して ります。 ところで、このプログラムには、次のような問題があ 処理は tail-f コマンドと基本的に同しです。 にかなり複雑になってしまいましたが、おこなっている コマンドの起動や、行頭にコマンド名を出力するため き出す処理を加えれば完成です ( リスト 2 ) 。 行するように変更して、出力行の先頭にコマンド名を書 ンしている部分を、 pipe や f 。 rk を使ってコマンドを実 このコマンドは、 tail - f コマンドのファイルをオープ
の集合を表す fd-set 型の 3 つの値のアドレス、タイム アウトを指定する構造体 timeval の値のアドレスの 5 つです。 select (width, &rfds, &wfds, &efds, &timeout) int width ; fd_set rfds, wfds, efds ; struct timeval timeout ; width には、 rfds 、 wfds 、 efds に指定するファイ ル・ディスクリプタの、最大値十 1 " ( もしくはそれより も大きな値 ) を指定します。これには、 FD-SETSIZE というマクロを用いることができます。この値は、ファ イル・ディスクリプタの最大値よりも大きいことが保証 されているので、これを使って処理するようにしておけ ば安全です。もちろん、 rfds 、 wfds 、 efds に指定する 値が明らかならば、その最大値に 1 を加えて指定しても かまいません。 rfds 、 wfds 、 efds は、ファイル・ディスクリプタの 集合を表すので、代入により簡単に値を設定することは できません。値の設定には、専用のマクロを使います。 fd-set 型の値を操作するマクロとして、 FD_ZERO (&fds) FD_SET (fd, &fds) FD_CLR(fd, &fds) FD_ISSET(fd, &fds) の 4 つか準備されています。 FD-ZERO は、 fds が示す集合の要素を空にします。 fd-set 型に値を設定する場合には、このマクロを使って いったん要素を空にしてから必要な要素を加えるように してください。 FD-SET は、ファイル・ディスクリプタを集合の要素 に加えるマクロです。複数のファイル・ディスクリプタを 監視する場合、最初に FD-ZERO を使って空にしてお き、必要なファイル・ディスクリプタの数だけ FD ー SET を繰り返して集合を設定します。 FD-CLR は、 FD-SET とは逆の動作をするもので、 集合からファイル・ディスクリプタを削除するためのマ クロです。 最後の FD-ISSET は、集合のなかにファイル・ディ スクリプタが含まれているかどうかを検査するためのも のです。 fd が fds に含まれていれば 0 以外の値を、含 まれていなければ 0 を返します。 引数の話に戻りますが、 rfds には、読込みが可能に なった場合に知らせてほしいファイル・ディスクリプタ 174 の集合を指定します。 wfds には、書込みが可能になっ た場合に知らせてほしいファイル・ディスクリプタの集 合を指定します。 efds には、、特別な条件 " カ起こった ときに知らせてほしいファイル・ディスクリプタの集合 を指定します。ただし、これまでの説明でとりあげた内 容の範囲では、 select システムコールが知らせてくれる ような特別な条件は起こりません。ネットワークを用い たプログラミングなどをおこなうときに、はしめて意味 のある情報が得られます。そのため、 こではこれ以 - E この引数については説明しません。これらの引数には、 fd-set 型の値そのものを指定するのではなく、 fd-set 型 の変数のアドレスを指定します。 最後の timeout 引数は、 select システムコールが条 件が成立するのを待つ最大時間を指定します。つまり、 この timeout で指定された時間が過ぎても指定された 条件 ( たとえば、ファイル・ディスクリプタから読込み が可能になるなど ) が成立しない場合は、 select はあき らめて処理を終了します。 この timeout 引数には、構造体 timeval の値のアド レスを指定します。これは、次のようになっています。 struct timeval { 1 ong tv_sec; 1 ong tv_usec; tv-sec には秒単位、 tv-usec にはマイクロ秒単位の 値を指定します。 tv-sec に 5 を指定し、 tv-usec に 0 を指定した場合、 select システムコールは条件の合った ファイル・ディスクリプタが存在しなくても 5 秒は待ち ます。 tv-sec と tv-usec の両方に 0 を指定した場合 は、条件の合ったファイル・ディスクリプタか存在しな ければただちに処理を終了します。つまり、条件の成り 立っファイル・ディスクリプタが存在するかどうかを、 処理を止めることなく検査できます。 timeout には、 NULL の指定も可能です。その場合 は、、、無限の " 時間を指定したことになります。つまり、 条件が成立するファイル・ディスクリプタか現れるまで、 システムコールは終了しません。 select システムコールの戻り値は、条件の成立したフ ァイル・ディスクリプタの数です。読込みで 2 つ、書込 みで 1 つのファイル・ディスクリプタの処理が可能にな れは、 3 という値が返されます。戻り値が 0 のときは、 timeout で指定した時間か経過しても条件の合ったファ UNIX MAGAZINE 1994 ユ 0
IJN Ⅸ流プログラ ミング 48 リスト 3 ptail の改良 while (buf[0] . pid ! = 0 Ⅱ buf[l] . pid ! = 0 ) { FD_ZERO (&fds) ; if (buf [ 0 ] . pid ! = 0 ) { FD_SET(buf [ 0 ] . fd, &fds) ; if (buf[l] . pid ! = 0 ) { FD_SET(buf [ 1 ] . fd, &fds) ; select (FD—SETSIZE, &fds, NULL, NULL, NULL) ; for (i = 0 ; i く 2 ; i + + ) { bp = &buf [i] ; if ( !FD_ISSET(bp—>fd, &fds) ) { contlnue ; if ( (len = read(bp->fd, bp->rp, BUFSIZ—I)) く 0 ) { exit(l) ; } else if (len > 0 ) { * (bp—>rp + = len) print—lines (bp) ; bp—>pid = 0 ; wait (NULL) ; } else { exit(O); に timeout に残った時間を設定するためです。ただし、 イル・ディスクリプタがなかったことを示します。 0 よ この機能はまだ実現されていないようで、いまのところ りも小さな数字が返された場合はエラーを示します。 は設定しておいた値か残っています。将来的にはこの値 条件の成立したファイル・ディスクリプタがある場合、 も変えられることが考えられるので、毎回設定しなおし 戻り値としてその個数が返されるだけでは、実際にどの たはうが無難です。 ファイル・ディスクリプタの準備ができたのかは分かり ません。 select システムコールでは、準備のできたファ ptail コマンドの改良 イル・ディスクリプタの集合を示すために、引数に指定 した rfds 、 wfds 、 efds の内容を書き換えます。 話を ptail コマンドの改良に戻しましよう。 select シ select システムコールを呼び出したときに、 FD-SET ステムコールを使うと、さきはど「 ptail コマンド」の で設定されていたファイル・ディスクリプタのうち準備 節で述べた問題を解決できます。変更したところはほん ができていないものは、集合から取り除かれています。 のわすかです。まず、変数の宣言に、 そのため、プログラムでは rfds 、 wfds 、 efds に設定 したファイル・ディスクリプタを憶えておき、それぞれ fd_set fds; について FD-ISSET を用いて検査をおこないながら処 を加えて、 main 関数の最後の for の二重ループ以下を 理を進めるのが普通です。もし FD-ISSET の値が真で リスト 3 のように変更します。 あれば、そのファイル・ディスクリプタは準備ができて いるので処理をおこなえます。 無限ループとなっていたものを、ループの終了の条件 を pid の値が 0 以外に変更しています。これは、両方の このことからも分かるように、 いったん select シス 子プロセスカ鮗了したときにプログラムを終了するため テムコールに対して用いたものは、その値カ畯わってい です。ループのなかでは、やはり pid の値を調べながら る可能性があるので、 rfds 、 wfds 、 efds の値は毎回設 fds というファイル・ディスクリプタの集合を設定して 定しなおさなければなりません。 timeout も再び設定し います。そのあとで、 select システムコールを呼び出し たほうがよいでしよう。これは、 select システムコール ています。このときには、 timeout に NULL を指定し が、準備の整ったファイル・ディスクリプタがある場合 175 UNIX MAGAZINE 1994 ユ 0
図 2 テープ・テパイスファイル crw—rw—rw— 1 root crw—rw—rw— 1 root staff staff 18 , 18 , 0 Feb 25 4 Sep 28 ドて構成するのカ材剽純勺だという点です。 140 SCSI では、言求密度とテーフ速度を指定するガ去か規定 最後に、テープ記録形式の選択について説明します。 レコード長で読み取ってもかまいません。 でも、手許の WS の許す範囲で、どのような ( 見かけの ) ばよいのです。はかで書き込まれたテープを受け取った側 る必要はなく、書き込む則の効率などの都合だけを考えれ 同しです。データ交換に用いる場合に相手側のことを考え かけの ) レコード長で書き込んでも、できあがるテープは ズのレコード長に分割されるのですから、どのような ( 見 いすれにせよ、テーフに言当求される点で決まったサイ 限はありません。 のときの空きメモリ量に制約されるくらいで、実質的な制 現在の WS にはたいてい ( 3 ) の機能があり、 ( 2 ) はそ ドライバがもっているかどうか。 READ/WRITE コマンドを実行する機能をデバイス きすぎた場合に、適当なサイズにうリして複数回 SCSI ( 3 ) read/write システムコールで要求されたデータ量か大 1 回あたりのデータ ( 2 ) デバイスドライノヾが許す、 read/write システムコール データ量の限界。 (I)WS の SCSI インターフェイスが 1 回で転送できる ります。 テムコールで読み書きできるデータ量は、次の要素て決ま 見かけのレコード長、つまり 1 回の read/write シス のパラメータとしてえる ) かぎり、矛盾は生しません。 けのレコード長として設定している ( アフリケーションへ てアクセスしています。本当のレコード長の倍数を、見か ン・ソフトウェアはほとんどなく、ほとんどは MT とし ただし、この f : は兼を意識した UNIX のアプリケーショ レコードを読み書きできる仕様になっています。 で、 1 回の read/write システムコールで複数個のテーフ ればなりません。 UNIX 上でのインターフェイスも同様 もちろん、転送するデータ長はレコード長の整数倍でなけ READ/WRITE コマンドで複数レコードを転送します。 固定レコード長の SCSI テープ装置では、 1 回の 1991 /dev/rstO 1988 /dev/nrstO されています。また、テーフの読み書きに際してデータの バッファリングをおこなうかどうかし尺できる規定があ ります。 言当求密度は 1 バイトの数で表されます。 0 がデフォル トの密度、 1 —Ox7E ( 126 ) か標準化された密度、 0X80 ~ 0xFF がメーカーの独自規定用です。 SCSI-2 では、 0X17 以下が規定されており、 0X18 ~ 0x7E は予約領域になっ ています。ただし、 SCSI-2 の密度コードにすべてのテー プ装置カ飛っているわけではありません。テーフ機器の設 計の時点でそのテーフ用の SCSI 規格の密度コードカ鴃め られていない場合には、べンダー固有の密度コードを使用 するしかないわけです。 テーフ。の速度は 4 ビットの数値て指定します。速度コー ド 0 がデフォルトの速度で、 1 が最ー、 2—0xF か高速 モードです。テーフ速度窈旨定は、 WS に接続されている ようなテープ装置では未をもたす、密度を指定した時点 でテーフ速度も決まってしまいます。 データのバッファリング機能を使うかどうかは、テー フの読み書き性能に景グされます。バッファリングをお こなわないで書き込むときは、データがテーフに書き込ま れてからテープ装置の WRITE コマンドか了します。 UNIX 上でのフロセスの write システムコールが、デー タのテーフ。への書込み完了まで待機させられることになり ます。しかも、次に書き込むテーフレコードを用意するた めの処理時間が必要ですから、テーフ。装置に間断なくデー タをイ合し続けることができません。 テーフ装置がバッファリンク幾能をもたない場合や、そ れで悪景切ゞ生じる場合にだけ、バッファリンク饑能を抑 SunOS 4. x でのテープ装置 追加ガ去について解説します。 最初に、 SunOS 4. x ( とくに 4.1.3 ) でのテープ装置の SunOS4 Ⅸへのテーフ追加 制します。 UNIX MAGAZINE 1994.10 ドディスクとは異なり、同一システムに多数のテーフ。装置 SunOS では、 4 つのテーフ。装置か接続できます。
LJN Ⅸ流プログラ 図 1 read システムコールの戻り値 % cat readtest . c printf ("%d bytes read\n" , nbytes) ; printf ("%d bytes read\n" , nbytes) ; printf ("%d bytes read\n" , nbytes) ; #include く fcntl . h> main ( ) int char int nbyt e s perror ( "/tmp/foo" ) ; if ( ()d = open("/tmp/foo" , O—RDONLY, nbytes ; buf[10] ; fd; 0644 ) ) くの { exit(l); read(fd, 0 bytes read 6 bytes read 10 bytes read % . /readtest 12345 123456789 % cat /tmp/foo exit(O); nbytes = read(fd, nbytes = read(fd, buf , 10 ) ; buf , 10 ) ; buf , 10 ) ; 図 2 ファイルに書き加えられた場合の read システムコールの戻り値 % cat extraread. c #include く fcntl . h> main ( ) int char int fd; buf [ 10 ] ; nbytes ; if ((fd = open("/tmp/foo" perror("/tmp/foo") ; exit(l); O_RDONLY , 0644 ) ) くの { while ((nbytes = read(fd, buf, 10 ) ) > 0 ) { printf ("%d bytes read\n" , nbytes) ; printf ( "EOF EOF EOF\n" ) ; system( "echo 12345 > > /tmp/foo" ) ; nbytes = read(fd, buf , 10 ) ; printf("%d bytes read\n" , nbytes) ; exit ( 0 ) ; % cat /tmp/foo 123456789 12345 % . /extraread 10 bytes read 6 bytes read EOF EOF EOF 6 bytes read UNIX MAGAZINE 1994 ユ 0 ミング 48 169
ミング 48 bp->fd bp->rp for (i for ( ; print—lines (bufp) *bufp ; char bp—>wp = bp—>buf ; 0 ; i く 2 ; i + + ) { bp = &buf [i] ; if ( (len = read(bp—>fd, bp—>rp , exit(l); } else if (len > 0 ) { * (bp->rp + = le 取 ) print—lines(bp) ; LJN Ⅸ流プログラ BUFSIZ-I)) く 0 ) { void fbuf void panic() while ()p = strchr(bufp->wp, ) \ Ⅱ ' ) ) ! = NULL) { bufp—>rp = bufp—>buf + (bufp—>rp ー bufp—>wp) ; strcpy (bufp->buf , bufp—>wp) ; return; if (bufp—>rp く & (bufp—>buf [BUFSIZ] ) ) { return; bufp—>wp = bufp—>rp = bufp—>buf ; if (bufp—>wp = = bufp—>rp) { bufp—>wp = p + 1 ; printf ("%s : %s\n" , bufp->command, bufp—>wp) ; bufp—>wp = bufp—>buf ; if (buf [ 0 ] . pid > の { kill(buf [ 0 ] . pid, wait (NULL) ; if (buf [ 1 ] . pid > の { kill(buf [ 1 ] . pid, wait (NULL) ; select システムコーノレは、 select システムコーノレ exit(l); 2 ) ; 2 ) ; ・読込みができるかどうかを調べるように指定されたフ ァイル・ディスクリプタの集合の要素から、読込みが 可能になった ・書込みができるかどうかを調べるように指定されたフ ァイル・ディスクリプタの集合の要素に、書込みが可 UNIX MAGAZINE 1994 ユ 0 能になった ・特別な条件カ起こるかどうかを調べるように指定され たファイル・ディスクリプタの集合の要素に対して、 その条件か起こった ・指定された時間か過した といういすれかの条件の場合に終了するシステムコール です。これらの条件が成立するまでは、プロセスは休ん でいます。 select システムコールの引数は、ファイル・ディスク リプタの最大値を示す整数、ファイル・ディスクリプタ 173
UNiX UNIX REVIEW 誌提携 MAGAZINE 20 昔は昔、今は今 ( 5 ) Windows と UNIX( 下 ) 44 UNIX Communication Notes AMD 再説 (4) 52 インターネットの利用と仕組み NCSA httpd の設定と HTML 入門 61 BSD/386 Version 1 . 1 と Pentium 100 MHz? 67 Daemons&Dragons X ウインドウ・システムの色の管理 85 Windows NT Unicode 96 BSD/386 で楽しむ PC-UNIX ・・ BSD/386 on High Performance PC 107 UN Ⅸの道具箱 フォントのインストールと PS プリンタ 121 転ばぬ先のセキュリティ DNS 130 LittIe Language 自由気ままに TcI / Tk プログラミング 9 ) 137 ワークステーションの基礎知識 磁気テープ ( 7 ) 164 NET WORTH インターネットのバックポー ン 168 UN Ⅸ流フログラミング s ect システムコール 177 An lntroduction tO X Window System 動画の扱い CONTENTS 94 / 10 東田 学、坂下 秀 、 , 山可 吉村 中村修、杉浦一徳 g„•Dinah McNutt ・・・五十嵐久和 、吉村、 ' 伸 片山喜章、白崎博生 山本和彦 srekcah@ sra. CO. jp 齊藤明紀 M. Steven Baker 今泉貴史 ・中村眞 ・表紙デサイン・守屋ー於・目次・絵・坂田かよ