Newer
Older
project / modules / libsc / src / sc_errno.c
Nomura Kei on 26 Sep 2022 1 KB UPDATE
/**
 * @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 "";
}