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) 2009 by Daiki Ueno
* Copyright (C) 2010 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * 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 */ /* Send the length of the request */
if (transctx->state == agent_NB_state_request_created) { if (transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, transctx->request_len); _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 (rc < 0) {
if (errno == EAGAIN) if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed"); "agent send failed");
@ -188,10 +189,10 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Send the request body */ /* Send the request body */
if (transctx->state == agent_NB_state_request_length_sent) { if (transctx->state == agent_NB_state_request_length_sent) {
rc = send(agent->fd, transctx->request, rc = _libssh2_send(agent->fd, transctx->request,
transctx->request_len, 0); transctx->request_len, 0);
if (rc < 0) { if (rc < 0) {
if (errno == EAGAIN) if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed"); "agent send failed");
@ -201,9 +202,9 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Receive the length of a response */ /* Receive the length of a response */
if (transctx->state == agent_NB_state_request_sent) { 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 (rc < 0) {
if (errno == EAGAIN) if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed"); "agent recv failed");
@ -219,9 +220,10 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Receive the response body */ /* Receive the response body */
if (transctx->state == agent_NB_state_response_length_received) { 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 (rc < 0) {
if (errno == EAGAIN) if (rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent recv failed"); "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_UNKNOWN_CHANNELTYPE 3
#define SSH_OPEN_RESOURCE_SHORTAGE 4 #define SSH_OPEN_RESOURCE_SHORTAGE 4
#if defined( WIN32 ) || defined( __VMS ) ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer,
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags); size_t length, int flags);
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags); ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
#else size_t length, int flags);
#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
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when #define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */ waiting for more data to arrive */

View File

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

View File

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

View File

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