2014-05-21 :-)
_ 午前
1030 起床 && 1 回休み
1130 おひる。カレークリームスパゲティ && 今日は出かけようとしていたんだが雨なので腹いせにクリームソースを作った。最近は面倒くさいのであまり作らない。
_ 午後
1300 アニメ消化
_ [chmod][NetBSD][/bin/chmod][コードリーディング]NetBSD /bin/chmod を読む
処理の流れ。
main chmod または lchmod
chmod は libc の関数を使うのでぶっちゃけ main で完結してる。
main を読む。
最初に関数ポインタ変数を宣言している。これは後ほど使う。
int (*change_mode)(const char *, mode_t);
この 2 つ setlocale は /bin/cat でもやってたけどイディオムだろうか。
setprogname(argv[0]); (void)setlocale(LC_ALL, "");
オプション -h の処理
case 'h': /* * In System V the -h option causes chmod to * change the mode of the symbolic link. * 4.4BSD's symbolic links didn't have modes, * so it was an undocumented noop. In NetBSD * 1.3, lchmod(2) is introduced and this * option does real work. */ hflag = 1; break;
超訳「りりかる -h オプション 始まります」
System V の挙動にならったらしい。
-h が効くのがここ。main 関数chmod または lchmod を使う。change_mode は main 冒頭にあった関数ポインタ変数。
if (hflag) change_mode = lchmod; else change_mode = chmod;
ファイルの mode を変更する。
fts_open と fts_read はファイルシステムを渡り歩く fts_open - NetBSD Manual Pages
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) {
ここでファイルまたはディレクトリを渡り歩く。
for (rval = 0; (p = fts_read(ftsp)) != NULL;) { switch (p->fts_info) {
正味の mode 変更処理はここ。change_mode は先ほど chmod または lchmod が設定されている。どちらかを呼び出す。
if ((*change_mode)(p->fts_accpath, getmode(set, p->fts_statp->st_mode)) && !fflag) { warn("%s", p->fts_path); rval = 1; }
lchmod はここにある。結局 chmod を呼び出している。
src/tools/compat/lchmod.c
int lchmod(const char *path, mode_t mode) { struct stat psb; if (lstat(path, &psb) == -1) return -1; if (S_ISLNK(psb.st_mode)) { return 0; } return (chmod(path, mode)); }
chmod の定義がどうも chmod.S のようなんだが、chmod.S が見当たらない。
src/lib/libc/sys/Makefile.inc
# modules with default implementations on all architectures: ASM= access.S acct.S \ bind.S \ chdir.S chflags.S chmod.S chown.S chroot.S __clock_getres50.S \ __clock_gettime50.S \