昨日の俺 「知らんかった……( ゚д゚)ポカーン」
C言語のmain関数には引数が”3つ”存在する。
大体Cの入門書は int main() とかだし、ちょっと毛が生えてきて、引数を取って挙動を変えましょうとかだと、argc, argv を取るだけだと思うし、sublime TextのCのsnippet もargv までしか補完してくれないし、envp ってなんやねんΣ(゚Д゚)
crt1.cには以下のように書かれている。
extern int main (int, char **, char **);
この3つめの引数が いわゆるenvp で、"環境変数へのポインタ"らしい。 環境変数はbashやzshで
$ set
というコマンドで確認できる。いわゆる$PATHとかの事。 実際に引数を確認するプログラムを作成してみましょう。
#include <stdio.h> int main(int argc, char *argv[], char *envp[]) { int i = 0; /* argc の確認 */ printf("argc = %d\n", argc); /* argv の確認 */ printf("argv = ["); for (i = 0; i < argc; i++) { printf("\'%s\' ", argv[i]); } printf("]\n"); /* envp の確認 */ printf("envp = ["); for (i = 0; envp[i]; i++) { printf("\'%s\' ", envp[i]); } printf("]\n"); return 0; }
で、実行結果ですが、
./a.out argc = 1 argv = ['./a.out' ] envp = ['TERM_PROGRAM=iTerm.app' 'TERM=xterm-256color' 'SHELL=/bin/bash' 'CLICOLOR=1'......(非常に汚い環境変数なのでお見せできません笑
となりました。環境変数は必ず hoge=piyo foo=bar という文字列で格納されているので、strtok関数などで分解してやると扱いやすいと思われます。
これは便利だ!!
PWDやHOMEなどの環境変数も入っているので、HOMEフォルダにアプリケーションの設定ファイル.ore_rcみたいなのを置けます。また、envpはfork/execしても変更されず引き継げますので(※要調査。変数をそのまま引き継ぐわけではなく、envpが格納されているメモリがexecにより書き換えられない?)
8年近く、Cのmain関数は引数2つだと思い込んでいたので、非常に勉強になりました。というか、反省しています。常識を疑うって大事(白目