世にも恐ろしいSIGPIPE、ソケットプログラミングの落とし穴
前回、「次回もシグナルのことを書く」と書いたのでシグナルのことを書く*1.
ソケットプログラミングの落とし穴は色々あるけど、ここでは個人的に嵌ったシグナル関連の落とし穴に関して書き殴る.
結論から書くと、コネクションが切れたソケットに書き込み(send(2)とかwrite(2)とか、同じものだけど)を行うと、SIGPIPEシグナルが発生してプロセスが強制終了するので、きちんとSIGPIPEシグナルをハンドリングしておこうという話.
以下では、サンプルコードを使って、実際にパイプの書き込み先をkillして、SIGPIPEの発生を疑似体験してみる.
*1:前回から115日が経っている.挫折したアドベントカレンダーもそうだけど、やはり連載宣言はするものじゃない.自分のような興味関心がブレまくる人間が連載宣言をしても、宣言した時をピークにモチベーションは下がり続ける.インプットのためのアウトプット、所詮メモの大原則を忘れている.
非再帰的makeでgoogletestのテストコードを含むソースツリーを管理するMakefileを書いた
場当たり的なMakefileで管理しているC/C++のコードの規模(数千行程度)がそれなりに大きくなってきた.
テストがないので大きな変更がしんどい.
テストがないのでバグを踏んでも何が原因かは勘とprintfデバッグ、辛い.
もういろんなところでテストがまったくないなんてありえないと言われている.
テストがないコードは全てレガシーコード.
どうせならTDD実践したい.
Linux上で、エディタはvimで、コードはGitで管理して...
C/C++だからテスティングフレームワークはgoogletestにしよう.
規模がある程度大きくなるので、分割コンパイル.
TDDなので、テストを書いたらすぐ実行したい.
なるべく早くフィードバックが欲しいので、変更を加えたソースファイルに関連するコンパイルのみが走って、なるべく早くテストを実行したい.
条件に当てはまる開発環境は?みんなはどうしているの?
googletestを使ってみた系の記事はサンプルコード以上の記述がない.
TDDBCで使ってるのはVC++かな?
OSSプロダクトはAutotools?CMake?なんだか闇が深そう.
IDEの言いようのない裏で何やってるかわからない感.
ビルドプロセスは明確にしておきたい.
プレーンテキスト!!
テキストフィルタリング!!
CLI!!
黒い画面!!
etc...
と言った様々な想いとか趣味趣向などが交錯して、どうしても思い描いた開発環境が欲しくなって書いた.
Autotoolsから逃げて「巨人の肩に乗れ」という原則を思いっきり破っていて、やってて楽しい一方でモヤモヤした気持ちは今でも拭えてないけど、とにかく書いた.
もう環境を整えるのに時間かけたくないので、githubから落としてきたらすぐにでも始められるように小さなスクリプトも書いた.
Makefileと関連するシェルスクリプトをgithubに上げた.
https://github.com/doi-t/nonrec-make-with-gtest
続きを読むgoogletestを/usr/local/にインストールするシェルスクリプト
発声練習:Intel C/C++ を用いた Google Test環境を準備するを参考にしてgoogletestのセットアップを行うシェルスクリプトを書いた.
ホームディレクトリにソースを落としてきて、コンパイルした後に/usr/local/に必要なヘッダとライブラリをcpしているだけ.
cmakeが必要なので、なければ予めパッケージを落としてくる.
gtestを/usr/local以下にインストール/アンインストールするシェルスクリプト
googletest自体については、googletest入門ガイドが翻訳されている.
こいつを使ってTDDを実践したいんだけど、ビルドプロセスやテストの自動化で永久にyak shavingやってる、二年くらい.
2014/2/6追記:googletestに関して調べたことメモ
fused source files
エンジニアのソフトウェア的愛情:googletest1.5.0の使い方・その1:ビルドする
どうも、1.5.0からテストをビルドする度にgoogletestも再コンパイルせよという方針らしい.
エンジニアのソフトウェア的愛情:Google Testをインストール、しないですませる方法
それで、毎回再コンパイルするってどうすんのって話になる.
どれを使うの?って話は1.5.0から追加された「fused source files」で解決する.
リンク先にある通り、二つのソースと一つのヘッダをプロジェクトに絡めるだけで、テスト環境が手に入る.
手元の環境が仮想環境だった場合、コンパイルに時間がかかるのが辛い.
問題ないなら、/usr/local/にセットしたらライブラリのリンクですませたい.
googletest付属のサンプル
どうやって毎回再コンパイルするの?って話は同伴されているサンプルテストをビルドするMakefileを見ればわかる.
このMakefileの読み方とgoogletestについて素晴らしい解説を行っているエントリを見つけたのでメモ.
minus9dの日記:googletestに付属するサンプルを読み解く
リンク先ある解説図を見れば、/usr/local/以下にセットしたライブラリに何が含まれているかが一目瞭然.わかりやすいなぁ.
二十五日半狂乱、11日目(の分)の記事