ふつうのLinuxプログラミングに入門した。第5章 練習問題
ツールの実装を読んでいると、Linuxのシステムコールやシグナルの知識が足りなくて、ときどき理解できません。
例)「シグナルを出すときはkill関数を使う」らしいけど、ツールの中ではsignal関数使ってるよ…どういうことなの… ←いまここ
というわけで、『ふつうのLinuxプログラミング入門』(通称・ふつりな)をやることにしました。
問題
サンプルコードとしてcatの簡易版がある。
これは、コマンドライン引数でファイル名を与えると、ファイルの内容を標準出力に書き込むプログラムである。
ファイル名が渡されない場合に、標準入力を読むように改造せよ。
自分の解答
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> static void do_cat(const char *path); static void die(const char *s); char *program; int main(int argc, char *argv[]) { int i; program = argv[0]; if(argc < 2){ program = argv[0]; do_cat(argv[0]); } else { for(i = 1; i < argc; i++){ do_cat(argv[i]); } } exit(0); } #define BUFFER_SIZE 2048 static void do_cat(const char *path) { int fd; unsigned char buf[BUFFER_SIZE]; int n; int isfile = 0; if(strcmp(path, program) == 0){ fd = STDIN_FILENO; } else { isfile = 1; fd = open(path, O_RDONLY); if(fd < 0){ die(path); } } for(;;){ n = read(fd, buf, sizeof buf); if(n < 0){ die(path); } if(n == 0){ break; } if(write(STDOUT_FILENO, buf, n) < 0){ die(path); } } if(isfile){ if(close(fd) < 0){ die(path); } } } static void die(const char *s) { perror(s); exit(1); }
思ったこと
- 引数がない状態を判定する方法がひどい
- どうしたらいいんだッ
- ”NO-FILE”とか渡した方が、関数の外に変数を定義するよりは、マシかも
- そもそも、コマンドライン引数の有無によってストリームの先を分けるとき、これくらいの役割・量の関数であれば、次のどちらがよいのか?
- mainで切り替えて別の関数に振り分ける
- どちらにも対応できる関数を作る
- 標準入力から読む場合に、Ctrl+cを押さない限り終了しない。改行を認識させて終了処理をした方がよい。
正解は・・・
サンプルコードのcat3.cを参照してください。
とのことだけど、見つけてないので、またあとで。ページ数書いてくれればいいのに><著者のWebサイトからサンプルコードをダウンロードできました。