256 строки
7.1 KiB
C
256 строки
7.1 KiB
C
|
|
/*
|
|
* Copyright (c) 2002-2011 by XMLVM.org
|
|
*
|
|
* Project Info: http://www.xmlvm.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
* License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
* USA.
|
|
*/
|
|
|
|
#include "xmlvm.h"
|
|
#include "xmlvm-hy.h"
|
|
|
|
|
|
const char* errorMessage (I_32 errorCode)
|
|
{
|
|
PortlibPTBuffers_t ptBuffers;
|
|
|
|
ptBuffers = hyport_tls_peek ();
|
|
if (0 == ptBuffers->errorMessageBufferSize)
|
|
{
|
|
ptBuffers->errorMessageBuffer = XMLVM_ATOMIC_MALLOC(HYERROR_DEFAULT_BUFFER_SIZE);
|
|
if (NULL == ptBuffers->errorMessageBuffer)
|
|
{
|
|
return "";
|
|
}
|
|
ptBuffers->errorMessageBufferSize = HYERROR_DEFAULT_BUFFER_SIZE;
|
|
}
|
|
|
|
/* Copy from OS to ptBuffers */
|
|
#if !defined(ZOS)
|
|
strerror_r(errorCode,
|
|
ptBuffers->errorMessageBuffer, ptBuffers->errorMessageBufferSize);
|
|
#else
|
|
/* Do not have strerror_r on z/OS so use port library function instead */
|
|
portLibrary->str_printf(portLibrary, ptBuffers->errorMessageBuffer, ptBuffers->errorMessageBufferSize, strerror(errorCode));
|
|
#endif /* ZOS */
|
|
ptBuffers->errorMessageBuffer[ptBuffers->errorMessageBufferSize - 1] = '\0';
|
|
return ptBuffers->errorMessageBuffer;
|
|
}
|
|
|
|
|
|
static const char* swapMessageBuffer (PortlibPTBuffers_t ptBuffers, const char *message)
|
|
{
|
|
char *tempBuffer = ptBuffers->reportedMessageBuffer;
|
|
U_32 tempBufferSize = ptBuffers->reportedMessageBufferSize;
|
|
|
|
if (message == NULL)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/* Can't swap unknown message buffer */
|
|
if (message != ptBuffers->errorMessageBuffer)
|
|
{
|
|
return message;
|
|
}
|
|
|
|
/* Save reported information */
|
|
ptBuffers->reportedErrorCode = ptBuffers->portableErrorCode;
|
|
ptBuffers->reportedMessageBuffer = ptBuffers->errorMessageBuffer;
|
|
ptBuffers->reportedMessageBufferSize = ptBuffers->errorMessageBufferSize;
|
|
|
|
if (tempBufferSize > 0)
|
|
{
|
|
tempBuffer[0] = '\0';
|
|
}
|
|
|
|
/* Clear pending fields ready for next error */
|
|
ptBuffers->portableErrorCode = 0;
|
|
ptBuffers->errorMessageBuffer = tempBuffer;
|
|
ptBuffers->errorMessageBufferSize = tempBufferSize;
|
|
|
|
return ptBuffers->reportedMessageBuffer;
|
|
}
|
|
|
|
|
|
void* hyport_tls_get ()
|
|
{
|
|
java_lang_Thread* curThread = (java_lang_Thread*) java_lang_Thread_currentThread__();
|
|
if (curThread->fields.java_lang_Thread.ptBuffers_ == JAVA_NULL) {
|
|
curThread->fields.java_lang_Thread.ptBuffers_ = XMLVM_MALLOC(sizeof(PortlibPTBuffers_struct));
|
|
XMLVM_BZERO(curThread->fields.java_lang_Thread.ptBuffers_, sizeof(PortlibPTBuffers_struct));
|
|
}
|
|
|
|
return curThread->fields.java_lang_Thread.ptBuffers_;
|
|
}
|
|
|
|
|
|
void* hyport_tls_peek ()
|
|
{
|
|
java_lang_Thread* curThread = (java_lang_Thread*) java_lang_Thread_currentThread__();
|
|
return curThread->fields.java_lang_Thread.ptBuffers_;
|
|
}
|
|
|
|
|
|
const char* hyerror_last_error_message ()
|
|
{
|
|
PortlibPTBuffers_t ptBuffers;
|
|
|
|
/* Was an error saved ? */
|
|
ptBuffers = hyport_tls_peek ();
|
|
if (NULL == ptBuffers)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/* New error ? */
|
|
if (ptBuffers->portableErrorCode != 0)
|
|
{
|
|
const char *message = NULL;
|
|
|
|
/* Customized message stored ? */
|
|
if (ptBuffers->errorMessageBufferSize > 0)
|
|
{
|
|
if ('\0' != ptBuffers->errorMessageBuffer[0])
|
|
{
|
|
message = ptBuffers->errorMessageBuffer;
|
|
}
|
|
}
|
|
|
|
/* Call a helper to get the last message from the OS. */
|
|
if (message == NULL)
|
|
{
|
|
message = errorMessage (ptBuffers->platformErrorCode);
|
|
}
|
|
|
|
/* Avoid overwrite by internal portlib errors */
|
|
return swapMessageBuffer (ptBuffers, message);
|
|
}
|
|
|
|
/* Previous message stored ? */
|
|
if (ptBuffers->reportedMessageBufferSize > 0)
|
|
{
|
|
if ('\0' != ptBuffers->reportedMessageBuffer[0])
|
|
{
|
|
return ptBuffers->reportedMessageBuffer;
|
|
}
|
|
}
|
|
|
|
/* No error. */
|
|
return "";
|
|
}
|
|
|
|
|
|
I_32 hyerror_last_error_number ()
|
|
{
|
|
PortlibPTBuffers_t ptBuffers;
|
|
|
|
/* get the buffers, return failure if not present */
|
|
ptBuffers = hyport_tls_peek ();
|
|
if (NULL == ptBuffers)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* New error ? */
|
|
if (ptBuffers->portableErrorCode != 0)
|
|
{
|
|
return ptBuffers->portableErrorCode;
|
|
}
|
|
else
|
|
{
|
|
return ptBuffers->reportedErrorCode;
|
|
}
|
|
}
|
|
|
|
|
|
I_32 hyerror_set_last_error (I_32 platformCode, I_32 portableCode)
|
|
{
|
|
PortlibPTBuffers_t ptBuffers;
|
|
|
|
/* get the buffers, allocate if necessary.
|
|
* Silently return if not present, what else would the caller do anyway?
|
|
*/
|
|
ptBuffers = hyport_tls_get ();
|
|
if (NULL == ptBuffers)
|
|
{
|
|
return portableCode;
|
|
}
|
|
|
|
/* Save the last error */
|
|
ptBuffers->platformErrorCode = platformCode;
|
|
ptBuffers->portableErrorCode = portableCode;
|
|
|
|
/* Overwrite any customized messages stored */
|
|
if (ptBuffers->errorMessageBufferSize > 0)
|
|
{
|
|
ptBuffers->errorMessageBuffer[0] = '\0';
|
|
}
|
|
|
|
return portableCode;
|
|
}
|
|
|
|
|
|
I_32 hyerror_set_last_error_with_message (I_32 portableCode, const char *errorMessage)
|
|
{
|
|
PortlibPTBuffers_t ptBuffers;
|
|
U_32 requiredSize;
|
|
|
|
/* get the buffers, allocate if necessary.
|
|
* Silently return if not present, what else would the caller do anyway?
|
|
*/
|
|
ptBuffers = hyport_tls_get ();
|
|
if (NULL == ptBuffers)
|
|
{
|
|
return portableCode;
|
|
}
|
|
|
|
/* Save the last error */
|
|
ptBuffers->platformErrorCode = -1;
|
|
ptBuffers->portableErrorCode = portableCode;
|
|
|
|
/* Store the message, allocate a bigger buffer if required. Keep the old buffer around
|
|
* just in case memory can not be allocated
|
|
*/
|
|
requiredSize = strlen (errorMessage) + 1;
|
|
requiredSize =
|
|
requiredSize <
|
|
HYERROR_DEFAULT_BUFFER_SIZE ? HYERROR_DEFAULT_BUFFER_SIZE : requiredSize;
|
|
if (requiredSize > ptBuffers->errorMessageBufferSize)
|
|
{
|
|
char *newBuffer = XMLVM_ATOMIC_MALLOC(requiredSize);
|
|
if (NULL != newBuffer)
|
|
{
|
|
if (ptBuffers->errorMessageBuffer != NULL)
|
|
{
|
|
XMLVM_FREE(ptBuffers->errorMessageBuffer);
|
|
}
|
|
ptBuffers->errorMessageBuffer = newBuffer;
|
|
ptBuffers->errorMessageBufferSize = requiredSize;
|
|
}
|
|
}
|
|
|
|
/* Save the message */
|
|
if (ptBuffers->errorMessageBufferSize > 0)
|
|
{
|
|
sprintf(ptBuffers->errorMessageBuffer, "%s", errorMessage);
|
|
ptBuffers->errorMessageBuffer[ptBuffers->errorMessageBufferSize - 1] = '\0';
|
|
}
|
|
|
|
return portableCode;
|
|
}
|