天泣記

2020-08-07 (Fri)

#1 coq pull request

GitHub coq/coq/pull/12798: Change OUnit package name to ounit2.

2020-08-23 (Sun)

#1 Plan 9 の #!

ひさしぶりに The #! magic, details about the shebang/hash-bang mechanism on various Unix flavours を見て、 interpreter の情報を argv[0] から得られない OS として Plan 9 を 実際に試せそうな気がしたので、試してみた

なんとか editor と C compiler が使えるようになったので、以下のように試せた

% cat interp.c
#include <stdio.h>

int main(int argc, char *argv[])
{
  int i;
  for (i = 0; i < argc; i++)
    printf("argv[%d] = %s\n", i, argv[i]);
  return 0;
}
% cat script
#!/usr/glenda/interp foo bar
% pcc interp.c -o interp
% chmod 0755 script
% ./script baz qux
argv[0] = script
argv[1] = foo
argv[2] = bar
argv[3] = ./script
argv[4] = baz
argv[5] = qux
% /usr/glenda/script baz qux
argv[0] = script
argv[1] = foo
argv[2] = bar
argv[3] = /usr/glenda/script
argv[4] = baz
argv[5] = qux

たしかに argv[0] に script という文字列が入っていて、argv のどこを見ても interp の情報がない

この argv[0]の挙動は manual に The result honors the two conventions of a program accepting as argument a file to be interpreted and argv[0] naming the file being executed. と明記されているぽい

あと symbolic link を... と思ったら、Plan 9 には symbolic link がないらしい

最後に困ったのが shutdown の方法で、これは fshalt コマンドを使うようだ。 (PLAN 9 DESKTOP GUIDE) ただ、fshalt は filesystem を停止するだけなので、(VM の) 電源を落とすのは手動。 (ACPI で自動的にやる設定もあるようだが)

なお、結局わからなかったのが、Plan 9 の version を表示するコマンド。 uname とか lsb_release の類があってもいいと思うのだが、見つけられなかった。

#2 Plan 9 の /proc

Plan 9 にも /proc はあるので、眺めてみたが、これも実行ファイルのパスはみあたらない

proc(3)

/proc/PID/args は、exec に渡した argv のようだ (argv[0] も含まれているが、main に渡されたものと同じだろう)

/proc/PID/text は、実行ファイルそのものであって、パスではない

乱暴に、以下をやってみた

% cp /bin/rc myrc
% cat s
#!/usr/glenda/myrc
grep myrc /proc/$pid/*
% chmod 0755 s
% ./s

rc というのは shell で、こうやって実行ファイルの myrc が /proc のどこかに 出てこないか、と調べたわけだが、見つからない (/proc には普通には読めないファイルがあるのでエラーがいろいろ出るが省略)

#3 ELF の $ORIGIN

最近の ELF では、$ORIGIN という記述を rpath 内で利用できて、 相対パスで shared library を指定できる

この機能を実現するには、(linker が userland で動く限り) userland から、 実行ファイルのパスを確実に得る必要がある。 そして、argv[0] は確実ではないので、kernel の支援が必要になる。 (なお、shared library 1 から shared library 2 をリンクするときに $ORIGIN を使うと、 shared library 1 からの相対パスになる。 linker は shared library 1 を読み込んだ以上、そのパスは知っているはずなので、kernel の支援は必要ないだろう)

Plan 9 ではそういう話はないのかな、と思ったが、 Plan 9 には shared library はないらしい

Why Static

なお、file /bin/rc としたら、amd64 plan 9 executable と出てきて、 うむ、独自形式っぽいな、と思った

#4 Plan 9 の /bin

そういえば、Plan 9 は PATH 環境変数がなくて、かわりに、/bin を union directory として、 いろんな bin directory をまとめてしまう、と読んだことがあるような気がする

intro(1) には、 /$cputype/bin と /rc/bin が /bin に union される、とか書いてあるようだ

とすると、実行ファイルからの相対パスというのは、 /bin/foo からの相対パスという話になって、 わざわざ相対パスにする意味は大きくないかもしれない

そういう Plan 9 の流儀なら、 実行ファイルがなにか外部のファイルを必要とするなら、 絶対パスでアクセスして、 その絶対パスのところに union directory かなにかで 必要なファイルを配置する、ということになるのかもしれない


[latest]


田中哲