C言語を手にLinuxの森を歩いてみる（手記）

基本的には以下の備考録です。

https://www.amazon.co.jp/%E3%81%B5%E3%81%A4%E3%81%86%E3%81%AELinux%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Linux%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B9%E3%82%8Bgcc%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E7%8E%8B%E9%81%93-%E9%9D%92%E6%9C%A8-%E5%B3%B0%E9%83%8E/dp/4797328355/ref=sr_1_1?ie=UTF8&qid=1491015235&sr=8-1&keywords=%E6%99%AE%E9%80%9A%E3%81%AElinux%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0


参考にしたもの
http://i.loveruby.net/ja/linuxprog/
http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=RHG%C6%C9%BD%F1%B2%F1%3A%3A%C5%EC%B5%FE+Revolution%3A%3A%A4%D5%A4%C4%A4%A6%A4%CELinux%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0
https://hydrocul.github.io/wiki/programming_languages_diff/etc/comment.html
http://itref.fc2web.com/c/preprocessor.html


#コンパイル

```
gcc [-o <出力ファイル>] <コンパイルするソース>
```


#標準ヘッダファイル
|ファイル名|説明|
|---|---|
|limits.h|実装に依存する値に関するヘッダファイル|
|stdio.h|標準入出力に関するヘッダファイル|
|signal.h|シグナルに関するヘッダファイル|
|stdlib.h|標準ライブラリに関するヘッダファイル|
|string.h|文字列操作に関するヘッダファイル|
|sys/types.h|システムに依存する変数タイプに関するヘッダファイル|
|iconv.h|文字コード変換ライブラリ(iconv API)のヘッダファイル|
|time.h|時刻操作に関するヘッダファイル|
|unistd.h|UNIX標準に関するヘッダファイル|
|wchar.h|ワイドキャラクタに関するヘッダファイル|


#コメント

```
// 単一行コメント
/*
  複数行コメント
  複数行コメント
*/
```

#ストリームの読み書き

##read(2)
ファイルディスクリプタfd番のストリームからバイト列を読み込むシステムコール

```
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t bufsize);
```

##write(2)
bufsizeバイト文をbufからファイルディスクリプタfd番のストリームに書き込む

```
#include <uninstd.h>
ssize_t write(int fd, const void *buf, size_t bufsize);
```

##open(2)
指定したファイルに繋がるストリームを作成し、そのストリームを指すファイルディスクリプタを返す

```
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *path, int flags);
int open(const char *path, int flags, mode_t mode);
```

##close(2)
ファイルディスクリプタfdに関連づけられているストリームを始末する

```
#include <unistd.h>

int close(int fd)
```

##perror(3)
errnoの値に合わせたエラーメッセージを標準エラー出力に出力します。

```
#include <stdio.h>

void perror(const char *s);
```

#アドレス空間の構造

|領域|説明|
|---|---|
|テキスト領域|機械語のプログラムのこと。|
|データ領域|グルーバル変数や関数内のスタティック変数のうち初期化済のもの、それに文字列リテラルなどが置かれます。|
|BSS領域|グローバル変数や関数内のスタティック変数のうち初期化が必要ないものが置かれます。実行ファイルではこの領域はサイズだけが記録してあります。|
|ヒープ領域|malloc()が管理する領域。この領域は実行時に拡大・縮小する可能性があります。|
|スタック領域|関数呼び出しに関連したデータを置くところ。例えば関数の引数やローカル変数などが置かれる。スタックと呼ばれるのは、名前の通りスタックとして使用されるから。|

C言語でメモリを確保する方法

1. ビルド時にわかっているサイズをBSSから確保

1. ビルド時にわかっているサイズを実行時にスタック領域から確保

1. 実行時に決まるサイズをヒープ領域から確保

1. 実行時に決まるサイズをスタック領域から確保


#ビルド

|name|description|
|---|---|
|プリプロセス|#include, #ifdef, #defineを処理して純粋なC言語のソースコードを出力する。|
|コンパイル|C言語のソースコードをアセンブリ言語のソースコードに変換する。|
|アセンブル|アセンブリ言語のソースコードを機械語を含むオブジェクトファイルに変換する|
リンク|スタティックリンクでは必要な関数が静的ライブラリから取り出され、生成するプログラムに物理的に連結されます。ダイナミックリンクではビルド時には最終的なコード結合までは行わない。ビルド時には必要な関数が存在するかをチェックするのみで、実行開始時にリンクローダが実行ファイルと共有ライブラリから関数を持ってきて、メモリの上で最終的にコードを結合する。|


#プロセスの環境

##カレントディレクトリ

##クレデンシャル
set-uidプログラムから起動されたプロセスには、2種類のクレデンシャルが存在する

|ユーザ|description|
|---|---|
|プロセスを起動したユーザ（グループ）|実ユーザ（グループ）ID（real user/group ID）|
|set-uidプログラムのオーナー（グループ）|実効ユーザ（グループ）ID（effictive user/group ID）|

|command|description|
|---|---|
|getuid()|自プロセスの実ユーザIDを返す|
|geteuid()|自プロセスの実効ユーザIDを返す|
|getgid()|自プロセスの実グループIDを返す|
|getegid()|自プロセスの実効グループIDを返す|


##環境変数

##使用リソース