strerror_r возвращает корзину, когда я вручную установил errno во время тестирования - PullRequest
4 голосов
/ 16 июня 2010

Во время тестирования у меня есть фиктивный объект, который устанавливает errno = ETIMEDOUT; Тестируемый объект видит ошибку и вызывает strerror_r , чтобы вернуть строку ошибки:

if (ret) {
    if (ret == EAI_SYSTEM) {
        char err[128];
        strerror_r(errno, err, 128);
        err_string.assign(err);
    } else {
        err_string.assign(gai_strerror(ret));
    }
    return ret;
}

Я не понимаю, почему strerror_r возвращает мусор. Я даже пытался позвонить

strerror_r(ETIMEDOUT, err, 128)

прямо и до сих пор получил мусор. Я должен что-то упустить. Кажется, я получаю версию функции gnu, а не posix, но это не должно иметь никакого значения в этом случае.

Редактировать

Я нахожусь на Ubuntu 8.04. Версия glibc выглядит как 2.7 в features.h.

Ответы [ 2 ]

10 голосов
/ 16 июня 2010

Согласно этой странице, http://linux.die.net/man/3/strerror_r,, если вы используете версию GNU strerror_r(), функция может решить вообще ничего не сохранять в предоставленный вами буфер; вам нужно использовать строку, возвращаемую из функции (кажется довольно странным интерфейсом):

Специфичный для GNU strerror_r() возвращает указатель на строку, содержащую сообщение об ошибке. Это может быть либо указатель на строку, которую функция хранит в buf, либо указатель на некоторую (неизменяемую) статическую строку (в этом случае buf не используется). Если функция хранит строку в буфере, то сохраняется не более байтовых байтов (строка может быть усечена, если буфлен слишком мал), и строка всегда содержит завершающий нулевой байт.

Таким образом, если вы используете версию GNU, вы не можете полагаться на свой буфер err, чтобы вставить в него что-нибудь полезное, если strerror_r() не вернет адрес err.

4 голосов
/ 16 июня 2010

Проблема в том, что в Linux есть две функции strerror_r.Если вы читаете руководство,

   int strerror_r(int errnum, char *buf, size_t buflen);
               /* XSI-compliant */

   char *strerror_r(int errnum, char *buf, size_t buflen);
               /* GNU-specific */


The XSI-compliant version of strerror_r() is provided if:
       (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE

Компилятор g ++ автоматически определяет _GNU_SOURCE, поэтому вы используете версию функции GNU, которая не обязательно сохраняет сообщение в предоставленном вами буфере.

...