fstat
fstat
前回から何度も登場してるfstatなんだけど、普通にmanするとfstat(1)が出 てくる。
NAME fstat - display status of open files SYNOPSIS fstat [-fnosv] [-M core] [-N system] [-p pid] [-u user] [file ...] DESCRIPTION fstat identifies open files. A file is considered open by a process if it was explicitly opened, is the working directory, root directory, active executable text, or kernel trace file for that process. If no options are specified, fstat reports on all open files in the system.
ob$ fstat |grep guile USER CMD PID FD MOUNT INUM MODE R/W SZ|DV sakae guile 85063 text /usr/local 752437 -rwxr-xr-x r 8388 sakae guile 85063 wd /tmp 2 drwxrwxrwt r 512 sakae guile 85063 0 / 565 crw--w---- rw ttyp2 sakae guile 85063 1 / 565 crw--w---- rw ttyp2 sakae guile 85063 2 / 565 crw--w---- rw ttyp2 sakae guile 85063 3 pipe 0x0 state: sakae guile 85063 4 pipe 0x0 state: sakae guile 85063 5 pipe 0x0 state: R : sakae guile 85063 12 pipe 0x0 state:
やけに配管が多いな。
fstatの仲間達
fstatとかのSee alsoを見れば大体形がつくんだけど、念入りに確認しとく。
ob$ locate bin | grep -v src | egrep 'bin/.*stat' /usr/bin/fstat /usr/bin/hoststat /usr/bin/kstat /usr/bin/netstat /usr/bin/nfsstat /usr/bin/purgestat /usr/bin/stat /usr/bin/systat /usr/bin/vmstat /usr/local/bin/gst-stats-1.0 /usr/local/bin/kpsestat /usr/local/bin/nfs-stat /usr/sbin/ifstated /usr/sbin/iostat /usr/sbin/pppstats /usr/sbin/pstat /usr/sbin/rpc.statd
と、色々有り。そしてfstatの兄弟として、fuserが居る。
lsof
Debina/WSL2だと、どうよ? デフォでlsofってのが入っていた。
LSOF(8) System Manager's Manual LSOF(8) NAME lsof - list open files SYNOPSIS lsof [ -?abChlnNOPQRtUvVX ] [ -A A ] [ -c c ] [ +c c ] [ +|-d d ] [ +|-D D ] [ +|-e s ] [ +|-E ] [ +|-f [cfgGn] ] [ -F [f] ] [ -g [s] ] [ -i [i] ] [ -k k ] [ -K k ] [ +|-L [l] ] [ +|-m m ] [ +|-M ] [ -o [o] ] [ -p s ] [ +|-r [t[m<fmt>]] ] [ -s [p:s] ] [ -S [t] ] [ -T [t] ] [ -u s ] [ +|-w ] [ -x [fl] ] [ -z [z] ] [ -Z [Z] ] [ -- ] [names] DESCRIPTION Lsof revision 4.95.0 lists on its standard output file information about files opened by processes for the following UNIX dialects: Apple Darwin 9 and Mac OS X 10.[567] FreeBSD 8.[234], 9.0 and 1[012].0 for AMD64-based systems Linux 2.1.72 and above for x86-based systems Solaris 9, 10 and 11
結構、汎用品っぽいな。【 lsof 】コマンド――オープンしているファイルを 一覧表示する 普通に解説が出て来るし。オイラーもgoshのpidを調べて、表示させてみた。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gosh 362 sakae cwd DIR 0,81 512 1407374883553287 /mnt/r gosh 362 sakae rtd DIR 8,32 4096 2 / gosh 362 sakae txt REG 8,32 81056 66411 /usr/local/bin/gosh gosh 362 sakae mem REG 8,32 724736 66303 /usr/local/lib/gauche-0.98/0.9.14/x86_64-pc-linux-gnu/text--line-edit.so : gosh 362 sakae mem REG 8,32 210976 8191 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 gosh 362 sakae 0u CHR 136,2 0t0 5 /dev/pts/2 gosh 362 sakae 1u CHR 136,2 0t0 5 /dev/pts/2 gosh 362 sakae 2u CHR 136,2 0t0 5 /dev/pts/2
そして、こんな楽しい事が、 rmで削除したファイルを復元できる lsof まあ、ネタって事です。
多数の配管
配管と言うと、まっさきに思いつくのは、生まれながらにして、皆が持ってる 血管だな。 血管はマルチパーパスなパイプだ。燃料パイプ(糖、脂肪)、ガス管(酸素、二 酸化炭素)、下水管(老廃物)ぐらいは普通 に頭に浮かんでくる。その他に、どんな機能が有るの。あの人に聞いてみた。
A: 血管の機能を比喩で理解するのは非常に有益です。以下に、血管の他の重要な機能を比喩と一緒に説明します。
- 通信ケーブル(ホルモン)
- 比喩: 血管は、体全体に信号を送る通信ケーブルのようなものです。
- 流れる成分: ホルモン(例:インスリン、アドレナリン)
- 説明: ホルモンは、特定の細胞や臓器に指示を送る化学メッセージです。血流によって運ばれることで、体の様々な機能を調整します。
- 栄養供給管(ビタミン、ミネラル)
- 比喩: 血管は、家に栄養を届ける配達員のようなものです。
- 流れる成分: ビタミン(例:ビタミンC、ビタミンD)、ミネラル(例:カルシウム、鉄)
- 説明: 血液は、食事から吸収されたビタミンやミネラルを全身の細胞に運び、健康を保つために必要な成分を供給します。
- 防御壁(免疫細胞)
- 比喩: 血管は、外敵から守るための防御壁や警備員のようなものです。
- 流れる成分: 免疫細胞(例:白血球、リンパ球)
- 説明: 血液は、体内に侵入した細菌やウイルスを攻撃し、感染を防ぐための免疫細胞を運びます。
- クーリングシステム(体温調節)
- 比喩: 血管は、家の空調システムのように体温を調節します。
- 流れる成分: 温度調節に関わる血液
- 説明: 血管は、皮膚の近くを流れることで熱を放散し、体温を下げたり、体の中心部に熱を保持したりすることで体温を調整します。
これらの機能を理解することで、血管がいかに多くの役割を果たしているかが分かります。血液は単に物質を運ぶだけでなく、体の機能を総合的に維持するために重要な役割を果たしています。
素晴しいバスラインだな。
再掲
FreeBSDでの結果。微妙にOpenBSDとは異なるなあ。
sakae@fb:~ $ fstat -p 15569 USER CMD PID FD MOUNT INUM MODE SZ|DV R/W sakae guile 15569 text / 177399 -rwxr-xr-x 14836 r sakae guile 15569 ctty /dev 110 crw--w---- pts/2 rw sakae guile 15569 wd /tmp 2 drwxrwxrwt 216 r sakae guile 15569 root / 2 drwxr-xr-x 1024 r sakae guile 15569 0 /dev 110 crw--w---- pts/2 rw sakae guile 15569 1 /dev 110 crw--w---- pts/2 rw sakae guile 15569 2 /dev 110 crw--w---- pts/2 rw sakae guile 15569 3 /dev 40 crw-rw-rw- zero r sakae guile 15569 4* pipe 15261000 <-> 152610c4 0 rw sakae guile 15569 5* pipe 152610c4 <-> 15261000 0 rw sakae guile 15569 6* pipe 152611a0 <-> 15261264 0 rw sakae guile 15569 7* pipe 15261264 <-> 152611a0 0 rw sakae guile 15569 8* pipe 15260680 <-> 15260744 0 rw sakae guile 15569 9* pipe 15260744 <-> 15260680 0 rw sakae guile 15569 10* pipe 152604e0 <-> 152605a4 0 rw sakae guile 15569 11* pipe 152605a4 <-> 152604e0 0 rw sakae guile 15569 12* pipe 15260340 <-> 15260404 0 rw sakae guile 15569 13* pipe 15260404 <-> 15260340 0 rw
解剖学的機能調査
いきなりメスを握ってみる。pipe(2)したらpipe2も出てきたので、これもBPの対象に含め る。
パイプは情報の流れに方向性が有るので、ディスクリプターはペアになってる。 すなわち書き込み用と読み出し用だ。fstatの結果でも、アドレスト思しきデー タがペアーで表われている。血管になぞ らえれば、動脈と静脈になるな。5回呼び出されるはず。
(gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0xffbfea14, flags=1048576) at pipe2.c:57 #2 0x205b7cf6 in guilify_self_1 (base=0xffbfead8, needs_unregister=0) at threads.c:397 #3 0x205b7a5d in scm_threads_prehistory (base=0xffbfead8) at threads.c:1790 #4 0x20502fb3 in scm_i_init_guile (base=0xffbfead8) at init.c:361 #5 0x205b58bb in scm_i_init_thread_for_guile (base=0xffbfead8, dynamic_state=0x0) at threads.c:574
(gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0x20628190 <finalization_pipe>, flags=1048576) at pipe2.c:57 #2 0x204ea85f in start_finalization_thread () at finalizers.c:276 #3 0x204ea415 in spawn_finalizer_thread () at finalizers.c:312 #4 0x20647168 in GC_notify_or_invoke_finalizers () from /usr/local/lib/libgc-threaded.so.1 #5 0x20649164 in GC_generic_malloc_many () from /usr/local/lib/libgc-threaded.so.1
(gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0xfbbfdec8, flags=1048576) at pipe2.c:57 #2 0x205b7cf6 in guilify_self_1 (base=0xfbbfdf54, needs_unregister=1) at threads.c:397 #3 0x205b5924 in scm_i_init_thread_for_guile (base=0xfbbfdf54, dynamic_state=0x20e8ba10) at threads.c:598 #4 0x205b8a87 in with_guile (base=0xfbbfdf54, data=0xfbbfdf78) at threads.c:642 #5 0x2064e29e in GC_call_with_stack_base () from /usr/local/lib/libgc-threaded.so.1
(gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0x2062b73c <signal_pipe>, flags=1048576) at pipe2.c:57 #2 0x20583cbd in start_signal_delivery_thread () at scmsigs.c:209 #3 0x206979c6 in _thr_once ( once_control=0x2062b428 <scm_i_ensure_signal_delivery_thread[once]>, init_routine=0x20583c80 <start_signal_delivery_thread>) at /usr/src/lib/libthr/thread/thr_once.c:96 #4 0x20583c6b in scm_i_ensure_signal_delivery_thread () at scmsigs.c:223 #5 0x20583e55 in scm_sigaction_for_thread (signum=0xa, handler=0x212e8270, flags=0x904, thread=0x20bac990) at scmsigs.c:336
(gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0xfbafced4, flags=1048576) at pipe2.c:57 #2 0x205b7cf6 in guilify_self_1 (base=0xfbafcf60, needs_unregister=1) at threads.c:397 #3 0x205b5924 in scm_i_init_thread_for_guile (base=0xfbafcf60, dynamic_state=0x217d2d00) at threads.c:598 #4 0x205b8a87 in with_guile (base=0xfbafcf60, data=0xfbafcf84) at threads.c:642 #5 0x2064e29e in GC_call_with_stack_base () from /usr/local/lib/libgc-threaded.so.1
うん、確かに5回の呼出の後、replに突入した。
で、ザット見、gcスレッドやシグナル・システムとの交信に、専用のパイプを 利用してるっぽい。
for users
パイプはユーザーにも公開されてて、scheme上から簡単に作成できる。
scheme@(guile-user)> ,d pipe - Scheme Procedure: pipe [flags] Return a newly created pipe: a pair of ports which are linked together on the local machine. The _car_ is the input port and the _cdr_ is the output port. Data written (and flushed) to the output port can be read from the input port. Pipes are commonly used for communication with a newly forked child process. The need to flush the output port can be avoided by making it unbuffered using `setvbuf'.
作成は、そのものズバリの関数名でできる。
scheme@(guile-user)> (define my (pipe)) [Switching to LWP 100116 of process 15726] Thread 1 hit Breakpoint 1, pipe2 () at pipe2.S:4 4 in pipe2.S (gdb) bt 6 #0 pipe2 () at pipe2.S:4 #1 0x2060328f in rpl_pipe2 (fd=0xffbfd73c, flags=0) at pipe2.c:57 #2 0x205f23c3 in scm_pipe2 (flags=0x904) at posix.c:277 #3 0x204f92af in scm_apply_subr (sp=0x215a9c00, idx=457, nslots=2) at gsubr.c:478 #4 0x205ccb47 in vm_debug_engine (thread=0x20baae00) at ./vm-engine.c:972 #5 0x205bdeba in scm_call_n (proc=0x20f13020, argv=0xffbfdfbc, nargs=1) at vm.c:1616
できた管を確認。
(gdb) c Continuing. scheme@(guile-user)> my $1 = (#<input: #{read pipe}# 14> . #<output: #{write pipe}# 15>)
fstatでディスクリプターが2個、増加してる事を確認。どちらもrwってなって るけど、これはOS的に確認が面倒なので、お茶を濁しているのだろう。
sakae@fb:/usr/ports/lang/guile3/work/guile-3.0.9/libguile $ fstat -p 15726 USER CMD PID FD MOUNT INUM MODE SZ|DV R/W : sakae guile 15726 14* pipe 1525f820 <-> 1525f8e4 0 rw sakae guile 15726 15* pipe 1525f8e4 <-> 1525f820 0 rw
フラグの表示
本当にrwって表示はどうよと疑問。fstatを遡上に載せてみる。
(gdb) bt #0 print_pipe_info (procstat=0x2066e000, fst=0x20691580) at /usr/src/usr.bin/fstat/fstat.c:482 #1 print_file_info (procstat=<optimized out>, fst=<optimized out>, uname=<optimized out>, cmd=<optimized out>, pid=<optimized out>) at /usr/src/usr.bin/fstat/fstat.c:298 #2 dofiles (procstat=<optimized out>, kp=<optimized out>) at /usr/src/usr.bin/fstat/fstat.c:229 #3 do_fstat (argc=3, argv=<optimized out>) at /usr/src/usr.bin/fstat/fstat.c:205 #4 0x00404223 in main (argc=541157744, argv=0x3) at /usr/src/usr.bin/fstat/main.c:48 #5 0x0040281d in _start1 (cleanup=0x20416970 <rtld_nop_exit>, argc=3, argv=0xffbfebbc) at /usr/src/lib/csu/i386/crt1_c.c:66 #6 0x0040293c in _start () at /usr/src/lib/csu/i386/crt1_s.S:42 : 489 print_access_flags(fst->fs_fflags); (gdb) p *fst $2 = {fs_type = 4, fs_flags = 0, fs_fflags = 3, fs_uflags = 0, fs_fd = 4, fs_ref_count = 1, fs_offset = 0, fs_typedep = 0x206bfa00, fs_path = 0x0, next = {stqe_next = 0x20691580}, fs_cap_rights = {cr_rights = { 144123984168878079, 288230376153808895}}} (gdb) n sakae guile 16302 4* pipe 152604e0 <-> 152605a4 0 rw
libprocstat.h に定義される struct filestatの中にあった。Descriptor
access flags. ってなってるから、OS依存だな。後でOpenBSDの sys_pipe
でも、眺めてみよう。
使ってみる
scheme@(guile-user)> (display "hello pipe\n" (cdr my)) scheme@(guile-user)> (read (car my)) ^C Thread 1 received signal SIGINT, Interrupt. Sent by kernel. _read () at _read.S:4 warning: 4 _read.S: No such file or directory (gdb) bt 5 #0 _read () at _read.S:4 #1 0x2069cf31 in __thr_read (fd=14, buf=0x22716010, nbytes=4096) at /usr/src/lib/libthr/thread/thr_syscalls.c:418 #2 0x20a6977f in read (fd=14, buf=0x22716010, nbytes=4096) at /usr/src/lib/libc/sys/read.c:45 #3 0x204f1f65 in fport_read (port=0x20e66c80, dst=0x22716000, start=0, count=4096) at fports.c:600 #4 0x20567c5b in scm_i_read_bytes (port=0x20e66c80, dst=0x22716000, start=0, count=4096) at ports.c:1566
パイプに書き込み、そして読み出し。ブロックしちゃったぞ。どうする? な んか、昔rubyをやってて、同じ問題にぶちあたったな。そしてmatzさんに教え を乞うた。
scheme@(guile-user)> (define my (pipe)) scheme@(guile-user)> (display "Hello PIPE\n" (cdr my)) scheme@(guile-user)> (close (cdr my)) $6 = #t scheme@(guile-user)> (read (car my)) $7 = Hello scheme@(guile-user)> (read (car my)) $8 = PIPE scheme@(guile-user)> (read (car my)) $9 = #<eof>
書き込んだら、ポートをクローズ。こうしておいてから、読み出せばよい。何 か、readって、S式を読み込むんで、ホワイトスペースは無視されるんだな。 文字列として読み込むには、(use-modules (ice-9 rdelim)) しといて、 read-stringすればいいのか。
普通は裸のpipeを苦労して使う事は無いだろう。ice-9 popen をuse-modules すれば、processとタイアップして、便利に使えるぞ。
etc
第45回野間文芸新人賞受賞作 こんな本を読んでいたら、さりげなく馬さん 関係のURLが紹介さ れてた。ついでにこんなのも。
競走馬の名前はカナで9文字以内、アルファベットにした場合に18文字以内と定められています。 ちなみに、あまり見かけませんが最少文字数はカナ2文字からOK。 ゼッケンからはみ出るほど長い名前の馬がいないのは、この決まりのおかげですね。 ちなみに国際的な馬名登録の国際基準でも「アルファベット18文字」というのは共通。
一応あいつにも聞いてみるか。
A: 競馬馬の命名には国や競馬団体によって様々な規則がありますが、一般的なルールとして以下のようなものがあります:
- 名前の長さ: 馬の名前は文字数に制限があります。例えば、日本中央競馬会(JRA)の場合、カタカナで最大9文字まで、英語では18文字までという制限があります。
- 重複禁止: 同じ国や競馬団体内で既に使用されている名前は使えません。また、有名な競走馬や種牡馬、繁殖牝馬の名前も使用できません。
- 禁止用語: 不適切な言葉や商標、商号、他人の名前など、公序良俗に反するものは使用できません。
- 馬名の変更: 馬名は基本的に変更できませんが、特定の条件下では変更が認められる場合もあります。
- 命名者の自由: 馬主が命名する権利を持っており、自分の好きな名前を付けることができます。ただし、前述の規則を遵守する必要があります。
これらのルールは国や競馬団体によって多少の違いがあるため、具体的な詳細は各団体の規則を確認することが重要です。
この規約が撤廃されて10文字になったら、、、ってのが小説に出てくるんだけ ど その発想が面白い。作者さん想像 力、武豊、4500勝おめでとう。
Q: 名前の長さ制限が撤廃されたら、どんな事が起きるか、考察してください
A: 名前の長さ制限が撤廃された場合、競馬界においていくつかの影響が考えられます。以下にその主な影響と可能性を挙げます:
- 識別の困難化:
- 長い名前の混同: 名前が長くなると、音や見た目が似た名前が増える可能性があり、混同しやすくなります。
- 覚えにくさ: ファンや関係者が馬の名前を覚えにくくなる可能性が高まります。特に、実況中継や新聞記事などで長い名前は不便です。
- 記録・表示の問題:
- システム対応: 競馬関連のシステムやデータベースは現在の文字数制限に基づいて設計されているため、長い名前に対応するためにはシステムの改修が必要になります。
- 表示スペース: レースプログラム、馬券、ウェブサイトなどで名前を表示するスペースが限られているため、長い名前は適切に表示できない可能性があります。
- マーケティング・ブランディングの影響:
- ブランド力の低下: 短い名前の方が覚えやすく、ブランディングしやすいため、長い名前が増えると馬のブランド力が低下する可能性があります。
- プロモーションの難しさ: ファンが覚えにくい名前では、プロモーション活動やファンサービスに支障が出る可能性があります。
- 創造性の増加:
- ユニークな名前: 制限がなくなることで、馬主はより自由に創造的な名前を付けることができます。
- 個性の表現: 長い名前を通じて、馬の個性や背景、馬主の意図をより詳細に表現することが可能になります。
- 規則や慣習の再評価:
- 新たなルールの制定: 長い名前による混乱や不便が生じた場合、新たなルールやガイドラインが必要になるかもしれません。
- 文化的変化: 競馬界における命名の文化や慣習が変化する可能性があります。
- コミュニケーションの問題:
- 発音の難しさ: 長い名前は発音が難しくなり、レース実況や報道での混乱が増えるかもしれません。
- 略称の増加: 長い名前を持つ馬の略称やニックネームが一般化し、それが公式記録と異なる場合の混乱が考えられます。
以上のように、名前の長さ制限が撤廃されることで、多くの実務的および文化 的な影響が予想されます。これに対処するためには、関係者間での調整や新た な規則の整備が必要になるでしょう。
やっぱり、こいつは常識的だな。創造性は乏しいと思うぞ。
そう言えば、春の馬の大運動会が終ったな。みんな浄財で、応援したかな? ご利益が無かった人は、秋に備えて馬貯金をしておこう。NISAよりも歴史が古 い、政府公認の蓄財術ですから。