From ca2e81eb1f1bcb3c43cc14d60969650af181d82f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Nov 2010 21:53:35 +0100 Subject: [PATCH] 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. --- src/agent.c | 20 ++++++++++--------- src/libssh2_priv.h | 11 ++++------- src/misc.c | 49 ++++++++++++++++++++++++---------------------- src/scp.c | 20 ++++--------------- src/session.c | 10 +++++----- src/transport.c | 16 +++++++-------- 6 files changed, 58 insertions(+), 68 deletions(-) diff --git a/src/agent.c b/src/agent.c index 8cc46a1..7f315d6 100644 --- a/src/agent.c +++ b/src/agent.c @@ -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"); diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index ad841f8..364ba05 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -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 */ diff --git a/src/misc.c b/src/misc.c index 8809b6b..cbea039 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2007 Sara Golemon - * 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 */ diff --git a/src/scp.c b/src/scp.c index 5e3b056..cb709d2 100644 --- a/src/scp.c +++ b/src/scp.c @@ -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; diff --git a/src/session.c b/src/session.c index 90dbb81..7934c8c 100644 --- a/src/session.c +++ b/src/session.c @@ -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; diff --git a/src/transport.c b/src/transport.c index 093ed39..f186253 100644 --- a/src/transport.c +++ b/src/transport.c @@ -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;