/** * @file sc_errno.c * @bried エラー番号、エラーメッセージを扱うモジュール。 * @author Nomura Kei * @copyright 2003 - 2022 Nomura Kei */ #ifndef __STDC_WANT_LIB_EXT1__ #define __STDC_WANT_LIB_EXT1__ (1) #endif #include <sc.h> #include <sc_threads.h> #include <sc_errno.h> #ifndef MAXMSG #define MAXMSG (256) #endif static thread_local char sc_error_message[MAXMSG]; /** * エラー番号に対応するメッセージを取得します。 * エラーメッセージは、buf に格納されます。 * * buf が NULL または、 buflen が 0 の場合、 * ライブラリ内で保持しているスレッドローカル変数に * メッセージが格納され、そのポインタを返します。 * * @param buf エラーメッセージを格納するバッファ * @param buflen バッファサイズ * @param errnum エラー番号 * @return エラーメッセージへのポインタ */ const char* sc_get_errmsg(char* buf, size_t buflen, int errnum) { char* bufptr = buf; size_t bufptrlen = buflen; if ((buf == NULL) || (buflen <= 0)) { bufptr = sc_error_message; bufptrlen = MAXMSG; } memset(bufptr, '\0', bufptrlen); #ifdef __STDC_LIB_EXT1__ // C++ 標準の strerror_s が利用可能 errno_t ret = strerror_s(bufptr, bufptrlen, errnum); #elif (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) \ ||(defined(__XOPEN_SOURCE) && (__XOPEN_SOURCE >= 600)) // XSI準拠 strerror_r が利用可能 int ret = strerror_r(errnum, bufptr, bufptrlen); #else // 上記以外の場合 ANSI 準拠 strerror(errnum) を使用する。 char* tmpmsg = strerror(errnum); strncpy(bufptr, tmpmsg, bufptrlen); bufptr[bufptrlen - 1] = '\0'; int ret = 0; #endif if (ret == 0) { return bufptr; } return ""; }