53ningen.com

@gomi_ningen's Website

struct と typedef struct

struct と宣言すると変数宣言のときに struct struct_name variable_name という形で書かないといけない。たとえば以下のような感じ。

#include <stdio.h>
#include <stdlib.h>

struct hoge {
    int fuga;
};

int main(int argc, char *argv[]) {
    struct hoge h;
    h.fuga = 1;
    printf("%d\n", h.fuga);
    exit(0);
}

もし struct hoge h ではなく hoge h と書いたら以下のようにエラーがでます。

$ make
mkdir -p bin
gcc ./src/main.c -o ./bin/main -Wall
./src/main.c: In function ‘main’:
./src/main.c:9:5: error: unknown type name ‘hoge’
     hoge h;
     ...
Read More

関数の引数の void

引数を取らないことを表明するために func_name(void) と書くのと func_name() と書くのは何が違うのか。違いを観察してみる。

何もかかないとき

次のようなコードをコンパイルすると通ってしまう。

#include <stdio.h>
#include <stdlib.h>

void do_nothing() {
}

int main(int argc, char *argv[]) {
    do_nothing("hoge");
    exit(0);
}

コンパイルして実行してみる。

$ make
mkdir -p bin
gcc ./src/main.c -o ./bin/main -Wall
$ ./bin/main
$

引数を void とした場合

#include <stdio.h>
#include <stdlib.h>

void do_nothing(void) {
}

int main(int argc, char *argv[]) {
    do_nothin...
Read More

C 言語のダイグラフ

C 言語にはダイグラフとよばれる環境により存在しない記号の代替となる記法を提供している。2 文字のトークンで 6 種類ある。

  • <: => [
  • :> => ]
  • <% => {
  • %> => }
  • %: => #
  • %:%: => ##

例えば、以下のような簡単なソースコードがあったとする。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int hoge[] = { 123 };
    printf("%d\n", hoge[0]);
    exit(0);
}

これは普通に動作するコードです。

$ mkdir -p bin
gcc ./src/main.c -o ./bin/main -Wall
$ ./bin/main.c
123

このソースコードをダイグラフを使ったものに差し替えてみる。

%:include <stdio.h>
%:include <s...
Read More

arping コマンドを実装する (1)

arping コマンドを実装した経験がなかったので、実装コードをカンニングしながらエッセンスを抽出して、動く簡易 arping コマンドを実装していきます。

参考にする arping の実装

手元環境の arp のパッケージを以下のようにして確認します。

$ rpm -qf /sbin/arping
iputils-20121221-7.13.amzn1.x86_64

というわけで、iputils の実装を参考にします。

$ git clone git@github.com:iputils/iputils.git
$ cd iputils
$ vi ./arping.c

arp の様子をみる

ARP は IPv4 アドレスと MAC アドレスの対応を確認するためのプロトコルで、例えば 192.168.2.128 にリクエストを送ろうとしたとき、それに対応するイーサネットフレームの宛先 MAC アドレスが知りたくなります。

初めて送る相手の場合 IPv4 アドレスに対応する MAC アドレスは当然わからないので ARP Requ...

Read More

ping コマンドを実装する (1)

ping コマンドを実装したことがなかったのでやっただけの記録です。

実際には「ソースコードで体感するネットワークの仕組み」という本のファーストステップとして仮想 IP ホストの実装があるのですが、その前に ping クライアントを実装しておくとスラスラすすみそうだなと思ったので、やってみました。

わたしは邪悪な人間なのでまず最初にカンニングします。ping のソースコードを次のような手順で手に入れました。

$ rpm -qf /bin/ping
iputils-20121221-7.13.amzn1.x86_64

$ yumdownloader --source iputils
Loaded plugins: priorities, update-motd, upgrade-helper
Enabling amzn-updates-source repository
Enabling amzn-main-source repository
Enabling epel-source repository
amzn-m...
Read More

Hello, World カーネルモジュール

超技術書典で買った LINUX カーネルモジュール自作入門 を参考にしつつ、自作カーネルモジュールの Hello, World までをやってみました。参考書籍として Linux カーネル Hacks なんかも参照しながら、カーネルまわりに入門した。

  • Linux カーネルはモノリシック
  • ただしモジュール機能がある
    • ファイルシステム、デバイスドライバなどはモジュール単位でカーネル空間に動的に追加・削除が可能
    • Linux カーネル空間に動的に組み込み可能なバイナリ入るは .ko の拡張子を持つ
  • カーネルモジュールの作成方法は以下の 2 通り   - カーネルソースツリーに含まれる機能をモジュールとして作成する   - 独自機能をモジュールとして作成する

以下では独自カーネルモジュールを作成してみる

[amazon template=wishlist&asin=4873115019]

環境と...

Read More

ファイルを open したまま各種システムコールを呼び出すとどうなるか

会社にて、インフラ屋さんからアプリケーション屋さんまでわりと多分野の数人が集まって「ふつうの Linux プログラミング」という本を輪読しています。各章、それぞれのメンバーが知っていることと知らないことがうまくばらけていて、良い輪読になっています。

また、分野違いの人ならではの視点からの疑問や知識が輪読中に飛び出してきて、なかなか有意義です。業務経験〜10 年くらいの人たちで寄ってたかって読むと良い本ではないかなと思いますので、ぜひ読んでみてください。

[amazon template=wishlist&asin=4797386479]

さて、この本の第 10 章の練習問題には「ファイルを open() して、close() する前にそのファイルを rename() すると何が起きるでしょうか。unlink() はどうか、別のファイルを rename() するとどうなるか、実験して調べなさい」(230p.より引用)というものがあります。

この問題をみたときに私自身は logrotate などの設定をした...

Read More

プロセスはどのようにスケジューリングされるのか

Linux のしくみの プロセススケジューラの章の内容、まあそうですよね...と思いつつ実際に手元マシンで実験してみたことはなかったのでやってみました。ついでに、たまたま気が向いたので結果をグラフ化してまとめておきました。gnuplot 使うの 4 年ぶり以上だ...。

[amazon template=wishlist&asin=477419607X]

実験内容

  • 複数のプロセスを生成して、それぞれのプロセスにおいてループを回して、ユーザーモードの負荷をかけたとき、どのように各プロセスが実行されるかを観察する
    • 測定の際は、複数の論理 CPU にまたがって実行されないよう taskset コマンドで実行する論理 CPU を指定する
  • 実際に本に書かれていたことが正しいか自分の環境で実験してみた
  • 本のコードは、わりと真面目に良い感じの実験結果が得られるような処理やエラー処理が丁寧に書かれていた
    • 写経が面倒なので、本質的なふるまいはかわらないように適当にコードを書いて実験してみた
    • 雑なコード...
Read More

GNU-Coreutils touch コマンドの実装を読む

<p> 基本的に <code>utime(2)</code> を使えば良さそうなので、実装が楽そうだし、自分で書いて見つつ、GNU-Coreutils の実装を眺めてみるかなという気持ちになったので挑戦。<code>utime(2)</code> は次のようなインターフェースを持っている。</p>
#include <sys/types.h>
#include <utime.h>

int utime(const char *path, struct utimbuf *buf);

struct utimbuf {
    time_t actime;
    time_t modtime;
}
<h3>基本的な実装</h3> <p>単純に actime と modtime を更新してやればよいので、次のように書けば良さそう</p>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <utime.h>

int main(int...
Read More

gdb を使ったデバッグ

<ul> <li>「<a href="http://amzn.to/2CQhKu1">ふつうの Linux プログラミング</a>」というほんでバグがある C のコード <code>bug_head.c</code> のデバッグ作業をするときに <code>gdb</code> というツールが紹介されていた</li> <li>デバッグ時に <code>gdb</code> が役に立つので、ひとまずその流れを以下でみてみる</li> </ul> <h3>基本的なデバッグの流れ</h3> <p>流れを見た方がわかりやすいのでまず実例からみていく</p>
# コンパイルは -g オプションをつける
$ gcc ./src/bug_head.c -g -o ./bin/bug_head

# gdb をかましてデバッグ対象バイナリを実行する
$ gdb ./bin/bug_head
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7
Copyright (C) 2013 Free Software Foundation, Inc...
Read More

Copyright © 53ningen.com