strerror_r함수에 관하여
글쓴이: bluesoho / 작성시간: 목, 2004/07/22 - 12:52오후
man에서 찾아보면 char *strerror_r(int errnum, char *buf, size_t len)라고 적혀있었습니다
그런데 아래와 같이 사용하니 buf엔 아무것도 없었습니다
왜 그런지 가르쳐주시면 고맙겠습니다
#include <stdio.h>
#include <errno.h>
#include <string.h>
char buf[256], *perr;
perr = strerror_r(EIO, buf, sizeof(buf));
if(perr)
{
printf("EIO Message: %s\n", perr); /* EIO Message: Input/output error*/
printf("EIO Message: %s\n", buf); /* EIO Message: */
printf("buf length: %d\n", strlen(buf)); /* buf length: 0 */
}
저의 리눅스 환경은 Fedora Core 2, GCC 3.3.3 입니다
Forums:
buf는 strerror_r함수가 필요할때 사용할수있도록 넘겨주는것입
buf는 strerror_r함수가 필요할때 사용할수있도록 넘겨주는
것입니다. 필요없으면 사용하질않고 또한 사용한다고 해도
그 안에 의미가 있는 데이타가 들어있다는 보장은 없습니다.
[quote="hwang"]buf는 strerror_r함수가 필요할때 사
아래의 내용은 저의 컴에서 copy해 온 것 입니다
이내용에 따르면 buf에 에러 메시지를 넣는다고 한것 같은데...
만약 그렇지 않다면 이 함수와 strerror()가 뭐가 다릅니까?
잘 이해되지 않습니다.
더 심입된 지도를 바랍니다.
고맙습니.
SYNOPSIS
#include <string.h>
char *strerror(int errnum);
int strerror_r(int errnum, char *buf, size_t n);
DESCRIPTION
The strerror() function returns a string describing the error code
passed in the argument errnum, possibly using the LC_MESSAGES part of
the current locale to select the appropriate language. This string
must not be modified by the application, but may be modified by a sub-
sequent call to perror() or strerror(). No library function will mod-
ify this string.
The strerror_r() function is similar to strerror(), but is thread safe.
It returns the string in the user-supplied buffer buf of length n.
RETURN VALUE
The strerror() function returns the appropriate error description
string, or an unknown error message if the error code is unknown. The
value of errno is not changed for a successful call, and is set to a
nonzero value upon error. The strerror_r() function returns 0 on suc-
cess and -1 on failure, setting errno.
ERRORS
EINVAL The value of errnum is not a valid error number.
ERANGE Insufficient storage was supplied to contain the error descrip-
tion string.
CONFORMING TO
SVID 3, POSIX, BSD 4.3, ISO/IEC 9899:1990 (C89).
strerror_r() with prototype as given above is specified by SUSv3, and
was in use under Digital Unix and HP Unix. An incompatible function,
with prototype
char *strerror_r(int errnum, char *buf, size_t n);
is a GNU extension used by glibc (since 2.0), and must be regarded as
obsolete in view of SUSv3. The GNU version may, but need not, use the
user-supplied buffer. If it does, the result may be truncated in case
the supplied buffer is too small. The result is always NUL-terminated.
SEE ALSO
errno(3), perror(3), strsignal(3)
2001-10-16 STRERROR(3)
strerror함수는 glibc의 경우 strerror_r을 결국 호출합
strerror함수는 glibc의 경우 strerror_r을 결국 호출합니다.
그때 사용하는 buf가 모든 strerror에서 같이 사용되기때문에
thread unsafe하게됩니다.
strerror_r의 return값이 이미 있는 constant string이라면
굳이 인자로 넘어왔던 buf를 사용하지않아도 아무 문제가 안됩니다.
그럴 경우 buf는 아무런 사용도 하지않은채 그냥 돌려줍니다.
manpage에 해답이 다 나와있습니다. :)[quote]int
manpage에 해답이 다 나와있습니다. :)
strerror_r 함수 리턴값은 int 형입니다.
성공하면 0 실패하면 -1을 반환합니다.
이 코드를
이런식으로 바꾸시면 됩니다.
[code:1]char *__strerror_r (int er
뭔지 모를 때는 소스를 보는게 제일이죠. 위 코드는 glibc 2.2.2 에서 얻은 것입니다.
잘보니, 인자로 넘겨 받는 버퍼는 Unknown error 4294967293 뭐 이런식으로 출력하는데 쓰이는 군요. errno 값을 음수로 넣어보시면 효과가 나타납니다.
본디 strerror 값은 readonly 이기 때문에 thread safety, reentrant가 보장될 것 같습니다. 다만, unknown error를 출력할 때 맨 뒤에 붙는 에러코드가 고민되는 상황이 되는 군요. 이 경우에만 buf를 사용하며, 그 때는 buf가 의미 있게 쓰이는 군요.
어쨌거나 return 값이 중요한 것이지 buf 는 내부에서만 사용하고 다른 용도(값을 받는)로는 더 사용하지 않습니다.
---
http://coolengineer.com
고맙습니다
고맙습니다
재미있는 점은 manpage 내용과 실제 헤더에 선언된 내용이 다르다는
재미있는 점은 manpage 내용과 실제 헤더에 선언된 내용이 다르다는 점입니다.
manpage에는
int strerror_r(int errnum, char *buf, size_t n);
그런데 /usr/include/string.h 파일을 보면
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) __THROW;
로 나옵니다. return type이 다르죠. :)
어느쪽이 실제 표준에 맞는 건가요?
덧) debian sid, libc-2.3.2.ds1-13 버전이 설치된 시스템에서 확인했습니다.
실은 info 페이지의 내용과 man 페이지의 내용도 일치하지 않습니다.
실은 info 페이지의 내용과 man 페이지의 내용도 일치하지 않습니다. :)
(제 시스템은 Fedora Core 1, 기본설정 그대로입니다.)
info 페이지 쪽의 내용이 헤더와 일치하더군요.
strerror_r 의 type이 다르다고만 생각하시는데, 아래 인용한
strerror_r 의 type이 다르다고만 생각하시는데, 아래 인용한 처음 man page에 두 개의 format이 다 나와 있으며, 각각 어떤 OS에서 사용하는지도 아주 친절하게 설명되어 있습니다.
UNIX에는 이런 류의 함수들이 수도 없이 많습니다. 이름은 같지만 인자나 return 값이 다른 것들 많죠..
gethostbyname_r 같은 함수는 인자를 받는 것이 UNIX 세계에서 무려 세 종류나 됩니다. ( http://www.gnu.org/software/ac-archive/htmldoc/ac_caolan_func_which_gethostbyname_r.html )
이런 것들 때문에 autoconf 라는 좋은 툴이 있습니다. 위의 예에 대한 것들은
http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_46.html
여기에서 찾아 보세요.
그리고 이런 종류의 autoconf 매크로는
http://www.gnu.org/software/ac-archive/htmldoc/index.html
에서 거의 다 찾을 수 있습니다.
---
http://coolengineer.com
man page 에 두 가지가 모두 등장하는 건 알고 있습니다. :) 다
man page 에 두 가지가 모두 등장하는 건 알고 있습니다. :) 다만 그 중 SYNOPSIS 에 등장하는 형식이 정작 시스템 상에서는 사용할 수 없는 형식이었다는 점이 문제죠. DESCRIPTION 역시 int 를 반환하는 strerror_r() 함수에 대한 설명이었기 때문에 역시 시스템 상에서는 맞지 않았고요.
pynoos 님은 man page 에 친절하게 설명돼있다고 하셨습니다만, 예를 들어 제 경우같은 초보자 수준에서는 SYNOPSIS 에 나온 형식이 틀려버리면 아주 당황스러운데다 man page 가 그다지 친절하게 읽히지도 않습니다. 정작 둘 중 어느 쪽을 써야 하는 건지, char * 를 반환하는 함수의 경우에 buf 는 뭐에다 쓰는 건지는 man page 만으로는 알 수가 없으니까요. 물론 소스를 뒤져보거나 하면 어렵지 않게 확인할 수 있겠습니다만, 드는 시간도 시간이려니와 처음 접하는 사람에게는 흔히 무리죠.
그러니 뭔가 이상할 경우에는 man page 말고도 info 를 써서 찾아보는 것도 좋다고 생각해서 적어둔 겁니다. man page 가 틀렸으니 믿지 말라는 얘기는 아닙니다. :)
망할 놈의(?) man page 군요. 우째 자기가 제공하는 것을 보이지
망할 놈의(?) man page 군요. 우째 자기가 제공하는 것을 보이지 않고 남의 prototype을 보인답니까... 원..
그리고 이런 괴리는 Redhat 9 부터 인것 같네요. 제 7.1 에서는
확인한 바에 의하면 redhat 9에 있는 glibc 2.3.2 에서 조차 glibc 2.2.x 에 있는 것과 동일한 코드를 사용합니다.
---
http://coolengineer.com
댓글 달기