Commit 5fc8b16d authored by Steven Murray's avatar Steven Murray
Browse files

Added utils::serrnoToString() and utils::errnoToString()

parent dbf4efd7
......@@ -300,10 +300,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult
// If fork failed
if(0 > forkRc) {
const std::string& errorMsg = "Failed to fork cleaner session for tape drive";
logForkError(errorMsg,params);
return createExceptionResult(SEINTERNAL, errorMsg, true);
return createExceptionResult(SEINTERNAL,
"Failed to fork cleaner session for tape drive", true);
// Else if this is the parent process
} else if(0 < forkRc) {
......@@ -358,9 +356,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult
// If fork failed
if(0 > forkRc) {
const std::string& errorMsg = "Failed to fork data-transfer session for tape drive";
logForkError(errorMsg,params);
return createExceptionResult(SEINTERNAL, errorMsg, true);
return createExceptionResult(SEINTERNAL,
"Failed to fork data-transfer session for tape drive", true);
// Else if this is the parent process
} else if(0 < forkRc) {
log::Param params[] = {log::Param("pid", forkRc)};
......@@ -411,11 +408,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult
// If fork failed
if(0 > forkRc) {
// Log an error message and return
const std::string& errorMsg = "Failed to fork label session for tape drive";
logForkError(errorMsg,params);
return createExceptionResult(SEINTERNAL, errorMsg, true);
return createExceptionResult(SEINTERNAL,
"Failed to fork label session for tape drive", true);
// Else if this is the parent process
} else if(0 < forkRc) {
......
......@@ -75,21 +75,8 @@ public:
*/
void execute() throw();
private:
/**
* Retrieve sstrerror_r['s messages and store it by adding a Parameter in params
* then log msg with all the params at level=LOG_ERR
* Used to handle the failure of a fork
* @param msg
* @param params
*/
template <class ParamContainer>
void logForkError(const std::string& msg,ParamContainer& params){
char message[100];
sstrerror_r(errno, message, sizeof(message));
params.push_back(log::Param("message", message));
m_log(LOG_ERR,msg,params);
}
private:
/**
* The maximum permitted size in bytes for the payload of a frame sent between
* the ProcessForker and its proxy.
......
......@@ -23,6 +23,7 @@
#include "castor/utils/utils.hpp"
#include <errno.h>
#include <gtest/gtest.h>
#include <list>
#include <stdlib.h>
......@@ -380,4 +381,18 @@ TEST_F(castor_utils, testCheckVidSyntaxInvalidCharacter) {
castor::exception::InvalidArgument);
}
TEST_F(castor_utils, testErrnoToString) {
using namespace castor::utils;
const std::string str = errnoToString(EACCES);
ASSERT_EQ(std::string("Permission denied"), str);
}
TEST_F(castor_utils, testSerrnoToString) {
using namespace castor::utils;
const std::string str = serrnoToString(SENOSHOST);
ASSERT_EQ(std::string("Host not known"), str);
}
} // namespace unitTests
......@@ -20,6 +20,7 @@
*****************************************************************************/
#include "castor/utils/utils.hpp"
#include "h/strerror_r_wrapper.h"
#include <algorithm>
#include <errno.h>
......@@ -334,13 +335,9 @@ bool castor::utils::getDumpableProcessAttribute() {
}
}
/**
* Sets the attributes of the current process to indicate hat it will produce a
* core dump if it receives a signal whose behaviour is to produce a core dump.
*
* @param dumpable true if the current program should be dumpable.
*/
//------------------------------------------------------------------------------
// setDumpableProcessAttribute
//------------------------------------------------------------------------------
void castor::utils::setDumpableProcessAttribute(const bool dumpable) {
const int rc = prctl(PR_SET_DUMPABLE, dumpable ? 1 : 0);
switch(rc) {
......@@ -365,3 +362,51 @@ void castor::utils::setDumpableProcessAttribute(const bool dumpable) {
}
}
}
//------------------------------------------------------------------------------
// errnoToString
//------------------------------------------------------------------------------
std::string castor::utils::errnoToString(const int errnoValue) throw() {
char buf[100];
if(!strerror_r_wrapper(errnoValue, buf, sizeof(buf))) {
return buf;
} else {
const int errnoSetByStrerror_r_wrapper = errno;
std::ostringstream oss;
switch(errnoSetByStrerror_r_wrapper) {
case EINVAL:
oss << "Failed to convert errnoValue to string: Invalid errnoValue"
": errnoValue=" << errnoValue;
break;
case ERANGE:
oss << "Failed to convert errnoValue to string"
": Destination buffer for error string is too small"
": errnoValue=" << errnoValue;
break;
default:
oss << "Failed to convert errnoValue to string"
": strerror_r_wrapper failed in an unknown way"
": errnoValue=" << errnoValue;
break;
}
return oss.str();
}
}
//------------------------------------------------------------------------------
// serrnoToString
//------------------------------------------------------------------------------
std::string castor::utils::serrnoToString(const int serrnoValue) throw() {
char buf[100];
if(!sstrerror_r(serrnoValue, buf, sizeof(buf))) {;
return buf;
} else {
std::ostringstream oss;
oss << "Failed to convert serrnoValue to string"
": sstrerror_r returned -1: serrnoValue=" << serrnoValue;
return oss.str();
}
}
......@@ -204,7 +204,12 @@ bool getDumpableProcessAttribute();
*/
void setDumpableProcessAttribute(const bool dumpable);
/**
* Determines the demangled type name of the specified object.
*
* @param t The object.
* @return The demangled type name.
*/
template <class T>std::string demangledNameOf(const T&t){
std::string responseType = typeid(t).name();
int status = -1;
......@@ -216,6 +221,27 @@ template <class T>std::string demangledNameOf(const T&t){
return responseType;
}
/**
* Determines the string representation of the specified error number.
*
* Please note this method is thread safe.
*
* @param errnoValue The errno value;
* @return The string representation of the specified CASTOR error number.
*/
std::string errnoToString(const int errnoValue) throw();
/**
* Determines the string representation of the specified CASTOR error number.
*
* Please note this method is thread safe.
*
* @param serrnoValue The serrno value;
* @return The string representation of the specified CASTOR error number.
*/
std::string serrnoToString(const int serrnoValue) throw();
} // namespace utils
} // namespace castor
......@@ -35,7 +35,7 @@
#define EDNSBASEOFF 3000 /* DNS error base offset */
#define SENOERR SEBASEOFF /* No error */
#define SENOSHOST SEBASEOFF+1 /* Host unknown */
#define SENOSHOST SEBASEOFF+1 /* Host not known */
#define SENOSSERV SEBASEOFF+2 /* Service unknown */
#define SENOTRFILE SEBASEOFF+3 /* Not a remote file */
#define SETIMEDOUT SEBASEOFF+4 /* Has timed out */
......
......@@ -81,7 +81,7 @@ The \fBserrno\fP variable is divided into common values and per package values,
The following error values might be returned by any package:
.TP 1.9i
.B SENOSHOST
(1001) Host unknown
(1001) Host not known
.TP
.B SENOSSERV
(1002) Service unknown
......
......@@ -56,6 +56,9 @@
* @param errnum The error number.
* @param buf The buffer.
* @param buflen The length of the buffer.
* @return 0 on success and -1 on error. If -1 is returned then errno is set
* to either EINVAL to indicate the error number is invalid, or to ERANGE to
* indicate the supplied error buffer is not large enough.
*/
EXTERN_C int strerror_r_wrapper(int errnum, char *buf, size_t buflen);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment