C言語
C言語をやってみよう,ふと思い立った.かなり久しぶりだ.大学当時Cは講義であった.学生時代怠けまくった結果(?)私はCよりも,趣味でやっていたJavaの方が書いたコードの行数は多い.だが,やはり「たしなみ」としてC言語はやっておかねばなるまい.
とりあえず,ライブラリにある関数をいろいろ試してみる.もちろん(?)Debian環境で.
GNU/Linuxシステムでのファイル操作について.ここでは特にシステムコールを用いてファイル操作する方法について.
標準入出力ライブラリを使用するとファイル操作がしやすく,バッファリングなども効くので便利である.
標準入出力ライブラリによるファイル操作についてもっと.
printf族とscanf族による書式付き入出力と,入出力時のエラーについて.
コマンドライン引数を取得する方法と,それを簡単に行なうライブラリ関数getoptについて.
関数getopt_longは長い形式のオプションの取得に便利な関数である.これはGNU拡張らしい.長いオプションは大抵--で始まる.
HOMEやUSERなど,環境変数に応じた処理をしたくなることもあろう.なので,環境変数を取得したり設定したりできると嬉しい.
プログラムによっては日付や時刻を取得する必要がある.コンピュータで日付や時刻を操作する場合は,「エポックの起点」からの経過秒(もしくはミリ秒)をもとに行うことが多いようだ(もちろんlocaleも考慮する).「エポックの起点」はシステムによるが,UNIXではGMT 1970年1月1日0時らしい.epochを辞書で引いてみたら,「ある特徴のある時代」らしい.ネットで調べると,「基準時刻」と訳してあったりする.こちらの方がわかりやすいだろうか.
ユーザ情報というと,アカウント名,uid,gidなどである.これらの情報が実際のプログラミングでどう使用されるのかは,ちょっとわからないが,取得できないよりはできるほうがいい.
プログラムを実行しているマシンの各種情報の取得の仕方.
syslog関数によるロギングについて
プログラムを実行する際のリソース情報(とくにリソースの制限)を取得する必要がある場合がある.
time関数やsleep関数は秒単位でしか処理できないが,ミリ秒とかマイクロ秒とか,より高精度な処理をしたいときのための関数,gettimeofdayとnanosleepを試してみた
プロセスがプロセスを生んで殺してまた生んで.....そして死ぬ.
関数systemによる,もっとも簡単なプロセスからプロセスを生む方法.
実行中のプロセスを新しいプロセスで置き換える.したがって新しいプロセスのPIDやniceなどはexecを実行したプロセスと同じである.あと,ファイルディスクリプタなどもexec元がオープンしていれば,新しいプロセスでもオープンされている.ディレクトリストリームはクローズされるらしい.execではshell経由での起動ではないので,shellの展開機能は使用できないが,shell起動のオーバーヘッドはない.
forkはプロセスのコピーを作成する.そしてwaitで待つ.処理の流れが一本から複数に分かれる様がフォークみたいだからforkなのだろうか.
シグナルを使うとイベント駆動でいろいろできる.
まずは基本.BASHでいうとtrapになるだろうか.
受信の方法がわかったところで今度は送信してみる.シグナルの送信には,raiseとkillがある.raiseは自分自身にシグナルを送信する関数である.killはコマンドkillと同等の機能をもつ関数である.
sigaction関数はsignal関数よりもより細かい制御ができる.sigactionはX/Open仕様ではsignalよりも信頼できるとして推奨しているらしい.
人は一日何回コマンドラインでパイプを使用するのだろうか.ここではCでパイプを使用する方法について記述する.
パイプのopenとclose.
popenとpcloseがsystem関数のパイプ版だと考えると,pipeはexecのpipe版と考えられるだろうか.
FIFOは名前付きパイプらしい.パイプがファイルで嬉しくなる.
IPCはInterProcess Communicationの略でSystem V IPCと呼ばれ,SVR2で導入されたらしい(man 5 ipc参照).なんかipc()というハッカー向けの関数(システムコール)もあるようだ(man 2 ipc参照).で,IPCではシグナルやパイプに代わるプロセス間通信の方法として以下についての機能を提供している.
- セマフォ
- 共有メモリ
- メッセージキュー
共有メモリの話題に入る前の準備としてセマフォについて記述する.
共有メモリもセマフォと同じ雰囲気で取得,設定,操作する.
メッセージキューはパイプとより扱いが簡単でちょっと嬉しい.
Pthreadを使用してマルチスレッドプログラミングをしてみた.
まずはスレッドを生成してみる.
スレッドのデタッチと合流について調べてみた.
スレッド属性について調べてみた.
スレッドの同期には,pthread_joinによる合流の他に,ロックという方法がある.
ロックで基本的な同期は実現できるが,限界がある.より高度な表現でより高度な同期を実現するための関数があるようなので,試してみた.
マシンがネットワークにつながってないと寂しくて不安なので,つなげたい.
まずsocket関数とプロトコルとアドレスについて記述しておく.
PF_UNIXでソケット通信してみる.
PF_INETの前にネットワーク情報について記述してみる.
PF_INET,SOCK_DGRAMでソケット通信してみる.
selectを使用して複数のファイルディスクリプタからの入出力を制御
端末を制御してUIを良い感じにしたいときもあろう.
処理によっては普通にgetcharするとCRを読み込んじゃって困ることがあるかもしれない.
出力がリダイレクトされているかどうかを調べる.これはファイルディスクリプタをチェックすればわかる.
termiosは「非同期通信ポートを制御するための汎用ターミナルインタフェース」らしい.端末をclearしたりechoを抑制したり非カノニカルモードにしたりできる.
terminfoを使用すると出力場所とかをイイ感じにできるかもしれない.
cursesはviやカーネルのmake menuconfigなどで使用されている,アレ(どれ?)である.CUIで画面制御したいときに使用する.
何はともあれウィンドウを出してみる.
cursesの多くの関数のうち,基本的なものを紹介する.
出力文字には強調表示やアンダーラインなどの属性を付加することができる.
termiosやterminfoでやったことと同様のキーボード入力制御ができる.
cursesでは複数のウィンドウを作成,操作できる.あとサブウィンドウも作成,操作できる.
多くの端末では,ESCキーや矢印キーなどを押すとエスケープシーケンスが送信される.これを処理してみる.
cursesでは画面をスクロールさせたりもできる.
ウィンドウは物理画面や親ウィンドウの範囲内に収まっていなければならない.パッドとはそのような制約なしに自由な大きさで作成できる論理画面である.
ncursesではマウスの操作を検知できるらしい.ただしSVr4以前とか4.4BSD以前ではできないようだ.
CUnitはCプログラムのためのテスティングフレームワークであり,ユニットテストに便利そうなので試してみた.
CUnitはLGPLなC言語プログラムのためのテスティングフレームワークらしい.
CUnitでのテストの作成から実行,レポートの閲覧まで,ざっと試してみた
CUnitではテストスィートを実行する前の初期化関数とクリーンアップ関数が登録できるようなので,試してみた.
OpenSSLを使用するとセキュアな通信ができたり,証明書を作ったり署名したりできるようだが,その足回りとして暗号化関数などがあるようなので,その辺から始めて,SSL通信までざっと試してみたい.
OpenSSLにはDES暗号化する関数が提供されている.これにはいろいろなバリエーションがあるようだが,良くわからないので,とりあえずメジャーそうな3DESを試してみる.
OpenSSLにはRSAのキーペアを作成し,これを使用して暗号化,復号する機能や,キーをPEM形式で入出力する機能があるのでためしてみた.
BIOはOpenSSLにおけるフレームワークにおける抽象データ型で,暗号化や符号化,ファイルやネットワークといった入出力の詳細をアプリケーションから隠蔽する.で,このフレームワークのもとで実装されているBase64コーデックを試してみた.
C言語に関してのその他のトピックを記述してみる.
GNU RreadlineはCUIに劇的な利便性をもたらす偉大なライブラリでありながら,これを使用するプログラムを作成したことがないので,作成してみた.
libsafeはCの標準関数のうち,よくバッファオーバーフローを起こすものを差し替えてバッファサイズをチェックする処理をしてくれるらしいので試してみた.
自作のアプリケーションでデータを圧縮解凍したいと思うことがたまにある.zlibを使用すると簡単にzip圧縮と解凍ができるようなので試してみた.
bz2はメモリを喰うがzlibより圧縮効率がよいらしいので,そのライブラリbzlibを試してみた.

