send/recv: use _libssh2_recv and _libssh2_send now

Starting now, we unconditionally use the internal replacement functions
for send() and recv() - creatively named _libssh2_recv() and
_libssh2_send().

On errors, these functions return the negative 'errno' value instead of
the traditional -1. This design allows systems that have no "natural"
errno support to not have to invent it. It also means that no code
outside of these two transfer functions should use the errno variable.
This commit is contained in:
Daniel Stenberg 2010-11-12 21:53:35 +01:00
parent aff9c825c8
commit ca2e81eb1f
6 changed files with 58 additions and 68 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 by Daiki Ueno
* Copyright (C) 2010 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -176,9 +177,9 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Send the length of the request */
if (transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, transctx->request_len);
rc = send(agent->fd, buf, sizeof buf, 0);
rc = _libssh2_send(agent->fd, buf, sizeof buf, 0);
if (rc < 0) {
if (errno == EAGAIN)
if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
@ -188,10 +189,10 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Send the request body */
if (transctx->state == agent_NB_state_request_length_sent) {
rc = send(agent->fd, transctx->request,
transctx->request_len, 0);
rc = _libssh2_send(agent->fd, transctx->request,
transctx->request_len, 0);
if (rc < 0) {
if (errno == EAGAIN)
if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
@ -201,9 +202,9 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Receive the length of a response */
if (transctx->state == agent_NB_state_request_sent) {
rc = recv(agent->fd, buf, sizeof buf, 0);
rc = _libssh2_recv(agent->fd, buf, sizeof buf, 0);
if (rc < 0) {
if (errno == EAGAIN)
if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
@ -219,9 +220,10 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Receive the response body */
if (transctx->state == agent_NB_state_response_length_received) {
rc = recv(agent->fd, transctx->response, transctx->response_len, 0);
rc = _libssh2_recv(agent->fd, transctx->response,
transctx->response_len, 0);
if (rc < 0) {
if (errno == EAGAIN)
if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent recv failed");

View File

@ -998,13 +998,10 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
#define SSH_OPEN_UNKNOWN_CHANNELTYPE 3
#define SSH_OPEN_RESOURCE_SHORTAGE 4
#if defined( WIN32 ) || defined( __VMS )
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags);
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags);
#else
#define _libssh2_recv(a,b,c,d) recv(a,b,c,d)
#define _libssh2_send(a,b,c,d) send(a,b,c,d)
#endif
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer,
size_t length, int flags);
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
size_t length, int flags);
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
@ -89,53 +89,56 @@ static int wsa2errno(void)
}
#endif
#ifndef _libssh2_recv
/* _libssh2_recv
*
* Wrapper around standard recv to allow WIN32 systems
* to set errno
* Replacement for the standard recv, return -errno on failure.
*/
ssize_t
_libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags)
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags)
{
ssize_t rc = recv(socket, buffer, length, flags);
ssize_t rc = recv(sock, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
#ifdef __VMS
return -wsa2errno();
#elsif defined(__VMS)
if (rc < 0 ){
if ( errno == EWOULDBLOCK ) errno = EAGAIN;
if ( errno == EWOULDBLOCK )
return -EAGAIN;
else
return -errno;
}
#else
if (rc < 0 )
return -errno;
#endif
return rc;
}
#endif /* _libssh2_recv */
#ifndef _libssh2_send
/* _libssh2_send
*
* Wrapper around standard send to allow WIN32 systems
* to set errno
* Replacement for the standard send, return -errno on failure.
*/
ssize_t
_libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length,
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
int flags)
{
ssize_t rc = send(socket, buffer, length, flags);
ssize_t rc = send(sock, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
#ifdef VMS
if (rc < 0 ){
if ( errno == EWOULDBLOCK ) errno = EAGAIN;
return -wsa2errno();
#elsif defined(__VMS)
if (rc < 0 ) {
if ( errno == EWOULDBLOCK )
return -EAGAIN;
else
return -errno;
}
#else
if (rc < 0 )
return -errno;
#endif
return rc;
}
#endif /* _libssh2_recv */
/* libssh2_ntohu32
*/

View File

@ -510,13 +510,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
*(p++) = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
if (errno) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mtime");
goto scp_recv_error;
}
s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */
@ -537,13 +532,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
*p = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_atime = strtol((char *) s, NULL, 10);
if (errno) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid atime");
goto scp_recv_error;
}
/* SCP ACK */
session->scpRecv_response[0] = '\0';
@ -676,9 +665,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
*(p++) = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_mode = strtol(s, &e, 8);
if ((e && *e) || errno) {
if (e && *e) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode");
goto scp_recv_error;
@ -694,9 +683,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
*s = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_size = scpsize_strtol(p, &e, 10);
if ((e && *e) || errno) {
if (e && *e) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size");
goto scp_recv_error;

View File

@ -115,17 +115,17 @@ banner_receive(LIBSSH2_SESSION * session)
ret = _libssh2_recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (ret < 0) {
if(session->api_block_mode || (errno != EAGAIN))
if(session->api_block_mode || (ret != -EAGAIN))
/* ignore EAGAIN when non-blocking */
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error recving %d bytes: %d", 1, errno);
"Error recving %d bytes: %d", 1, -ret);
}
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Recved %d bytes banner", ret);
if (ret < 0) {
if (errno == EAGAIN) {
if (ret == -EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
session->banner_TxRx_total_send = banner_len;
@ -231,7 +231,7 @@ banner_send(LIBSSH2_SESSION * session)
if (ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d",
banner_len - session->banner_TxRx_total_send, errno);
banner_len - session->banner_TxRx_total_send, -ret);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Sent %d/%d bytes at %p+%d", ret,
@ -239,7 +239,7 @@ banner_send(LIBSSH2_SESSION * session)
banner, session->banner_TxRx_total_send);
if (ret != (banner_len - session->banner_TxRx_total_send)) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
if ((ret > 0) || ((ret == -1) && (ret == -EAGAIN))) {
/* the whole packet could not be sent, save the what was */
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;

View File

@ -347,17 +347,17 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
_libssh2_recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) {
if (nread <= 0) {
/* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */
if ((nread < 0) && (errno == EAGAIN)) {
if ((nread < 0) && (nread == -EAGAIN)) {
session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND;
return LIBSSH2_ERROR_EAGAIN;
}
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error recving %d bytes (got %d): %d",
PACKETBUFSIZE - remainbuf, nread, errno);
"Error recving %d bytes (got %d)",
PACKETBUFSIZE - remainbuf, -nread);
return LIBSSH2_ERROR_SOCKET_RECV;
}
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
@ -600,7 +600,7 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (rc < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", length, errno);
"Error sending %d bytes: %d", length, -rc);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
@ -621,7 +621,7 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
}
else if (rc < 0) {
/* nothing was sent */
if (errno != EAGAIN)
if (rc != -EAGAIN)
/* send failure! */
return LIBSSH2_ERROR_SOCKET_SEND;
@ -812,7 +812,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", total_length, errno);
"Error sending %d bytes: %d", total_length, -ret);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
ret, total_length, p->outbuf);
@ -821,7 +821,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
}
if (ret != total_length) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
if ((ret > 0) || ((ret == -1) && (ret == -EAGAIN))) {
/* the whole packet could not be sent, save the rest */
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
p->odata = orgdata;