aboutsummaryrefslogtreecommitdiff
path: root/libssh/socket.c
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-04-14 14:12:50 +0000
committerAndreas Schneider <mail@cynapses.org>2009-04-14 14:12:50 +0000
commitd36a20884999d2f9455c2d6342b33698af9b4450 (patch)
tree1b7fc644dd0733f69c2a320220df909b69a6c31e /libssh/socket.c
parentfc1cba44073f819733ac59f40a4b5dc1b2fad5ae (diff)
downloadlibssh-d36a20884999d2f9455c2d6342b33698af9b4450.tar.gz
libssh-d36a20884999d2f9455c2d6342b33698af9b4450.tar.xz
libssh-d36a20884999d2f9455c2d6342b33698af9b4450.zip
Add more error checks to ssh_socket_wait_for_data().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@467 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh/socket.c')
-rw-r--r--libssh/socket.c131
1 files changed, 78 insertions, 53 deletions
diff --git a/libssh/socket.c b/libssh/socket.c
index 8e1e4be..4e842b1 100644
--- a/libssh/socket.c
+++ b/libssh/socket.c
@@ -386,65 +386,90 @@ int ssh_socket_write(struct socket *s, const void *buffer, int len) {
* \returns SSH_AGAIN need to call later for data
* \returns SSH_ERROR error happened
*/
-int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session, u32 len){
- int except, can_write;
- int to_read;
- int r;
- char *buf;
- char buffer[4096];
- enter_function();
- to_read=len - buffer_get_rest_len(s->in_buffer);
- if(to_read <= 0){
- leave_function();
- return SSH_OK;
+int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session, u32 len) {
+ char buffer[4096] = {0};
+ char *buf = NULL;
+ int except;
+ int can_write;
+ int to_read;
+ int r;
+
+ enter_function();
+
+ to_read = len - buffer_get_rest_len(s->in_buffer);
+
+ if (to_read <= 0) {
+ leave_function();
+ return SSH_OK;
+ }
+
+ if (session->blocking) {
+ buf = malloc(to_read);
+ if (buf == NULL) {
+ leave_function();
+ return SSH_ERROR;
}
- if(session->blocking){
- buf=malloc(to_read);
- if (buf == NULL) {
- leave_function();
- return SSH_ERROR;
- }
- r=ssh_socket_completeread(session->socket,buf,to_read);
- if(r==SSH_ERROR || r ==0){
- ssh_set_error(session,SSH_FATAL,
- (r==0)?"Connection closed by remote host" : "Error reading socket");
- ssh_socket_close(session->socket);
- session->alive=0;
- free(buf);
- leave_function();
- return SSH_ERROR;
- }
- buffer_add_data(s->in_buffer,buf,to_read);
- free(buf);
- leave_function();
- return SSH_OK;
+ r = ssh_socket_completeread(session->socket,buf,to_read);
+ if (r == SSH_ERROR || r == 0) {
+ ssh_set_error(session, SSH_FATAL,
+ (r == 0) ? "Connection closed by remote host" :
+ "Error reading socket");
+ ssh_socket_close(session->socket);
+ session->alive = 0;
+ SAFE_FREE(buf);
+
+ leave_function();
+ return SSH_ERROR;
}
- /* nonblocking read */
- do {
- ssh_socket_poll(s,&can_write,&except); /* internally sets data_to_read */
- if(!s->data_to_read){
- leave_function();
- return SSH_AGAIN;
- }
- /* read as much as we can */
- if(ssh_socket_is_open(session->socket))
- r=ssh_socket_unbuffered_read(session->socket,buffer,sizeof(buffer));
- else
- r=-1;
- if(r<=0){
- ssh_set_error(session,SSH_FATAL,
- (r==0)?"Connection closed by remote host" : "Error reading socket");
- ssh_socket_close(session->socket);
- session->alive=0;
- leave_function();
- return SSH_ERROR;
- }
- buffer_add_data(s->in_buffer,buffer, (u32) r);
- } while(buffer_get_rest_len(s->in_buffer)<len);
+ if (buffer_add_data(s->in_buffer,buf,to_read) < 0) {
+ SAFE_FREE(buf);
+ leave_function();
+ return SSH_ERROR;
+ }
+
+ SAFE_FREE(buf);
+
leave_function();
return SSH_OK;
+ }
+
+ /* nonblocking read */
+ do {
+ /* internally sets data_to_read */
+ r = ssh_socket_poll(s, &can_write, &except);
+ if (r < 0 || !s->data_to_read) {
+ leave_function();
+ return SSH_AGAIN;
+ }
+
+ /* read as much as we can */
+ if (ssh_socket_is_open(session->socket)) {
+ r = ssh_socket_unbuffered_read(session->socket, buffer, sizeof(buffer));
+ } else {
+ r =- 1;
+ }
+
+ if (r <= 0) {
+ ssh_set_error(session, SSH_FATAL,
+ (r == 0) ? "Connection closed by remote host" :
+ "Error reading socket");
+ ssh_socket_close(session->socket);
+ session->alive = 0;
+
+ leave_function();
+ return SSH_ERROR;
+ }
+
+ if (buffer_add_data(s->in_buffer,buffer, (u32) r) < 0) {
+ leave_function();
+ return SSH_ERROR;
+ }
+ } while(buffer_get_rest_len(s->in_buffer) < len);
+
+ leave_function();
+ return SSH_OK;
}
#ifdef USE_SELECT