From 307d911078e9c5f8932de09c3991ca909a836e91 Mon Sep 17 00:00:00 2001 From: Masayuki Yamamoto <15698961+ma8ma@users.noreply.github.com> Date: Sat, 23 Sep 2023 21:51:16 +0900 Subject: [PATCH] Reset errno to zero before calling functions (#1256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 関数を呼び出した後にerrnoの値をチェックする箇所では関数を呼び出す前に errnoを0にリセットします。 参考文献 - https://linuxjm.osdn.jp/html/LDP_man-pages/man3/errno.3.html - https://www.jpcert.or.jp/sc-rules/c-err30-c.html --- src/iomonitor.cpp | 2 ++ src/jdlib/jdiconv.cpp | 2 ++ src/jdlib/jdsocket.cpp | 11 +++++++++-- src/jdlib/jdsocketopenssl.h | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/iomonitor.cpp b/src/iomonitor.cpp index 457646cd5..f7a2b2c7b 100644 --- a/src/iomonitor.cpp +++ b/src/iomonitor.cpp @@ -64,6 +64,7 @@ void IOMonitor::init_connection() int mkfifo_status = -1; do_makefifo: + errno = 0; mkfifo_status = mkfifo( m_fifo_file.c_str(), O_RDWR | S_IRUSR | S_IWUSR ); // FIFO作成でエラーになった( 基本的に既にメインプロセスがある ) @@ -73,6 +74,7 @@ void IOMonitor::init_connection() if( errno == EEXIST ) { // FIFOを書き込み専用モードでオープン( ノンブロック ) + errno = 0; if( ( m_fifo_fd = open( m_fifo_file.c_str(), O_WRONLY | O_NONBLOCK ) ) == -1 ) { // 反対側が既にオープンされていない( 異常終了などでメインプロセスがない ) diff --git a/src/jdlib/jdiconv.cpp b/src/jdlib/jdiconv.cpp index 068130ef5..0905d8cea 100644 --- a/src/jdlib/jdiconv.cpp +++ b/src/jdlib/jdiconv.cpp @@ -58,6 +58,7 @@ Iconv::Iconv( const Encoding to, const Encoding from, const bool broken_sjis_be_ void Iconv::open_by_alternative_names( const char* to_str, const char* from_str ) { // "MS932"で失敗したら"CP932"で試してみる + errno = 0; if( m_enc_to == Encoding::sjis ) m_cd = g_iconv_open( "CP932", from_str ); else if( m_enc_from == Encoding::sjis ) m_cd = g_iconv_open( to_str, "CP932" ); @@ -150,6 +151,7 @@ std::string& Iconv::convert( char* str_in, std::size_t size_in, std::string& out std::size_t byte_left_in = buf_in_end - buf_in_tmp; std::size_t byte_left_out = buf_out_end - buf_out_tmp; + errno = 0; const int ret = g_iconv( m_cd, &buf_in_tmp, &byte_left_in, &buf_out_tmp, &byte_left_out ); #ifdef _DEBUG diff --git a/src/jdlib/jdsocket.cpp b/src/jdlib/jdsocket.cpp index 46ead6122..629a3a375 100644 --- a/src/jdlib/jdsocket.cpp +++ b/src/jdlib/jdsocket.cpp @@ -163,6 +163,7 @@ bool Socket::connect( const std::string& hostname, const std::string& port, cons } // connect peer + errno = 0; err = ::connect( m_soc, ainf->ai_addr, ainf->ai_addrlen ); if( err ) { // ノンブロックでまだ接続中 @@ -375,19 +376,24 @@ int Socket::write( const char* buf, const std::size_t bufsize ) return kSocket_ERR; } + int err; #ifdef MSG_NOSIGNAL + errno = 0; tmpsize = ::send( m_soc, buf + bufsize - send_size, send_size, MSG_NOSIGNAL ); + err = errno; #else // SolarisにはMSG_NOSIGNALが無いのでSIGPIPEをIGNOREする (FreeBSD4.11Rにもなかった) signal( SIGPIPE, SIG_IGN ); /* シグナルを無視する */ + errno = 0; tmpsize = ::send( m_soc, buf + bufsize - send_size, send_size, 0 ); + err = errno; signal( SIGPIPE, SIG_DFL ); /* 念のため戻す */ #endif // MSG_NOSIGNAL if( tmpsize == 0 - || ( tmpsize < 0 && !( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) ) ) + || ( tmpsize < 0 && !( err == EAGAIN || err == EWOULDBLOCK || err == EINTR ) ) ) { - m_errmsg = std::string{ "send failed: errno=" } + std::strerror( errno ); + m_errmsg = std::string{ "send failed: errno=" } + std::strerror( err ); return kSocket_ERR; } } @@ -432,6 +438,7 @@ int Socket::read( char* buf, const std::size_t bufsize ) return kSocket_ERR; } + errno = 0; ret = ::recv( m_soc, buf, bufsize, 0 ); if( ret < 0 && !( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) ) { diff --git a/src/jdlib/jdsocketopenssl.h b/src/jdlib/jdsocketopenssl.h index b16059d2d..508cf8d31 100644 --- a/src/jdlib/jdsocketopenssl.h +++ b/src/jdlib/jdsocketopenssl.h @@ -149,6 +149,7 @@ void Socket::tls_close() { int ret; + errno = 0; while( ( ret = SSL_shutdown( m_tls ) ) != 1 ) { WaitFor want_read = WaitFor::recv;