stdioでの標準入出力により、catコマンド作成します。
readやwriteといったシステムコール呼び出しは関数呼び出しよりも大変遅いようです。
そのため、標準入出力ライブラリー(stdio)に記述されている一連の関数を用いることが通例のようです。
stdioでは、ストリームからreadを用いて読み込んだデータをバッファと呼ばれる一時記憶領域に保存し、そこからユーザー指定の任意のデータを抽出するような処理方式になっているようです。
stdioはプログラムとストリームの間にバッファ(緩衝)を用意し、readやwriteの機能を修飾する役目を持っていると考えます。
/* mycat.c */
#include<stdio.h> /* fopen, fgetc, fclose, putchar */
#include<stdlib.h> /* */
int main(int argc, char *argv[])
{
int i;
for(i = 1; i<argc; i++){
FILE *f; /* FILE型へのポインタ */
int c;
f=fopen(argv[i], "r"); /* ファイルパスを指定して、そのファイルにつながるストリームを作り
それを管理するFILE型へのポインタを返し、fへ格納する*/
/*何らかの理由で失敗した場合は、NULLを返し、errnoに原因に対応する値を格納する。*/
if(!f){
perror(argv[i]); /* エラー処理 */
exit(1);
}
while((c = fgetc(f)) != EOF){ /* fputcでストリームからバイト単位でデータを読み込む */
/* ストリームの場合はEOF(-1)が返されるため、*/
/*戻り値を格納する変数もint型である。*/
if(putchar(c) < 0) exit(1); /* バイト単位の出力APIのputcharを用いる。*/
}
fclose(f); /*fが参照するストリームを閉じる。*/
}
exit(0);
}
$ gcc -o mycat mycat.c
$ echo "It is sunny today." > test.txt
$ ./mycat test.txt
It is sunny today.
#ファイルパーミッションを変更して読み取り不可にする
$ sudo chmod -r test.txt
$ ./mycat test.txt
test.txt: Permission denied
#存在しないファイル名(hogehoge)を指定してプログラムを実行
$ ./mycat hogehoge
hogehoe: No such file or directory