catコマンドを作る
P86
掲載されているソースを見ないで書いてみる。
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define BUF_SIZE 1024 void do_cat( const char *pszFileName ) { int fd = open( pszFileName, O_RDONLY ); if (fd > 0) { char buf[BUF_SIZE]; int buf_read = 0; while ( (buf_read = read(fd, buf, BUF_SIZE-1)) > 0 ) { // segmentation fault //buf[buf_read] = '?0'; //printf(buf); write( STDOUT_FILENO, buf, buf_read ); } } else { printf("Couldn't open '%s'?n", pszFileName); } close (fd); } int main( int argc, char *argv[] ) { int i; if ( argc < 2 ) { return 0; } for ( i = 1; i < argc; i++ ) { do_cat(argv[i]); } return 0; }
readしたbufferをprintfで書いたらセグメンテーション違反って言われたので素直にwriteを使ったらうまくいった。
教科書のソースと比べて気づいた点。
- プロトタイプ宣言がある
- dieを作ってる
- readするループが無限ループ
- しかも無限ループがfor文(while(1)の方が好きだ)
- システムコールの戻り値をちゃんとチェックして適切な対応(die or break)をしている
- do_catの戻り値の型がstatic void
- sizeof buf(sizeof(buf)じゃなくていいんだね)
- ポインタ変数でも変数名がpで始まらない
システムコールでエラーが発生した場合、エラーNo.がerrnoというグローバル変数にセットされる。perror(const char *s)でそれに対応するメッセージを標準エラー出力に出力、strerror(int errnu)で対応するメッセージを取得。Perlの$!と同じようなもの。
-
- -