# なんか書くのに体力使う…. 

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
$