Это правильный способ использования strerror_r?

Я предоставляю оболочку С++ для потокобезопасного strerror_r в следующем коде:

struct MyErrno {};
std::ostream& operator<<(std::stream& os, const MyErrno& err)
{
    const int len = 128
    char buf [len];
    os << strerror_r(errno, buf, len);
    return os;
}

Это просто простая оболочка, поэтому в коде C++ я могу сказать что-то вроде

<< MyErrno() << ..

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


person Palace Chan    schedule 21.02.2013    source источник
comment
У вас была конкретная проблема с этим кодом?   -  person Dark Falcon    schedule 21.02.2013


Ответы (1)


Я не понимаю всего контекста, в котором вы хотите это использовать (в частности, какова роль структуры MyErrno и что такое StreamErrno, поскольку ваше определение operator<< применяется к значению типа sockaddr_in, которое не используется).

Однако, в общих чертах, это небезопасный способ использования errno, хотя это совершенно безопасный способ использования strerror_r.

Проблема в том, что вы, скорее всего, используете это в таком контексте:

if ((something) != OK) {
  std::cerr << "Something bad happened: "
            << (some value which causes your function to be called)
            << ...
}

То есть, вероятно, будет какой-то системный вызов (вывод строки «Произошло что-то плохое») между системным вызовом, который завершился ошибкой, оставив значение в errno, и использованием errno в вашей функции. Практически любой системный вызов может привести к установке errno, даже если ошибка безобидна; следовательно, лучше всего получить значение errno немедленно. Это было бы хорошей причиной для использования пользовательского типа, такого как MyError:

struct MyError {
  int error;
  MyError(int err) : error(err) {}
};

std::ostream& operator<<(std::ostream& os, const MyError& e) {
  // as with your function, but using `e.error` instead of `errno`
}

if ((something) != OK) {
  MyError e(errno);
  std::cerr << "Something bad happened: " << e
            << ...
}
person rici    schedule 21.02.2013