ふつうのLinuxプログラミング 第2版 Linuxの仕組みから学べるgccプログラミングの王道
- 作者: 青木峰郎
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2017/09/22
- メディア: 単行本
- この商品を含むブログを見る
本書がメインテーマとしているのは「Linuxに用意されている、システムとのやり取りをするためのAPI」。すなわちシステムコールの概念や方法をC言語プログラミングを通じて学ぶことができる1冊です。たとえばls
やmv
やpwd
など、普段何気なく利用しているコマンドがKernelとどのようなやり取りをしているのか? 基礎的だが、おざなりにされがちな部分を学ぶことができて、Linuxに対する理解が深まりました。個人的には
このあたりの「わかったふりをしてきた」ところをきっちり学びなおすことができてよかったと思います。プログラマである以上は仕組みが分かったうえで、便利なものを使うという態度を徹底したいものです。しったかぶりを決め込む、わからないものをわからないままにしておくのはだめ絶対(´・ω・`)
筆者の狙いかどうかはわかりませんが「プログラミングを通じて学ぶ」というのが本書の良書たるゆえんだと思いました。Linuxに書かれた本は数多くあれど、そのほとんどは知識として学ぶだけで、読んだ後にきちんと知識が定着しているかどうかというと、実はちょっとあやしい。一方、本書は大量のソースコードが掲載されており、読者は自由に写経することが可能です(実際わたしも全コードをすべて写経しました)。写経とはいえ、実際に手を動かすのと動かさないのでは、知識の身に付き具合が全く違います。忙しいとついついおっくうになりがちですが、これからも意識的に手を動かしていきたいところです。
最後に読者プレゼント(?)。まずは本書を読み終わった後に、なんとなく作成したなんちゃってls
コマンド。本書の途中でls
コマンドを作成するくだりがあるのですが、それとほぼいっしょのような……。
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> #include <string.h> int main(int argc, char *argv[]) { if (argc == 1) { fprintf(stderr, "NO ARGS\n"); exit(1); } for (int i = 1; i < argc; i++) { char *dirname = argv[i]; DIR *dir = opendir(dirname); if (!dir) { perror(dirname); exit(1); } struct dirent *ent; while (ent = readdir(dir)) { char *filename = ent->d_name; if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; printf("%s\n", filename); } if (closedir(dir) < 0) { perror(dirname); exit(1); } } }
もうひとつが標準入力やファイルから1行すべてを読み込むreadline
関数を作ったので、こちらもなんとなく公開しておきます。本書はその性質上、ファイルから1行読み込む処理を何度も書く必要があるのですが、そのたびにfgets
を使うのは面倒。とくにいちいち文字数を指定するのはおっくうなので、その必要のない関数を用意しておき、使いまわしていました(´・ω・`) 何かのお役に立てば幸いです(´・ω・`)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LEN 100 char *readline(FILE *stream); char *xalloc(char *ptr, int len); void die(char *str); char *readline(FILE *stream) { int len = LEN; char *line = xalloc(NULL, len); char ch; int i; for (i = 0; ;i++) { if (i == len) { len += LEN; line = xalloc(line, len); } ch = getc(stream); if (ch == EOF || ch == '\n') break; line[i] = ch; } if (i == 0 && ch == EOF) return NULL; line[i] = '\0'; return line; } void die(char *str) { fprintf(stderr, "failed to %s\n", str); exit(1); } char *xalloc(char *ptr, int len) { int size = len * sizeof(char); void *str = realloc(ptr, size); if (str == NULL) { if (ptr != NULL) { free(ptr); } die("xalloc"); } return str; }