ls ソースコードを取得する

普段使っているコマンドがどう実装されているのか知りたかったのと、 勉強も兼ねてコードリーディングをしたいと思い、ls コマンドのソースコードを読むことにしました。

まずはソースコードを取得する必要があります。 環境によって様々な方法があると思いますが、ここでは Linux での取得方法を紹介します。 Linux 以外はビルド・実行しておらず未検証のためリンクだけ掲載しています。 環境により実装や依存ライブラリが異なるので、ビルド・実行するのであれば環境にあったソースコードを取得したほうがよいです。

Linux

Linux では ls を含む cp, mkdir 等の基本的なコマンドは coreutils というパッケージ内に含まれていますので、 このパッケージのソースコードを取得します。

Ubuntu

coreutils がどのパッケージリポジトリにあるのか確認します

$ apt show coreutils | grep -i apt-sources
APT-Sources: http://jp.archive.ubuntu.com/ubuntu eoan/main amd64 Packages
# or
$ apt-cache showpkg coreutils | grep -i file
                 File: /var/lib/apt/lists/jp.archive.ubuntu.com_ubuntu_dists_eoan_main_binary-amd64_Packages
                 File: /var/lib/apt/lists/jp.archive.ubuntu.com_ubuntu_dists_eoan_main_binary-i386_Packages
                 File: /var/lib/apt/lists/jp.archive.ubuntu.com_ubuntu_dists_eoan_main_i18n_Translation-ja
                 File: /var/lib/apt/lists/jp.archive.ubuntu.com_ubuntu_dists_eoan_main_i18n_Translation-en

coreutils パッケージは http://jp.archive.ubuntu.com/ubuntu eoan/main amd64 Packages で管理されていることがわかりました 。

デフォルトだとパッケージのソースコードを取得できるように設定されていません。 一時的に /etc/apt/sources.list を変更してソースコードを取得できるようにします。

$ sudo vi /etc/apt/sources.list
...
$ grep "^[^#;]" /etc/apt/sources.list
deb http://jp.archive.ubuntu.com/ubuntu/ eoan main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu/ eoan main restricted  # <- これを追加
deb http://jp.archive.ubuntu.com/ubuntu/ eoan-updates main restricted
deb http://jp.archive.ubuntu.com/ubuntu/ eoan universe
...

ダウンロードします

$ sudo apt-get update -y
$ apt-get source coreutils -q
パッケージリストを読み込んでいます...
5,401 kB のソースアーカイブを取得する必要があります。
取得:1 http://jp.archive.ubuntu.com/ubuntu eoan/main coreutils 8.30-3ubuntu2 (dsc) [2,048 B]
取得:2 http://jp.archive.ubuntu.com/ubuntu eoan/main coreutils 8.30-3ubuntu2 (tar) [5,360 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu eoan/main coreutils 8.30-3ubuntu2 (diff) [39.6 kB]
5,401 kB を 6秒 で取得しました (950 kB/s)
dpkg-source: info: extracting coreutils in coreutils-8.30
dpkg-source: info: unpacking coreutils_8.30.orig.tar.xz
dpkg-source: info: unpacking coreutils_8.30-3ubuntu2.debian.tar.xz
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying prefer-renameat2-from-glibc-over-syscall.patch
dpkg-source: info: applying renameatu.patch
dpkg-source: info: applying 61_whoips.patch
dpkg-source: info: applying 63_dd-appenderrors.patch
dpkg-source: info: applying 72_id_checkngroups.patch
dpkg-source: info: applying 80_fedora_sysinfo.patch
dpkg-source: info: applying 85_timer_settime.patch
dpkg-source: info: applying 99_kfbsd_fstat_patch.patch
dpkg-source: info: applying 99_float_endian_detection.patch
$ ls
coreutils-8.30/  coreutils_8.30-3ubuntu2.debian.tar.xz  coreutils_8.30-3ubuntu2.dsc  coreutils_8.30.orig.tar.xz

ダウンロードできました。coreutils-8.30/src/ls.cls の主なソースコードです。

CentOS

コマンド例です。dnf を使って rpm をダウンロード、展開します。

cd /tmp
dnf install -y -q dnf-plugins-core
dnf download -y -q --setopt=strict=0 --source coreutils
rpm2cpio coreutils-8.30-6.el8.src.rpm | cpio -idmdD /tmp/coreutils
cd /tmp/coreutils
tar Jxf coreutils-8.30.tar.xz
vi coreutils-8.30/src/ls.c

UNIX

macOS

FreeBSD

NetBSD