てきとうなメモ

本の感想とか技術メモとか

gemでnokogiriがインストールできない

nokogiriにいつからかlibxml2やlibxsltをバンドルするようになった。

これらをコンパイルするためにmini_portile2を利用しているのだが、内部的に開発用ツールを呼んでいるので、開発用のツールが入っていないとインストールに失敗する。
Cのライブラリをコンパイルするのでgccが必要だし、パッチをあてているのでpatchかgit(git patchする)が必要である

システムのlibxml2やlibxsltを利用したい場合や、これらのツールをインストールしたくない場合は、以下ののように明示的にシステムのライブラリを利用するようにオプションをつける。

$ gem install nokogiri -- --use-system-libraries

bundlerの場合は以下のようにする。

$ bundle config build.nokogiri --use-system-libraries
$ bundle install

Linuxのディストリビューションのバージョンを取得

例えばCentOSだと/etc/redhat-release→/etc/centos-releaseを見ればわかるのだが、世の中的にはどうしているのかなと思ってAnsibleのコードとか読んでみたけど、やっぱり/etc/redhat-release見ているだけだった。

ansibleはplatform.dist()[1]を取得していて、platform.dist()は/etcからリリースファイルにマッチするファイルを読み込んで、ファイルの内容に対してさらに正規表現でバージョンなどを取得している。リリースファイルの正規表現やリリース情報の正規表現は以下。

_release_filename = re.compile(r'(\w+)[-_](release|version)')
_lsb_release_version = re.compile(r'(.+)'
                                   ' release '
                                   '([\d.]+)'
                                   '[^(]*(?:\((.+)\))?')
_release_version = re.compile(r'([^0-9]+)'
                               '(?: release )?'
                               '([\d.]+)'
                               '[^(]*(?:\((.+)\))?')

結構泥臭い。あと、platform.distは3.5でdeprecatedになっていて3.7で削除されるらしいので、Ansible側のコードは書き直しが必要になってくるのかな。

/etc/init.d/xxxを直接起動してもsystemctl経由になる

$ sudo /etc/init.d/hello start
Starting hello (via systemctl):                            [  OK  ]

従来のinit.dの起動スクリプト直接実行しても、こんな感じでsystemctl経由で起動される。

init.dの起動スクリプトは/etc/init.d/functionsで処理されている。/etc/init.d/functionsは起動スクリプトを実行する際の便利なシェル関数群だったのだが、CentOS7ではsystemctlへのリダイレクトも実施している。

if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
                ( /bin/mountpoint -q /cgroup/systemd || /bin/mountpoint -q /sys/fs/cgroup/systemd ) ; then
        case "$0" in
        /etc/init.d/*|/etc/rc.d/init.d/*)
                _use_systemctl=1
                ;;  
        esac
fi

上記の部分で/etc/init.d/*や/etc/rc.d/init.d/*のスクリプトは_use_systemctlフラグを立てられる。

で、/etc/init.d/functionsの最後の方で

if [ "$_use_systemctl" = "1" ]; then
        if  [ "x$1" = xstart -o \
                "x$1" = xstop -o \
                "x$1" = xrestart -o \
                "x$1" = xreload -o \
                "x$1" = xtry-restart -o \
                "x$1" = xforce-reload -o \
                "x$1" = xcondrestart ] ; then

                systemctl_redirect $0 $1
                exit $?
        fi
fi

となりsystemctl_redirectを実行され、systemctl_redirectは

systemctl_redirect () {
        ...
        action "$s" /bin/systemctl $options $command "$prog.service"
}

とsystemctlを実行している。

というようなスクリプトになっているのでsystemctl経由で呼ばれないようにする方法はいくつかある。


環境変数SYSTEMCTL_SKIP_REDIRECTを1の設定して起動するのが一番正規の方法だろう。
また、処理が/etc/init.d/functions経由なので/etc/init.d/functionsを読み込んでいなければ、そのままのスクリプトとして実行される。
他にも、スクリプト名が/etc/init.d/*や/etc/rc.d/init.d/*でなければ実行されないので

$ cd /etc/init.d
$ sudo ./<サービス名> start

とかやっても、(systemctl関係なく)そのまま起動されるだけである。

ちなみにsystemctlの方でちゃんと設定している場合はinit.dの起動スクリプトは以下のようなものでも良い。

#!/bin/sh
. /etc/init.d/functions

まあ、systemd対応しているものにわざわざinit.dの起動スクリプトを用意する必要性はないと思うが。

紙のコミックとKindleコミックで発売日が同じもの 2016年04月分

7thGARDEN 5 (ジャンプコミックスDIGITAL)

7thGARDEN 5 (ジャンプコミックスDIGITAL)

とんかつDJアゲ太郎 6 (ジャンプコミックスDIGITAL)

とんかつDJアゲ太郎 6 (ジャンプコミックスDIGITAL)

カラダ探し 7 (ジャンプコミックスDIGITAL)

カラダ探し 7 (ジャンプコミックスDIGITAL)

コントラスト88 1 (ジャンプコミックスDIGITAL)

コントラスト88 1 (ジャンプコミックスDIGITAL)

ドラゴンボール超 1 (ジャンプコミックスDIGITAL)

ドラゴンボール超 1 (ジャンプコミックスDIGITAL)

μ&i 6 (ジャンプコミックスDIGITAL)

μ&i 6 (ジャンプコミックスDIGITAL)

火ノ丸相撲 9 (ジャンプコミックスDIGITAL)

火ノ丸相撲 9 (ジャンプコミックスDIGITAL)

灼熱の卓球娘 3 (ジャンプコミックスDIGITAL)

灼熱の卓球娘 3 (ジャンプコミックスDIGITAL)

遊☆戯☆王ARC-V 1 (ジャンプコミックスDIGITAL)

遊☆戯☆王ARC-V 1 (ジャンプコミックスDIGITAL)

昼のセント酒 (幻冬舎単行本)

昼のセント酒 (幻冬舎単行本)

それでも君が 2 (マーガレットコミックスDIGITAL)

それでも君が 2 (マーガレットコミックスDIGITAL)

ケダモノ彼氏 12 (マーガレットコミックスDIGITAL)

ケダモノ彼氏 12 (マーガレットコミックスDIGITAL)

センセイ君主 9 (マーガレットコミックスDIGITAL)

センセイ君主 9 (マーガレットコミックスDIGITAL)

婚約生 3 (マーガレットコミックスDIGITAL)

婚約生 3 (マーガレットコミックスDIGITAL)

虹色デイズ 12 (マーガレットコミックスDIGITAL)

虹色デイズ 12 (マーガレットコミックスDIGITAL)

年下の男の子 3 (マーガレットコミックスDIGITAL)

年下の男の子 3 (マーガレットコミックスDIGITAL)

木陰くんは魔女。 1 (マーガレットコミックスDIGITAL)

木陰くんは魔女。 1 (マーガレットコミックスDIGITAL)

木陰くんは魔女。 2 (マーガレットコミックスDIGITAL)

木陰くんは魔女。 2 (マーガレットコミックスDIGITAL)

紙のコミックとKindleコミックで発売日が同じもの 2016年03月分

ぷにんぷにんぷ (幻冬舎単行本)

ぷにんぷにんぷ (幻冬舎単行本)

しらたまくん 6 (ヤングジャンプコミックスDIGITAL)

しらたまくん 6 (ヤングジャンプコミックスDIGITAL)

グラビアトリ 2 (ヤングジャンプコミックスDIGITAL)

グラビアトリ 2 (ヤングジャンプコミックスDIGITAL)

ゴールデンカムイ 6 (ヤングジャンプコミックスDIGITAL)

ゴールデンカムイ 6 (ヤングジャンプコミックスDIGITAL)

テラフォーマーズ 16 (ヤングジャンプコミックスDIGITAL)

テラフォーマーズ 16 (ヤングジャンプコミックスDIGITAL)

ノー・ガンズ・ライフ 3 (ヤングジャンプコミックスDIGITAL)

ノー・ガンズ・ライフ 3 (ヤングジャンプコミックスDIGITAL)

ボクガール 9 (ヤングジャンプコミックスDIGITAL)

ボクガール 9 (ヤングジャンプコミックスDIGITAL)

ヤスミーン 3 (ヤングジャンプコミックスDIGITAL)

ヤスミーン 3 (ヤングジャンプコミックスDIGITAL)

リクドウ 7 (ヤングジャンプコミックスDIGITAL)

リクドウ 7 (ヤングジャンプコミックスDIGITAL)

干物妹!うまるちゃん 8 (ヤングジャンプコミックスDIGITAL)

干物妹!うまるちゃん 8 (ヤングジャンプコミックスDIGITAL)

それでも君が 1 (マーガレットコミックスDIGITAL)

それでも君が 1 (マーガレットコミックスDIGITAL)

インディゴの夜 4巻 (デジタル版ビッグガンガンコミックス)

インディゴの夜 4巻 (デジタル版ビッグガンガンコミックス)

ハンキー・ドリー 1 (マーガレットコミックスDIGITAL)

ハンキー・ドリー 1 (マーガレットコミックスDIGITAL)

バディゴ! 4 (りぼんマスコットコミックスDIGITAL)

バディゴ! 4 (りぼんマスコットコミックスDIGITAL)

町田くんの世界 3 (マーガレットコミックスDIGITAL)

町田くんの世界 3 (マーガレットコミックスDIGITAL)

椿町ロンリープラネット 3 (マーガレットコミックスDIGITAL)

椿町ロンリープラネット 3 (マーガレットコミックスDIGITAL)

三者三葉 12巻

三者三葉 12巻

gethostbynameの引数にipアドレスを指定した場合の動作

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv) {
  struct hostent *host = gethostbyname(argv[1]);
  printf("h_name = %s\n", host->h_name);
  printf("ip = ");
  for (char **addrp = host->h_addr_list; *addrp != NULL; addrp++) {
    struct in_addr addr;
    addr.s_addr = *((in_addr_t *) *addrp);
    char* ip = inet_ntoa(addr);
    printf(" %s", ip);
  }
  printf("\n");
}
$ gcc -std=c99 gethostbyname.c
$ ./a.out www.google.com
h_name = www.google.com
ip =  216.58.220.196
$ ./a.out 216.58.220.196
h_name = 216.58.220.196
ip =  216.58.220.196

ホスト名とIPアドレス両方に対応したアプリを作る場合、条件分岐しなくてよいので便利ではあるのだけども、統一感はないかな。SUSやPOSIXとしてはIPアドレスを指定した場合の動作は定義していない。

The name argument of gethostbyname() shall be a node name; the behavior of gethostbyname() when passed a numeric address string is unspecified. For IPv4, a numeric address string shall be in the dotted-decimal notation described in inet_addr().

The Base Specifications Issue 6

W. Richard StevensのUnix Network Programmingのp.308によると、RloginがIPアドレスに対応していなかったかららしい

This code was added because the Rlogin client accepts only a hostname, calling gethostbyname, and will not accept a dotted-decimal string[Vixie 1996]

アプリ側の問題をライブラリ側で実装するのはどうなんだろうと一瞬思ったが、他のアプリにとっても便利だと思うのでまあいいのか

4.3BSD-Renoの頃]にはこのコードは入っているな

struct hostent *
gethostbyname(name)
	char *name;
{
...

				if ((host_addr.s_addr = inet_addr(name)) == -1) {
					h_errno = HOST_NOT_FOUND;
					return((struct hostent *) NULL);
				}
				host.h_name = name;
				host.h_aliases = host_aliases;
				host_aliases[0] = NULL;
				host.h_addrtype = AF_INET;
				host.h_length = sizeof(u_long);
				h_addr_ptrs[0] = (char *)&host_addr;
				h_addr_ptrs[1] = (char *)0;
#if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
				host.h_addr_list = h_addr_ptrs;
#else
				host.h_addr = h_addr_ptrs[0];
#endif
				return (&host);

紙のコミックとKindleコミックで発売日が同じもの 2016年02月分

BUNGO―ブンゴ― 4 (ヤングジャンプコミックスDIGITAL)

BUNGO―ブンゴ― 4 (ヤングジャンプコミックスDIGITAL)

しあわせゴハン 2 (ヤングジャンプコミックスDIGITAL)

しあわせゴハン 2 (ヤングジャンプコミックスDIGITAL)

もぐささん 8 (ヤングジャンプコミックスDIGITAL)

もぐささん 8 (ヤングジャンプコミックスDIGITAL)

元ヤン 3 (ヤングジャンプコミックスDIGITAL)

元ヤン 3 (ヤングジャンプコミックスDIGITAL)

神様のハナリ 2 (ヤングジャンプコミックスDIGITAL)

神様のハナリ 2 (ヤングジャンプコミックスDIGITAL)

不能犯 4 (ヤングジャンプコミックスDIGITAL)

不能犯 4 (ヤングジャンプコミックスDIGITAL)

天と献上姫(3) (冬水社・いち*ラキコミックス)

天と献上姫(3) (冬水社・いち*ラキコミックス)

コープスパーティー 2巻 (デジタル版ガンガンコミックスJOKER)

コープスパーティー 2巻 (デジタル版ガンガンコミックスJOKER)

ALL OUT!!(8) (モーニングコミックス)

ALL OUT!!(8) (モーニングコミックス)

おしりマカロン(1) (モーニングコミックス)

おしりマカロン(1) (モーニングコミックス)

ギャングース(11) (モーニングコミックス)

ギャングース(11) (モーニングコミックス)

生き返っても、あの世 (幻冬舎単行本)

生き返っても、あの世 (幻冬舎単行本)

A.【アンサー】 2 (マーガレットコミックスDIGITAL)

A.【アンサー】 2 (マーガレットコミックスDIGITAL)

ReReハロ 9 (マーガレットコミックスDIGITAL)

ReReハロ 9 (マーガレットコミックスDIGITAL)

なないろ革命 4 (りぼんマスコットコミックスDIGITAL)

なないろ革命 4 (りぼんマスコットコミックスDIGITAL)

一鬼夜行 3巻 (デジタル版ビッグガンガンコミックス)

一鬼夜行 3巻 (デジタル版ビッグガンガンコミックス)

歌うたいの黒うさぎ 9 (マーガレットコミックスDIGITAL)

歌うたいの黒うさぎ 9 (マーガレットコミックスDIGITAL)

葬除屋XRAID 1巻 (デジタル版ビッグガンガンコミックス)

葬除屋XRAID 1巻 (デジタル版ビッグガンガンコミックス)

葬除屋XRAID 2巻 (デジタル版ビッグガンガンコミックス)

葬除屋XRAID 2巻 (デジタル版ビッグガンガンコミックス)