Re: errno and library functions
# なんか書くのに体力使う….
In article <YAS.04Jul28213743@kirk.is.tsukuba.ac.jp>
yas@is.tsukuba.ac.jp (Yasushi Shinjo) writes:
> rename() は、BSD 系では、システムコールかなあ。
そうだと思います.
> f系のファイルにけっこうあますね。これはだいたいシステムコー
> ルと関係していそう
私の感覚では (建前上は) 関係していないことになって
います (fopen に owner とかの概念はありませんし).
ANSI Rationale にも「どんな C 言語環境でも動作する
ことを保証するため UNIX に依存するもの (open など
のシステムコール) は省かれた」とありました.
> remove() は、本当はライブラリではダメな気がします。unlink()
> して失敗したら rmdir() という方法だと、unlink() に失敗した後、
> rmdir() の前に、隙をついて何かやられるとうまくありません。
# 少なくとも FreeBSD は lstat → unlink or rmdir[*].
## 証明っぽいのも書いたけどとりあえず削除.
その「うまく」ない状況というのは, 実は atomic でも
「うまく」ない場合が多いので, 「何かやられる」こと
の方を問題とする (攻撃者がファイルを置き換えられる
ような構成にしない) のが普通でしょう.
# [*]: ネット上で「lstat → unlink の間にファイル
# を入れ替えられると任意のファイルを削除してしまう」
# という文章を見ましたが, これは remove のことを言っ
# ているのではなくて, 「確かに自分が作成したファイ
# ルかどうか」を i-node で見ても駄目だよね, という
# 話だと思いました (remove だと仮に atomic な操作
# にしても消えてしまうことは防げないので).
> ライブラリ関数(システムコールを伴わないはず)なのに失敗して
> errno に値を返すものがありますね。
関数の戻値がその型の範囲をカヴァーしてしまっている
ものなど, でしょう.
> strtol() とか。これも何か困る気がしたんだけど、
> 忘れました。
滞り無く処理が終了した場合でも errno が 0 になるこ
とはない (errno を上書きしてくれない) ということを
知らないと strtol のエラーは拾えません.
$ cat strtol_test.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int
main (int ac, char **av)
{
unsigned i;
for (i = 1; i < ac; i++)
{
char *endpos;
long l;
/* errno = 0; */
l = strtol (av[i], &endpos, 0);
if (errno)
perror (av[i]);
else
printf ("%ld %u\n", l, endpos - av[i]);
}
return 0;
}
$ cc -o strtol_test strtol_test.c
$ ./strtol_test 0xa a 0xa
10 3
a: Invalid argument
0xa: Invalid argument
$
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735