回 3-1 道 3 コンピュータの中
システムコールは、
読み終えたらファイルを
この頁の流れ
アプリが
ファイルを 開く 1 行は、 誰が 開いているのか
ファイルを実際に
Python で
ファイルを読む 2 行
with open("memo.txt") as f:
data = f.read()この 2 行で、
OS は 何を していて、 システムコールは どう 呼ばれるのか
OS は装置とメモリをアプリに
OS の 役目は、 資源を 分けて、 装置の 違いを隠すこと
OS は、CPU の
カーネル 空間と ユーザー空間
OS の
| ユーザー空間 | カーネル空間 | |
|---|---|---|
| 住んでいる物 | ブラウザ、 | カーネル、 |
| 装置を触れるか | 触れない。 | 直接触れる |
| 落ちたとき | その | OS ごと止まる |
ユー
線を 越える手順
線を
- システムコールの
番号と 引数を、 カーネルが 待っている 場所 (CPU の レジスタ、 計算に 使う 小さな 置き場) に置く - 専用の
命令で CPU を カーネルモード (装置を 触れる 状態) に 切り 替え、 カーネルに 本当の 仕事をさせる - カーネルが
CPU を ユーザーモードに 戻した とき、 失敗なら 理由の 番号を errno (失敗の 理由を 入れておく変数) に置く
どの
| 番号 | 名前 | 仕事 |
|---|---|---|
| 0 | read | 番号の |
| 1 | write | 番号の |
| 2 | open | ファイルを |
| 3 | close | 番号札を |
| 257 | openat | 場所を |
x86-64 では、syscall で、
開いていない
ラッパー関数と 代表的な システムコール
ふつうのos.open、os.read、os.write、os.close も、
| 分野 | 代表的な |
|---|---|
| ファイル | open、 |
| プロセス (動いている | fork、 |
| メモリ | mmap、 |
| ネットワーク | socket、 |
ファイルディスクリプタは、 開いた ファイルの番号札
open が
open(2) に
動かして確かめる
Python の os の 4 つの窓口を、
動かす 4 つの窓口を順に呼ぶ
▶ 実行ボタンを押すと結果がここに表示されます
実行すると、次の通りに出ます
open True
write 6
close
open True
read b'hello\n'
closeopen はfd >= 3 は
ふだんの open() も、open() の
動かす open() の中の番号札
▶ 実行ボタンを押すと結果がここに表示されます
実行すると、次の通りに出ます
int
0
3f.fileno() はos.fstat でf.write のf.flush() のf.write のflush か close の
read は、
動かす 4 バイトずつ読む
▶ 実行ボタンを押すと結果がここに表示されます
実行すると、次の通りに出ます
4 b'hell'
2 b'o\n'
0 b''6 バイトのf.read() の 1 行も、
ここまでを
| Python の書き方 | 裏で |
|---|---|
open("memo.txt") | open (いまの |
f.read() | read を |
f.write(...) | ためてから |
with の終わり | close |
どこで 崩れるのか
システムコールは
閉じた 番号で 読むと EBADF
閉じた
動かす 閉じた番号と無いファイル
▶ 実行ボタンを押すと結果がここに表示されます
実行すると、次の通りに出ます
EBADF
Bad file descriptor
ENOENT
No such file or directory閉じたOSError という
開いたまま 閉じ忘れる
番号札には、1 つのプログラムが
要求のたびに 1 枚ずつwith を
呼ぶ回数が 増えると遅くなる
システムコールはopen() は
動かす ためる大きさと呼ぶ回数
▶ 実行ボタンを押すと結果がここに表示されます
実行すると、次の通りに出ます
1 1000
64 32
4096 1
20002 バイトの行を 1000 行書いています。open() の
ためている間は OS に
崩れる
- 開いたら
必ず 使える、という 前提。 名前が 無い、 権限が 無い、 番号札が 尽きた、 で open は失敗する - 頼んだ分だけ返る、という
前提。 read と write は、 頼んだより 少ない 数を 返すことがある f.writeを呼べば もう 書けている、という 前提。 ためている 間は、 まだ OS に 渡っていない - 番号札は
自分だけの 物、という 前提。 閉じた 番号は、 別の ファイルに 使い回される
仕事で どう 確かめるか
仕事では、
1 つ目は、Linux の
strace(1) の説明の例
open("/dev/null", O_RDONLY) = 3
open("/foo/bar", O_RDONLY)
= -1 ENOENT (No such file
or directory)1 行目は
| 使い方 | 分かること |
|---|---|
strace -e trace=%file | ファイルの |
strace -c | システムコールごとの |
strace -p と番号 | 動いている |
2 つ目は、OSError の
関わる実例
カーネルとユー
Dirty COW (CVE-2016-5195、 2016 年 10 月)
CVE の
Meltdown (2018 年 1 月)
2018 年 1 月 3 日に公開された
よくある問い
システムコールと ふつうの 関数の 呼び出しは 何が 違うのですか
ふつうの関数は、
カーネル 空間と ユー ザー 空間は 何が 違うのですか
カーネル
Python の open と os.open は 何が 違うのですか
os.open はopen() は
write システムコールの 引数は何ですか
write のsyscall を
確認クイズ
答えだと
1 問目
システムコールの
2 問目
open の
3 問目
この
「あ」を 1 字書く
import os
f = os.O_WRONLY | os.O_CREAT
fd = os.open("sc_q.txt", f)
b = "あ".encode()
print(os.write(fd, b))
os.close(fd)
os.remove("sc_q.txt")4 問目
os.close(fd) のfd を os.read(fd, 1) に
説明課題
次の 2 行で、裏で OS が
説明する 2 行
with open("memo.txt") as f:
data = f.read()- どの
システムコールが、 どの 順で 呼ばれるか - それぞれに
何を 渡し、 何が返るか - 失敗したら
何が返るか
自分の
この回の 先の一歩
「ファイルが
もっと深く
この
一次資料
どれも 2026年10月27日に開いて、
- intro(2) (Linux man-pages、英語)。ラッパー関数が番号と
引数を レジスタに 置いて カーネルモードへ 移り、 失敗なら errno を 置いて -1 を返すこと - syscalls(2) (Linux man-pages、英語)。アプリとカーネルの基本の
接点である こと、 名前の一覧 - syscall(2) (Linux man-pages、英語)。x86-64 の
syscallの命令と、 rax、 rdi、 rsi、 rdx の使い方 - syscall_64.tbl (Linux の
ソース、英語) 。read 0、write 1、 open 2、 close 3、 openat 257 の番号 - open(2) (Linux man-pages、英語)。一番小さい
空き番号が 返る こと、 ENOENT と EMFILE、 glibc 2.26 から openat を使うこと - read(2) (Linux man-pages、英語)。0 がファイルの終わりで、
少なく 返っても 失敗ではないこと - write(2) (Linux man-pages、英語)。書けた
バイト数か -1 を返すこと - close(2) (Linux man-pages、英語)。閉じた
番号が 使い回されること - stdin(3) (Linux man-pages、英語)。標準入力、
標準出力、 標準エラーが 0、 1、 2 であること - errno(3) (Linux man-pages、英語)。EBADF と
ENOENT の意味 - strace(1) (Linux man-pages、英語)。出力の例と、
-e trace=%file、-c、-pの働き - os (Python 公式文書、英語)。
os.open、os.read、os.writeの戻り値 - Built-in Functions (Python 公式文書、英語)。
open()が多くの環境で 128 KB ほど ためて書くこと - CVE-2016-5195 (CVE の
記録、 。4.8.3 よりMITRE の API、英語) 前の カーネルの 競合状態で 読むだけの 写しに 書けたこと、2016 年 10 月の悪用 - Meltdown (Lipp ほか、
arXiv、英語) 。2018 年 1 月 3 日の公開、カーネルのメモリを読めた こと、 原因が ハードウェアで KAISER が 妨げること
