新城@筑波大学情報です。こんにちは。

In article <86wu822g18.wl@xh6.cc.hokudai.ac.jp>
        Hiroki Kashiwazaki <reo@cc.hokudai.ac.jp> writes:
> そこでちゃんと戻り値を見ようという事で、今書いているコードの中に
> 頻出する strncpy について考える時、
> char *strncpy (char *s1, const char *s2, size_t n);
> で、s1の値が返される訳ですが、

strncpy() の戻り値は、元々、意味的に調べる必要はありません。
雰囲気として
        if( (x = y) == z ) ...
と書くのを真似て、
        if( strcmp(strcpy(x,y),z)==0 ) ...
と書きやすくしただけなので。

バッファ・オーバーフローを防ぐには、strncpy() は実は今一つで
す。n を取りますが、最後に埋めるだけなので。結構、誤用される
関数だと思います。私もだいぶ長い間誤用していた気がします。

本当は、strlcpy() がいいんですよね。FreeBSD のマニュアルより。
------------------------------------------------------------
STRLCPY(3)             FreeBSD Library Functions Manual             STRLCPY(3)

NAME
     strlcpy, strlcat - size-bounded string copying and concatenation

SYNOPSIS
     #include <string.h>

     size_t
     strlcpy(char *dst, const char *src, size_t size)

     size_t
     strlcat(char *dst, const char *src, size_t size)

DESCRIPTION
     The strlcpy() and strlcat() functions copy and concatenate strings re-
     spectively.  They are designed to be safer, more consistent, and less er-
     ror prone replacements for strncpy(3) and strncat(3).  Unlike those func-
     tions, strlcpy() and strlcat() take the full size of the buffer (not just
     the length) and guarantee to NUL-terminate the result (as long as size is
     larger than 0).  Note that you should include a byte for the NUL in size.

     The strlcpy() function copies up to size - 1 characters from the NUL-ter-
     minated string src to dst, NUL-terminating the result.

     The strlcat() function appends the NUL-terminated string src to the end
     of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
     nating the result.

RETURN VALUES
     The strlcpy() and strlcat() functions return the total length of the
     string they tried to create.  For strlcpy() that means the length of src.
     For strlcat() that means the initial length of dst plus the length of
     src. While this may seem somewhat confusing it was done to make trunca-
     tion detection simple.
------------------------------------------------------------

単にバッファ・オーバーフローを防ぎたいだけならこうします。
------------------------------------------------------------
           char *s, *p, buf[BUFSIZ];
           ...
           (void)strlcpy(buf, s, sizeof(buf));
           (void)strlcat(buf, p, sizeof(buf));
------------------------------------------------------------
後ろがちょん切れてもいいなら、結果を調べる必要はありません。
(あ、(void)だ。)

後ろが切れてはいけないなら、こうします。
------------------------------------------------------------
           char *dir, *file, pname[MAXPATHNAMELEN];
           ...
           if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
                   goto toolong;
           if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
                   goto toolong;
------------------------------------------------------------

ただ、strlcpy() は、Linux に入ってなくて困るんですよね。しょ
うがないので代りに snprintf() を使うように勧めているんですけ
ど。いくら snprintf() を使えと言っても、strcpy() とか 
strcat() 使う人が多くて困ります。どうしたらいいでしょうか。

ライブラリ関数の名前の影響は怖いですね。

\\ 新城 靖 (しんじょう やすし) \\
\\ 筑波大学 電子・情報       \\