Let we collect all cases to file description error cases.
Until now, we use strerror_r return type value to print error logs.
But it will not works at XSI base kernel.
And also, strerror_r need a lots of parameters so the line of codes increased
wherever we want to print errno value.
So we can control both GNU and XSI case,
and easly check the error occured point.
Change-Id: Ice950acacf7cefc1e3dc3c1427342b91cfa66b5b
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/integration-api/debug.h>
+// INTERNAL INCLUDES
+#include <dali/internal/system/common/system-error-print.h>
+
namespace Dali
{
namespace Internal
if(file.seekg(0, std::ios::beg).good() == false)
{
DALI_LOG_ERROR("Failed to seek the beginning of the file: \"%s\"\n", filename.c_str());
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return errorCode;
}
if(file.read(reinterpret_cast<char*>(memblock.Begin()), fileSize).good() == false)
{
DALI_LOG_ERROR("Failed to read the file: \"%s\"\n", filename.c_str());
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return errorCode;
}
file.close();
}
else
{
- char buf[512];
- DALI_LOG_ERROR("file open failed for: \"%s\", error : %s\n", filename.c_str(), strerror_r(errno, buf, 512));
+ DALI_LOG_ERROR("file open failed for: \"%s\"\n", filename.c_str());
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
return errorCode;
size = file.tellg();
file.close();
}
+ else
+ {
+ DALI_LOG_ERROR("file open failed for: \"%s\"\n", filename.c_str());
+ DALI_PRINT_SYSTEM_ERROR_LOG();
+ }
return size;
}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/integration-api/debug.h>
+// INTERNAL INCLUDES
+#include <dali/internal/system/common/system-error-print.h>
+
namespace Dali
{
FileStream::Impl::Impl(const std::string& filename, uint8_t mode)
if(closeFailed)
{
DALI_LOG_WARNING("File close failed for FILE: \"%p\".\n", static_cast<void*>(mFile));
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
mFile = nullptr;
if(!mFileStream.is_open())
{
DALI_LOG_WARNING("stream open failed for: \"%s\", in mode: \"%d\".\n", mFileName.c_str(), openMode);
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
return mFileStream;
}
static_cast<void*>(mBuffer),
static_cast<unsigned>(mDataSize),
openMode);
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
mFile = fopen(mFileName.c_str(), openMode);
if(!mFile)
{
- char buf[512];
DALI_LOG_ERROR("file open failed for: \"%s\", in mode: \"%s\".\n", mFileName.c_str(), openMode);
- DALI_LOG_ERROR("file open failed error : %s\n", strerror_r(errno, buf, 512));
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
else if(mBuffer)
mFile = fmemopen(mBuffer, mDataSize, openMode);
if(!mFile)
{
- char buf[512];
DALI_LOG_ERROR("File open failed for memory buffer at location: \"%p\", of size: \"%u\", in mode: \"%s\".\n",
static_cast<void*>(mBuffer),
static_cast<unsigned>(mDataSize),
openMode);
- DALI_LOG_ERROR("file open failed error : %s\n", strerror_r(errno, buf, 512));
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/imaging/common/image-loader.h>
#include <dali/internal/imaging/common/pixel-buffer-impl.h>
#include <dali/internal/system/common/file-reader.h>
+#include <dali/internal/system/common/system-error-print.h>
namespace Dali
{
}
else
{
- DALI_LOG_ERROR("std::ostream.write failed!\n");
+ DALI_LOG_ERROR("std::ostream.write failed! [numBytes:%d]\n", numBytes);
}
}
else
if(!result)
{
- const int errorMessageMaxLength = 128;
- char errorMessage[errorMessageMaxLength] = {}; // Initailze as null.
-
- // Return type of stderror_r is different between system type. We should not use return value.
- [[maybe_unused]] auto ret = strerror_r(errno, errorMessage, errorMessageMaxLength - 1);
-
- DALI_LOG_ERROR("Can't write to %s. buffer pointer : %p, length : %u, error message : [%s]\n", filename.c_str(), buffer, numBytes, errorMessage);
+ DALI_LOG_ERROR("Can't write to %s. buffer pointer : %p, length : %u\n", filename.c_str(), buffer, numBytes);
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
return result;
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <sys/types.h>
#include <unistd.h>
+// INTERNAL INCLUDES
+#include <dali/internal/system/common/system-error-print.h>
+
// Sockets enums like INADDR_ANY use C-Casts
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
if(mSocketFileDescriptor == -1)
{
DALI_LOG_ERROR("Unable to create socket\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
else
if(ret == -1)
{
DALI_LOG_ERROR("Socket close failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
return true;
if(ret == -1)
{
- char buf[512];
- DALI_LOG_ERROR("bind failed for port %d %s \n", port, strerror_r(errno, buf, 512));
+ DALI_LOG_ERROR("Socket bind failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
if(ret == -1)
{
DALI_LOG_ERROR("Listen failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
if(clientFileDescriptor == -1)
{
DALI_LOG_ERROR("Accept failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return NULL;
}
if(ret != 0)
{
DALI_LOG_ERROR("Pipe creation failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
mQuitPipeCreated = true;
if(ret == -1)
{
DALI_LOG_ERROR("select failed\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return ERROR;
}
else if(FD_ISSET(mQuitPipe[0], &readFileDescriptors))
if(ret < 1)
{
DALI_LOG_ERROR("ExitSelect failed!\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
return;
}
int ret = setsockopt(mSocketFileDescriptor, SOL_SOCKET, SO_REUSEADDR, &reUseInteger, sizeof(reUseInteger));
if(ret == -1)
{
- char buf[512];
- DALI_LOG_ERROR("SO_REUSEADDR option failed %s \n", strerror_r(errno, buf, 512));
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
return true;
if(ret == -1)
{
DALI_LOG_ERROR("SO_RCVBUF / SO_SNDBUF option failed \n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
return true;
return false;
}
- bytesRead = static_cast<unsigned int>(read(mSocketFileDescriptor, buffer, bufferSizeInBytes));
+ int ret = read(mSocketFileDescriptor, buffer, bufferSizeInBytes);
+ if(ret == -1)
+ {
+ DALI_LOG_ERROR("Socket read error \n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
+ return false;
+ }
+
+ bytesRead = static_cast<unsigned int>(ret);
return true;
}
if(ret < 1)
{
DALI_LOG_ERROR("Socket writer error \n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
return false;
}
else
--- /dev/null
+#ifndef DALI_TIZEN_SYSTEM_ERROR_PRINT_H
+#define DALI_TIZEN_SYSTEM_ERROR_PRINT_H
+
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/integration-api/debug.h>
+
+namespace Dali
+{
+namespace TizenPlatform
+{
+/**
+ * @brief Print errno and the error message to Dali::TizenPlatform::LogMessage as error level.
+ * Please use this function with DALI_PRINT_SYSTEM_ERROR_LOG macro
+ */
+void PrintSystemError(const char* fileName, const char* functionName, const int lineNumber);
+
+} // namespace TizenPlatform
+
+#ifndef DALI_PRINT_SYSTEM_ERROR_LOG
+#define DALI_PRINT_SYSTEM_ERROR_LOG() Dali::TizenPlatform::PrintSystemError(DALI_LOG_FORMAT_PREFIX_ARGS);
+#endif
+
+} // namespace Dali
+
+#endif // DALI_TIZEN_SYSTEM_ERROR_PRINT_H
// INTERNAL INCLUDES
#include <dali/internal/system/common/file-descriptor-monitor.h>
+#include <dali/internal/system/common/system-error-print.h>
#include <dali/internal/system/common/system-factory.h>
namespace Dali
else
{
DALI_LOG_ERROR("Unable to create TriggerEvent File descriptor\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
if(size != sizeof(uint64_t))
{
DALI_LOG_ERROR("Unable to write to UpdateEvent File descriptor\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
}
else
if(size != sizeof(uint64_t))
{
DALI_LOG_WARNING("Unable to read to UpdateEvent File descriptor\n");
+ DALI_PRINT_SYSTEM_ERROR_LOG();
}
// Save value to prevent duplicate deletion
# module: system, backend: linux
SET( adaptor_system_linux_src_files
${adaptor_system_dir}/common/shared-file.cpp
+ ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/glib/callback-manager-glib.cpp
${adaptor_system_dir}/glib/file-descriptor-monitor-glib.cpp
${adaptor_system_dir}/glib/timer-impl-glib.cpp
# module: system, backend: tizen-wayland
SET( adaptor_system_tizen_wayland_src_files
${adaptor_system_dir}/common/shared-file.cpp
+ ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
+ ${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/tizen-wayland/logging-tizen.cpp
${adaptor_system_dir}/tizen-wayland/system-settings-tizen.cpp
${adaptor_system_dir}/tizen-wayland/widget-application-impl-tizen.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/tizen-wayland/widget-controller-tizen.cpp
)
# module: system, backend: ubuntu-x11
SET( adaptor_system_ubuntu_x11_src_files
${adaptor_system_dir}/common/shared-file.cpp
+ ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
+ ${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/ubuntu-x11/logging-x.cpp
${adaptor_system_dir}/ubuntu-x11/system-settings-x.cpp
${adaptor_system_dir}/ubuntu-x11/widget-application-impl-x.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/ubuntu-x11/widget-controller-x.cpp
)
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/libuv/callback-manager-libuv.cpp
${adaptor_system_dir}/libuv/file-descriptor-monitor-libuv.cpp
${adaptor_system_dir}/libuv/system-factory-libuv.cpp
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/glib/callback-manager-glib.cpp
${adaptor_system_dir}/glib/file-descriptor-monitor-glib.cpp
${adaptor_system_dir}/glib/system-factory-glib.cpp
# module: system, backend: android
SET( adaptor_system_android_src_files
${adaptor_system_dir}/common/shared-file.cpp
+ ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/common/trigger-event.cpp
${adaptor_system_dir}/common/trigger-event-factory.cpp
${adaptor_system_dir}/android/callback-manager-android.cpp
${adaptor_system_dir}/android/system-factory-android.cpp
${adaptor_system_dir}/android/system-settings-android.cpp
${adaptor_system_dir}/android/timer-impl-android.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/android/widget-application-impl-android.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
)
# module: system, backend: windows
SET( adaptor_system_windows_src_files
+ ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/windows/callback-manager-win.cpp
${adaptor_system_dir}/windows/file-descriptor-monitor-windows.cpp
+ ${adaptor_system_dir}/windows/system-error-print-win.cpp
${adaptor_system_dir}/windows/system-factory-win.cpp
${adaptor_system_dir}/windows/system-settings-win.cpp
${adaptor_system_dir}/windows/timer-impl-win.cpp
${adaptor_system_dir}/windows/trigger-event-factory.cpp
${adaptor_system_dir}/windows/logging-win.cpp
${adaptor_system_dir}/windows/widget-application-impl-win.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/windows/widget-controller-win.cpp
)
# module: system, backend: macOS
SET( adaptor_system_macos_src_files
- ${adaptor_system_dir}/ubuntu-x11/logging-x.cpp
+ ${adaptor_system_dir}/common/shared-file.cpp
+ ${adaptor_system_dir}/common/time-service.cpp
+ ${adaptor_system_dir}/common/trigger-event-factory.cpp
+ ${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
+ ${adaptor_system_dir}/generic/system-error-print-generic.cpp
${adaptor_system_dir}/macos/file-descriptor-monitor-macos.cpp
${adaptor_system_dir}/macos/system-factory-mac.cpp
${adaptor_system_dir}/macos/system-settings-mac.cpp
${adaptor_system_dir}/macos/timer-impl-mac.cpp
- ${adaptor_system_dir}/common/shared-file.cpp
- ${adaptor_system_dir}/common/trigger-event-factory.cpp
- ${adaptor_system_dir}/generic/shared-file-operations-generic.cpp
- ${adaptor_system_dir}/common/time-service.cpp
${adaptor_system_dir}/macos/trigger-event.mm
${adaptor_system_dir}/macos/callback-manager-mac.mm
${adaptor_system_dir}/macos/widget-application-impl-mac.cpp
+ ${adaptor_system_dir}/ubuntu-x11/logging-x.cpp
)
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FUNCTION HEADER
+#include <dali/internal/system/common/system-error-print.h>
+
+// EXTERNAL INCLUDES
+#include <cerrno> ///< for errno
+#include <cstring> ///< for strerror_r
+#include <sstream> ///< for std::ostringstream
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali/internal/system/common/logging.h>
+
+namespace Dali
+{
+namespace TizenPlatform
+{
+namespace
+{
+// Reference : https://github.com/intel/intel-graphics-compiler/issues/213
+// Seperate function logic for GNU-specific and XSI-compliant by the type of return value.
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+// For GNU case
+std::string ConvertResultToString(const char* errorName, const char* /* not used */)
+{
+ return std::string(DALI_LIKELY(errorName) ? errorName : "null");
+}
+
+// For XSI case
+std::string ConvertResultToString(int /* not used */, const char* errorName)
+{
+ return std::string(DALI_LIKELY(errorName) ? errorName : "null");
+}
+#pragma GCC diagnostic pop
+} // namespace
+
+void PrintSystemError(const char* fileName, const char* functionName, const int lineNumber)
+{
+ std::ostringstream oss;
+
+ const static int errorMessageMaxLength = 128;
+ thread_local static char errorMessage[errorMessageMaxLength] = {}; // Initialze as null.
+
+ int copiedErrorNumber = errno;
+
+ auto reternValue = strerror_r(copiedErrorNumber, errorMessage, errorMessageMaxLength - 1);
+
+ if(DALI_LIKELY(fileName))
+ {
+ oss << fileName << ": ";
+ }
+ if(DALI_LIKELY(functionName))
+ {
+ oss << functionName << "";
+ }
+ oss << "(" << lineNumber << ") > ";
+
+ oss << "errno [" << copiedErrorNumber << "] ";
+ oss << ConvertResultToString(reternValue, static_cast<const char*>(&errorMessage[0])) << "\n";
+
+ std::string message = oss.str();
+ LogMessage(Dali::Integration::Log::DebugPriority::ERROR, message);
+}
+
+} // namespace TizenPlatform
+
+} // namespace Dali
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// WINDOWS INCLUDES
+#include <Windows.h> // For GetLastError and FormatMessage
+
+// Need to undef the following constants as they are defined in one of the headers in Windows.h but used in DALi (via debug.h)
+#undef TRANSPARENT // Used in constants.h
+#undef CopyMemory // Used in dali-vector.h
+
+// FUNCTION HEADER
+#include <dali/internal/system/common/system-error-print.h>
+
+// EXTERNAL INCLUDES
+#include <sstream> ///< for std::ostringstream
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali/internal/system/common/logging.h>
+
+namespace Dali
+{
+namespace TizenPlatform
+{
+void PrintSystemError(const char* fileName, const char* functionName, const int lineNumber)
+{
+ std::ostringstream oss;
+
+ // Windows error messages are very long! (error code 10401 message length is 2174)
+ // Use FormatMessage limitation length here : 65535
+ const static DWORD errorMessageMaxLength = 0xffff;
+ thread_local static char errorMessage[errorMessageMaxLength] = {}; // Initialze as null.
+
+ DWORD copiedErrorNumber = GetLastError();
+
+ // FORMAT_MESSAGE_IGNORE_INSERTS Should be used when we try to get FORMAT_MESSAGE_FROM_SYSTEM
+ DWORD errorMessageLength = FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, copiedErrorNumber, 0, (LPTSTR) & (&errorMessage[0]), errorMessageMaxLength - 1, NULL);
+
+ if(DALI_LIKELY(fileName))
+ {
+ oss << fileName << ": ";
+ }
+ if(DALI_LIKELY(functionName))
+ {
+ oss << functionName << "";
+ }
+ oss << "(" << lineNumber << ") > ";
+
+ oss << "errno [" << copiedErrorNumber << "] ";
+ oss << std::string(&errorMessage[0], (size_t)errorMessageLength) << "\n";
+
+ std::string message = oss.str();
+ LogMessage(Dali::Integration::Log::DebugPriority::ERROR, message);
+}
+
+} // namespace TizenPlatform
+
+} // namespace Dali