1
1

_libssh2_error: Support allocating the error message

Before this patch "_libssh2_error" required the error message to be a
static string.

This patch adds a new function "_libssh2_error_flags" accepting an
additional "flags" argument and specifically the flag
"LIBSSH2_ERR_FLAG_DUP" indicating that the passed string must be
duplicated into the heap.

Then, the method "_libssh2_error" has been rewritten to use that new
function under the hood.

Signed-off-by: Salvador Fandino <sfandino@yahoo.com>
Signed-off-by: Salvador Fandiño <sfandino@yahoo.com>
Этот коммит содержится в:
Salvador Fandino 2015-10-21 15:03:02 +02:00 коммит произвёл Daniel Stenberg
родитель d441da3086
Коммит ad23faaae6
4 изменённых файлов: 37 добавлений и 2 удалений

Просмотреть файл

@ -631,6 +631,7 @@ struct _LIBSSH2_SESSION
/* Error tracking */
const char *err_msg;
int err_code;
int err_flags;
/* struct members for packet-level reading */
struct transportpacket packet;
@ -950,6 +951,10 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
/* Something very bad is going on */
#define LIBSSH2_MAC_INVALID -1
/* Flags for _libssh2_error_flags */
/* Error message is allocated on the heap */
#define LIBSSH2_ERR_FLAG_DUP 1
/* SSH Packet Types -- Defined by internet draft */
/* Transport Layer */
#define SSH_MSG_DISCONNECT 1

Просмотреть файл

@ -51,10 +51,29 @@
#include <stdio.h>
#include <errno.h>
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags)
{
session->err_msg = errmsg;
if (session->err_flags & LIBSSH2_ERR_FLAG_DUP)
LIBSSH2_FREE(session, (char *)session->err_msg);
session->err_code = errcode;
session->err_flags = 0;
if ((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
size_t len = strlen(errmsg);
char *copy = LIBSSH2_ALLOC(session, len + 1);
if (copy) {
memcpy(copy, errmsg, len + 1);
session->err_flags = LIBSSH2_ERR_FLAG_DUP;
session->err_msg = copy;
}
else
/* Out of memory: this code path is very unlikely */
session->err_msg = "former error forgotten (OOM)";
}
else
session->err_msg = errmsg;
#ifdef LIBSSH2DEBUG
if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode)
/* if this is EAGAIN and we're in non-blocking mode, don't generate
@ -67,6 +86,11 @@ int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
return errcode;
}
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
{
return _libssh2_error_flags(session, errcode, errmsg, 0);
}
#ifdef WIN32
static int wsa2errno(void)
{

Просмотреть файл

@ -49,6 +49,7 @@ struct list_node {
struct list_head *head;
};
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags);
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg);
void _libssh2_list_init(struct list_head *head);

Просмотреть файл

@ -1058,6 +1058,11 @@ session_free(LIBSSH2_SESSION *session)
LIBSSH2_FREE(session, session->server_hostkey);
}
/* error string */
if (session->err_msg && ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
LIBSSH2_FREE(session, (char *)session->err_msg);
}
LIBSSH2_FREE(session, session);
return 0;