[Linux:Kernel] strncpy 대신 strlcpy

이 글에 있는 모든 코드는 GPL License를 따릅니다(All code attached is released under the GPL License in this article).

strncpy 에서는 source의 길이가 destination의 버퍼 길이와 같거나 더 길 경우, NUL-terminate되지 않는다. 구현이 다음과 같기 때문이다.

/**
 * strncpy – Copy a length-limited, %NUL-terminated string
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @count: The maximum number of bytes to copy
 *
 * The result is not %NUL-terminated if the source exceeds
 * @count bytes.
 *
 * In the case where the length of @src is less than  that  of
 * count, the remainder of @dest will be padded with %NUL.
 *
 */
char *strncpy(char *dest, const char *src, size_t count)
{
        char *tmp = dest;
        while (count) {
                if ((*tmp = *src) != 0)
                        src++;
                tmp++;
                count–;
        }
        return dest;
}

그래서 NUL-terminate를 보장하기 위한 함수가 있다 strlcpy 이다. 이 함수는 size-1 만큼의 string 복사와 함께 NULL로 끝남을 보장해 준다.

/**
 * strlcpy – Copy a %NUL terminated string into a sized buffer
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 * @size: size of destination buffer
 *
 * Compatible with *BSD: the result is always a valid
 * NUL-terminated string that fits in the buffer (unless,
 * of course, the buffer size is zero). It does not pad
 * out the result like strncpy() does.
 */
size_t strlcpy(char *dest, const char *src, size_t size)
{
        size_t ret = strlen(src);
        if (size) {
                size_t len = (ret >= size) ? size – 1 : ret;
                memcpy(dest, src, len);
                dest[len] = ‘\0’;
        }
        return ret;
}

strncpy를 strlcpy로 교체해야 할 것 같지만, 현재 커널에서는 둘 다 많이 사용되고 있다.
커널에서의 두 함수의 구현은 lib/string.c 에 있다.

참고 : http://lwn.net/Articles/33812/