こんにちは。
最近、ふつうのLinuxプログラミング 第2版を読んでいるので知識の定着のために学んだ内容を要約したメモを書きます。
このエントリは完全な個人のメモです。
お勉強のためにこの本を読んでいるので、内容を覚えるためにSummarizing(サマライジング)を行います。
第1章 Linuxプログラミングを始めよう
Linuxの世界(ユーザランド)を構成する三大要素
・ファイルシステム
・プロセス
・ストリーム
Linuxはユーザランドとカーネルランドに2分される。
この3つの概念は主にユーザランドを構成する要素になる。
Linuxはコンピュータを抽象化してユーザに提供するが、抽象化された世界がユーザランド、抽象化されたコンピュータを提供するのがカーネルランド(いわゆるカーネル)。
本の構成
この本は大まかに3部構成になっています。
それぞれの内容は以下。
第1部 Linuxの仕組み(第1章~4章)
第2部 Linuxプログラミングの根幹(第5章~第14章)
第3部 Linuxネットワークプログラミング(第15章~18章)
対象読者
・プログラミングを通してLinuxの仕組みを学びたい
・LinuxやUNIXプログラミングの本を読んで挫折した
・C言語の基本構文を覚えたからLinuxプログラミングを学びたい
必要なスキル
・C言語で簡単なプログラムが書ける
・Linuxでエディタが使える
・Linuxの基本的なコマンドが使える
対象のディストリビューション
基本的には特定のディストリビューションに依存しない。
ディストリビューション固有の話になる場合はUbuntu 16.04およびCent OS 7の環境を用いる。
その他
環境の準備やgccを使ったビルドの仕方、manコマンドの説明など。
第2章 Linuxカーネルの世界
オペレーティングシステムとは
OSについての厳密な定義は定まっていない。
Linuxに関して言えば、OSには以下のようなパッケージが含まれている。
・シェル
・util-linux
・procps
・GNU libc
・各種基本ライブラリ
・開発環境
・X Window System
・GNOMEやKDE
などなど。
我々が普段「Linux」として購入したりダウンロードしているものはOSではなく「ディストリビューション」と呼ばれるもの。
カーネル
この本で言うLinuxの世界とは、カーネルが作り出す世界のこと。
Linuxではこのカーネルがすべてのハードウェアとソフトウェアを管理している。
ルートディレクトリでlsコマンドを実行するとvmlinuzやvmlinuxといった名前のファイルがあるが、これがLinuxカーネルのプログラム本体。
通常「Linux」というとOSのことを指すが、厳密にはこのカーネルのことを指す。
「Linux OS」や「Linuxカーネル」と記載を明示的に分けることもある。
デバイスドライバ
カーネルはCPU、メモリ、HDD、時計などのデバイスを全て統括している。
しかし、CPUやHDDには多くの種類が存在し、それぞれ操作方法も異なる。
全てのハードウェアにカーネルが対応するのは不可能なので、デバイスを操作する部分はカーネルから独立させて交換可能にしておく必要がある。
この、それぞれのデバイスの操作を操作するためのソフトウェア部品のことを「デバイスドライバ」または「ドライバ」という。
システムコール
Linuxではハードウェアを直接操作できるのはカーネルのみ。
プログラムからハードウェアを操作したい場合はカーネルに操作を依頼する。
プログラムがハードウェアを操作するために提供されている仕組みがシステムコール。
システムコールには以下のようなものがある。
・read
・write
・open
・close
など。
この本では、このシステムコールを通してストリームやプロセスを学び、Linuxの理解を深めていく。
ライブラリ
プログラマはシステムコール以外にもライブラリ関数を使うことができる。
ライブラリ関数を使うためには「リンク」という作業が必要。
「リンク」の詳細については11章を参照。
標準ライブラリで特によく使われるのが「標準Cライブラリ(通称libc)」と呼ばれるもの。
API
そもそもAPIとは何か?
APIとはApplication Programming Interfaceの略で、何かを使ってプログラミングするときのインターフェイスのことを指す。
例えば、CライブラリのAPIは関数やマクロで、カーネルのAPIはシステムコール。
API=システムコールというわけではない。
※以下、参考
厳密にいうと、カーネルが提供しているのはABI(Application Binary Interface)である。
API:ソースコードとライブラリ間のインターフェイスを定義したもの。ビルド時にソースコードと一緒にコンパイルされる。
ABI:バイナリオブジェクト単位でインターフェイスを提供しているもの。
詳細はWiki参照。
第3章 Linuxを描き出す3つの概念
Linuxの3大要素
この章の内容は、Linuxを構成する3大要素の説明。
・ファイルシステム
・プロセス
・ストリーム
ファイルとは
linuxでlsコマンドを打ったら出てくるものはすべて「ファイル」。
テキストファイルのようなものは当然、ディレクトリやシンボリックリンクもファイル。
ファイルには以下のようないくつかの種類が存在する。
・普通のファイル(テキストファイルや画像ファイルなど)
・ディレクトリ
・シンボリックリンク
・デバイスファイル(ハードウェアをファイルとして表現したもの)
・名前付きパイプ
・UNIXドメインソケット
など。
全てのファイルは名前で指定することができる。
名前で扱うことができるのは非常に重要な特性。
/proc配下とか見てみると勉強になるはず。
カーネルが提供している統計情報などが見れる。
ファイルの付帯情報
ファイルには以下のような付帯情報が含まれる。
・ファイルの種類
・パーミッション
・サイズ
・更新時刻
など
ファイルシステムとマウント
ファイルシステムはHDDやSSDといった物理的な記憶媒体の上に存在している。
SSDやHDDの場合、ディスクを「パーティション」に区切り、それぞれのパーティションにファイルシステムを用意して「マウント」することで1つのディレクトリツリーを構成する。
mountコマンドを使用すると現在使用しているファイルシステムを見ることができる。
ファイルシステムはext4やxfs、btrfsなどいくつも種類がある。
疑似ファイルシステムといわれるものも存在するが、疑似ファイルシステムについては第9章を参照。
プロセスとは
プロセスとは、端的にいうと動作中のプログラムのことを指す。
1つのプログラムを複数同時に動かすこともできるので、プロセスにはプロセスIDと呼ばれる番号が振られている。
プロセスIDを使うことで、プロセスを一意に特定することができる。
シグナル送信時などに使用する。
シグナルについては第13章を参照。
ストリームとは
ここでいうストリームはバイトストリームを指す。
バイトストリームとは、バイト列(データ)が流れる通り道のこと。
たとえば、プロセスからファイルにアクセスしたい場合、カーネルにファイルと繋がるストリームの作成を依頼する。
プロセスはそのストリームを操作してファイルの中身を読み書きする。
また、SSDやHDD、キーボードなどのハードウェアも普通のファイルと同様にストリームで扱うことが可能。
パイプもプロセスとプロセスをつなぐストリーム。
ネットワーク通信もストリーム。
パイプやネットワーク通信など、プロセス同士がストリームを通してデータのやり取りをすることをプロセス間通信という。
第4章 Linuxとユーザ
マルチユーザシステム
Linuxはマルチユーザーシステムを採用している。
マルチユーザーシステムとは、複数人で1つのシステムを同時に使用することができるシステムのこと。
ユーザ名とパスワードを入力し、ログインすることでLinuxの機能を使えるようになる。
権限の分割
Linuxではマルチユーザーシステムとファイルシステム側の設定(パーミッション)を組み合わせることで、ユーザが変更可能なファイルを制限することができる。
全ての権限を持つユーザをスーパーユーザ(通常root)という。
ユーザーは最低でも1つのグループに属する。
パーミッションは以下の3つに対してそれぞれ設定可能。
・ファイルを所有するユーザー
・ファイルを所有するグループに所属するユーザー
・それ以外のユーザー
権限の種類は以下の3つ。
・読み込み
・書き込み
・実行
ディレクトリのパーミッション
ディレクトリのパーミッションは通常のファイルとは少し異なる。
・読み込み可能な場合、ファイル一覧を取得可能
・書き込み可能な場合、新しいファイルを作成可能
・実行可能な場合、中のファイルにアクセス可能
アクセスとは、読み書き実行すべてが可能な状態を指す。
クレデンシャル
「ユーザA」がファイルにアクセスする=「ユーザAの属性を持ったプロセス」がファイルにアクセスする、ということ。
プロセスが持つユーザ属性のことをクレデンシャルという。
ユーザIDやグループの情報は/etc/passwdや/etc/groupに記載されているが、基本的にはAPIを使って参照する。
専用APIについては第14章を参照。
端末とは
コンピュータのハードウェアのうち、人間が直接操作する部分を端末と呼ぶ。
昔は1台のコンピュータを複数人で同時にしようしていた。
なので、大本のコンピュータには特にディスプレイやキーボードなどはなく、それに「端末」を接続して人間がコンピュータの機能を使用するといった形式だった。
UNIX黎明期テレタイプというものが主流で、コンピュータからの出力は紙に打ち出され、コンピュータへの入力はテープやタイプライターが使用されていた。
UNIXでは端末のことを「tty」と呼ぶこともあるが、それはこの時の名残。
最近は端末というと、端末エミュレータのことを指すことが多い。
仮想コンソール
Linuxでは物理的な端末がそのまま使用されるのではなく、間に仮想コンソールというものが挟まる。
「コンソール」は「端末」とほぼ同義。
Ubuntuとかで端末を複数開けるのは、実は仮想コンソールを使用しているから。
X Window SystemではXが端末を1つ占有する。
ファイルとしての端末、ストリームとしての端末
UNIXでは、いろいろなものをファイルとして表現しているという特徴がある。
端末も例外ではなく、/dev配下に端末に対応するデバイスファイル(/dev/tty0、/dev/tty1など)が用意されている。
端末をファイルとして扱うことにより、ファイルに接続したストリームを得ることができる。
そのストリームからキーボードからの入力を受け取ったり、ストリームからディスプレイに文字を出力したりすることができる。
シェル
ユーザからの命令を解釈して実行するプログラムのことをシェルという。
代表的なものに、以下のようなものがある。
・bash
・sh
・csh
・tcsh
・zsh
など。
シェルはログイン時に起動されるという点では少し特殊だが、シェルそのものはストリームからコマンドを読み込んで実行するプログラムに過ぎない。
ストリームが端末につながっている場合、シェルは「$」や「%」のようなコマンドラインプロンプトを出力する。
その他
ASCIIコードの話など。
改行やベル、バックスペースなどにも文字コードが割り当てられている。
第1章~第4章は大体こんな感じです。
続きはこちら。
おわり。