まずB.G-STATIONとは何ぞや

B.G-STATION Advent Calendar 2017 1日目です。
adventar.org

まずは何ぞやって話です

まあ、B.G-STATIONは、僕が以前から運営していたというか運営しているサイトであり、同人個人サークル名でもあります。
B.G-STATION
車輪のx発明 ~B.G's Blog~

代表は僕であり、メンバーも僕だけですね。
(ちなみに、コミケでうちのスペースにもう一人座ってることがありますが、小学校からの友人でサーチケ代わりに午後店番とかやってもらってるのです。)

ホームページB.G-STATIONの誕生

高校の時に、科学部物理班という部活に入りました。
当時、コンピュータ教室が無かったのですが、理科講義室からPCの音が聞こえてました。
顧問の先生はロボット製作をしてて、僕らもそれをやってたこともあるのですが、先輩達は改造PC9821αにVisualBasic6を入れてゲームを作っていました。
それがプログラミングとの出会いでした。
僕もVB6+Win32でゲームを作ろうとしていましたが、割とすぐ挫折しました。
そして当時、家でCATVを導入したことで、インターネットができるようになりました。
ホームページスペースで最初に作ったホームページが初代のB.G-STATIONです。

B.G-STATION

これは初代じゃないですが、現存しているサイト・・・。ジオシティーズだから三代目かな・・・。
描いたイラストや作ったゲームを載せる予定でした。
イラストは載せましたが、ゲームは完成することがなかったので載せることはありませんでした。

同人ソフトサークルB.G-STATIONの設立

大学に入学した後、ゲーム製作関係のサークルに入りたくて、気になっていたAmusementMakers(以下AMと略します。)に入りました。

Amusement Makers

当時、東方紅魔郷とかでZUNさんとかが話題になり始めてた頃でした。
しかし、僕自身、東方シリーズは全く知らなかったし、AM出身とは全く知りませんでした。
また、TYPE-MOON月姫とか、葉鍵とか、ちょっとあとですがひぐらしがまだフリーウェアだった時代でもあります。

AMではノベル班に所属していました。
未来の描き方という同人ゲームがあったのですが、
ごく初期に背景を担当していました。というか正確にはする予定でした。
未来の描き方 - Google 検索
グラフィックを担当したのがいまや有名イラストレーターのカ〇トクさんで、彼のあまりのレベルの高さにレベルの低い僕が降りたというか降ろされたというかいろいろあってやることがなくなりました。
画力アップも兼ねて漫研にも入っていました。

並行して個人でゲーム作ってコミケで頒布しようとC66からコミケに申し込み始めました。
それが同人サークルとしてのB.G-STATIONです。

その後

C++ + DirectXでゲームを作り始めたのですが、挫折の連続・・・。
現在まで完成したものはありません・・・。
ああ・・・ダメすぎる人生・・・orz

卒業後も会社で忙しくしている間に、時代はC++ + DirectXからC# + Unityに・・・。
でもWin32APIにこだわりすぎてすっかり取り残されてしまいました。

同人誌を作ることもありました。いや、あの聖痕のクェイサー本は本当に黒歴史というか・・・。

そんな中、WindowsMobileからWindowsPhoneにハマり、廃れ・・・。

これから

そして今、また新たなスタイルでこのサークル及びサイトをやってるわけです。
どんなスタイルで何するのかって?
それを次回から書いていきます。

nullptr

C++11からは、ポインタへのNULLのセットは、nullptrを使うことが推奨されている。

nullptr - cpprefjp C++日本語リファレンス

nullptr.cppで、

intとconst char *を引数とするfuncがある。

値、指定された文字列をそれぞれ出力するだけ。

  // 0とNULLの場合.
  func(0); // 0を出力.
  func(NULL); // NULLを出力.(この環境では, 呼び出しが曖昧ということでコンパイルエラーになった.)
  func(nullptr); // C++11ではnullptrを推奨.

こうすると、

$ vi nullptr.cpp 
$ g++ nullptr.cpp -o nullptr -std=c++11
nullptr.cpp: 関数 ‘int main()’ 内:
nullptr.cpp:20:12: エラー: オーバーロードされている ‘func(NULL)’ の呼び出しが曖昧です
   func(NULL); // NULLを出力.(この環境では, 呼び出しが曖昧ということでコンパイルエラーになった.)
            ^
nullptr.cpp:5:6: 備考: candidate: void func(int)
 void func(int val); // オーバーロード関数func(int val)
      ^~~~
nullptr.cpp:6:6: 備考: candidate: void func(const char*)
 void func(const char *ptr); // オーバーロード関数func(const char *ptr)
      ^~~~
$ 

このように曖昧なのでコンパイルエラー。

こうすると、

$ vi nullptr.cpp 
$ g++ nullptr.cpp -o nullptr -std=c++11
$ ./nullptr 
val = 10
ptr = ABC

だったり、

val = 0
ptr = $

だったり、コンパイルして実行できる。

Sample/cpp/nullptr/nullptr/src/nullptr at master · bg1bgst333/Sample · GitHub

ioctl

ioctlは、デバイスを制御するのに使う。

Man page of IOCTL

今回は、ネットワークデバイスであるNICからIPを取得する。

ioctl.cで、

インターフェース名を入力。
ioctlでSIOCGIFADDRを送る。
成功するとstruct ifreq型のsifrに情報が格納される。

$ ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::3b07:5151:e763:f8b0  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:75:6b:bc  txqueuelen 1000  (Ethernet)
        RX packets 60323  bytes 13211145 (12.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 60397  bytes 8129752 (7.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 20  bytes 1720 (1.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20  bytes 1720 (1.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ vi ioctl.c 
$ gcc ioctl.c -o ioctl
$ ./ioctl 
interface_name: enp0s3
enp0s3 ip address = 10.0.2.15
$

IPが出力された。

Sample/unixsyscall/ioctl/ioctl/src/ioctl at master · bg1bgst333/Sample · GitHub

msync

msyncでメモリマップの内容に合わせてファイルを同期する。

Man page of MSYNC

msync.cで、

"test.txt"を開いたら、内容を"VWXYZ"に書き換えて、msyncで同期する。

$ ls
msync  msync.c  test.txt
$ vi msync.c 
$ gcc msync.c -o msync
$ vi test.txt 
$ cat test.txt 
ABCDE
$ ./msync 
sst.st_size = 6
page_size = 4096
memory_map_size = 4096
$ cat test.txt 
VWXYZ
$

"ABCDE"が"VWXYZ"に書き換えられた。

Sample/unixsyscall/msync/msync/src/msync at master · bg1bgst333/Sample · GitHub

mmap

mmapは、ファイルの内容をメモリにマッピングすることで高速にアクセスできる。

Man page of MMAP

mmap.cで、

ファイルサイズを取得し、メモリのページサイズも取得し、メモリマップサイズを計算。
"test.txt"を開いて、メモリにマッピング
メモリマップの中身を出力したら、アンマップして閉じる。

$ ls
mmap  mmap.c  test.txt
$ cat test.txt 
ABCDE
$ vi mmap.c 
$ gcc mmap.c -o mmap
$ ./mmap 
sst.st_size = 6
page_size = 4096
memory_map_size = 4096
-----begin-----
ABCDE

-----end-----
$

メモリ上にマッピングされた。

Sample/unixsyscall/mmap/mmap/src/mmap at master · bg1bgst333/Sample · GitHub

isatty

isattyは、ファイルディスクリプタが端末を参照しているかどうかを返す。

Man page of ISATTY

わかりにくいので補足すると、ファイルディスクリプタの出力先が標準出力であれば、端末は参照されていると言えるし、
リダイレクトなどで、ファイルなどに出力される場合は参照されていない。

isatty.cで、

isattyが1なら、標準出力、0なら、リダイレクトという形で判定できる。

$ vi isatty.c 
$ gcc isatty.c -o isatty
$ ./isatty 
ABCDE
ABCDE
ABCDE
ABCDE
ABCDE
$ ./isatty > test.txt
$ cat test.txt 
-----header-----
ABCDE
ABCDE
ABCDE
ABCDE
ABCDE
-----footer-----
$

リダイレクトの場合は、headerとfooterが付いているので、ちゃんと判定できてる。

Sample/unixsyscall/isatty/isatty/src/isatty at master · bg1bgst333/Sample · GitHub

fileno

filenoは、指定されたファイルポインタの指すストリームのファイルディスクリプタを返す。

Man page of FERROR

stdio.hだが、標準関数一覧には何故かない。
fileno.cで、

stdin, stdout, stderr, そして新たに開いた"test.txt"のファイルディスクリプタを出力。

$ vi fileno.c 
$ gcc fileno.c -o fileno
$ ./fileno 
fileno stdin = 0
fileno stdout = 1
fileno stderr = 2
fileno fp = 3
$

0, 1, 2, 3, と割り振られている。

Sample/unixsyscall/fileno/fileno/src/fileno at master · bg1bgst333/Sample · GitHub