注) /dev/null じゃなくて /dev/full に関するエントリです。
/dev/full は何ですか?
write(2) すると必ず ENOSPC を返すキャラクタデバイスです。
$ echo hello > /dev/full -bash: echo: write error: No space left on device
「そういえば、こんなキャラクタデバイスあったな〜」と思って、Linux カーネルのソースを読み直しました
ChatGPT に聞いてソースを調べる
grep や GNU Global でシュっと見つからないので、slack-gpt に カーネルのソースがどこかと聞いたら一発で正解を出してくれた
こちらが slack-gpt が教えてくれた URL です
/dev/full のソース
/dev/full の write を処理するコードは write_full
でした。
static const struct file_operations full_fops = { .llseek = full_lseek, .read_iter = read_iter_zero, .write = write_full, 🤏 };
必ず -ENOSPC をかえす実装になっています。おもしろいですね
static ssize_t write_full(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { return -ENOSPC; 🤏 }
なお、/dev/full デバイスの定義は下記の通り。デバイスの初期化コードは長くなりそうなので スキップ
static const struct memdev { const char *name; umode_t mode; const struct file_operations *fops; fmode_t fmode; } devlist[] = { #ifdef CONFIG_DEVMEM [DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, #endif [3] = { "null", 0666, &null_fops, FMODE_NOWAIT }, #ifdef CONFIG_DEVPORT [4] = { "port", 0, &port_fops, 0 }, #endif [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT }, [7] = { "full", 0666, &full_fops, 0 }, 🤏 [8] = { "random", 0666, &random_fops, FMODE_NOWAIT }, [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT }, #ifdef CONFIG_PRINTK [11] = { "kmsg", 0644, &kmsg_fops, 0 }, #endif };
感想
- シンプルな実装で面白い。自分でも作れそう
- 「ソース読むか ... でもどこだろう ...? 」と迷子になったが、ChatGPT のガイドでたどり着けた。
参考
💡 slack-gpt は同僚の P山さんが開発している ChatGPT Slack ボットです