mirror of
				https://github.com/libssh2/libssh2.git
				synced 2025-11-03 22:13:11 +03:00 
			
		
		
		
	_libssh2_channel_write: general code cleanup
simplified the function and removed some unused struct fields
This commit is contained in:
		
							
								
								
									
										159
									
								
								src/channel.c
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								src/channel.c
									
									
									
									
									
								
							@@ -1994,8 +1994,6 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
 | 
				
			|||||||
        buflen = 32700;
 | 
					        buflen = 32700;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (channel->write_state == libssh2_NB_state_idle) {
 | 
					    if (channel->write_state == libssh2_NB_state_idle) {
 | 
				
			||||||
        channel->write_bufwrote = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
					        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
				
			||||||
                       "Writing %d bytes on channel %lu/%lu, stream #%d",
 | 
					                       "Writing %d bytes on channel %lu/%lu, stream #%d",
 | 
				
			||||||
                       (int) buflen, channel->local.id, channel->remote.id,
 | 
					                       (int) buflen, channel->local.id, channel->remote.id,
 | 
				
			||||||
@@ -2012,104 +2010,97 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
 | 
				
			|||||||
                                  "data might be ignored");
 | 
					                                  "data might be ignored");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] +
 | 
					 | 
				
			||||||
           buflen(4) */
 | 
					 | 
				
			||||||
        channel->write_packet_len = (stream_id ? 13 : 9);
 | 
					 | 
				
			||||||
        channel->write_state = libssh2_NB_state_allocated;
 | 
					        channel->write_state = libssh2_NB_state_allocated;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Deduct the amount that has already been sent, and set buf accordingly. */
 | 
					 | 
				
			||||||
    buflen -= channel->write_bufwrote;
 | 
					 | 
				
			||||||
    buf += channel->write_bufwrote;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (buflen > 0) {
 | 
					    if (channel->write_state == libssh2_NB_state_allocated) {
 | 
				
			||||||
        if (channel->write_state == libssh2_NB_state_allocated) {
 | 
					        unsigned char *s = channel->write_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* drain the incoming flow first */
 | 
					        /* drain the incoming flow first */
 | 
				
			||||||
            do
 | 
					        do
 | 
				
			||||||
                rc = _libssh2_transport_read(session);
 | 
					            rc = _libssh2_transport_read(session);
 | 
				
			||||||
            while (rc > 0);
 | 
					        while (rc > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(channel->local.window_size <= 0) {
 | 
					        if(channel->local.window_size <= 0) {
 | 
				
			||||||
                /* there's no more room for data so we stop sending now */
 | 
					            /* there's no room for data so we stop */
 | 
				
			||||||
                break;
 | 
					            channel->write_state = libssh2_NB_state_idle;
 | 
				
			||||||
            }
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            channel->write_bufwrite = buflen;
 | 
					        channel->write_bufwrite = buflen;
 | 
				
			||||||
            channel->write_s = channel->write_packet;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            *(channel->write_s++) =
 | 
					        *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
 | 
				
			||||||
                stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
 | 
					            SSH_MSG_CHANNEL_DATA;
 | 
				
			||||||
                SSH_MSG_CHANNEL_DATA;
 | 
					        _libssh2_store_u32(&s, channel->remote.id);
 | 
				
			||||||
            _libssh2_store_u32(&channel->write_s, channel->remote.id);
 | 
					        if (stream_id)
 | 
				
			||||||
            if (stream_id)
 | 
					            _libssh2_store_u32(&s, stream_id);
 | 
				
			||||||
                _libssh2_store_u32(&channel->write_s, stream_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* Don't exceed the remote end's limits */
 | 
					 | 
				
			||||||
            /* REMEMBER local means local as the SOURCE of the data */
 | 
					 | 
				
			||||||
            if (channel->write_bufwrite > channel->local.window_size) {
 | 
					 | 
				
			||||||
                _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
					 | 
				
			||||||
                               "Splitting write block due to %lu byte "
 | 
					 | 
				
			||||||
                               "window_size on %lu/%lu/%d",
 | 
					 | 
				
			||||||
                               channel->local.window_size, channel->local.id,
 | 
					 | 
				
			||||||
                               channel->remote.id, stream_id);
 | 
					 | 
				
			||||||
                channel->write_bufwrite = channel->local.window_size;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (channel->write_bufwrite > channel->local.packet_size) {
 | 
					 | 
				
			||||||
                _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
					 | 
				
			||||||
                               "Splitting write block due to %lu byte "
 | 
					 | 
				
			||||||
                               "packet_size on %lu/%lu/%d",
 | 
					 | 
				
			||||||
                               channel->local.packet_size, channel->local.id,
 | 
					 | 
				
			||||||
                               channel->remote.id, stream_id);
 | 
					 | 
				
			||||||
                channel->write_bufwrite = channel->local.packet_size;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            /* store the size here only, the buffer is passed in as-is to
 | 
					 | 
				
			||||||
               _libssh2_transport_send() */
 | 
					 | 
				
			||||||
            _libssh2_store_u32(&channel->write_s, channel->write_bufwrite);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Don't exceed the remote end's limits */
 | 
				
			||||||
 | 
					        /* REMEMBER local means local as the SOURCE of the data */
 | 
				
			||||||
 | 
					        if (channel->write_bufwrite > channel->local.window_size) {
 | 
				
			||||||
            _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
					            _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
				
			||||||
                           "Sending %d bytes on channel %lu/%lu, stream_id=%d",
 | 
					                           "Splitting write block due to %lu byte "
 | 
				
			||||||
                           (int) channel->write_bufwrite, channel->local.id,
 | 
					                           "window_size on %lu/%lu/%d",
 | 
				
			||||||
 | 
					                           channel->local.window_size, channel->local.id,
 | 
				
			||||||
                           channel->remote.id, stream_id);
 | 
					                           channel->remote.id, stream_id);
 | 
				
			||||||
 | 
					            channel->write_bufwrite = channel->local.window_size;
 | 
				
			||||||
            channel->write_state = libssh2_NB_state_created;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (channel->write_bufwrite > channel->local.packet_size) {
 | 
				
			||||||
        if (channel->write_state == libssh2_NB_state_created) {
 | 
					            _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
				
			||||||
            rc = _libssh2_transport_send(session, channel->write_packet,
 | 
					                           "Splitting write block due to %lu byte "
 | 
				
			||||||
                                         channel->write_s -
 | 
					                           "packet_size on %lu/%lu/%d",
 | 
				
			||||||
                                         channel->write_packet,
 | 
					                           channel->local.packet_size, channel->local.id,
 | 
				
			||||||
                                         buf, channel->write_bufwrite);
 | 
					                           channel->remote.id, stream_id);
 | 
				
			||||||
            if (rc == LIBSSH2_ERROR_EAGAIN) {
 | 
					            channel->write_bufwrite = channel->local.packet_size;
 | 
				
			||||||
                return _libssh2_error(session, rc,
 | 
					 | 
				
			||||||
                                      "Unable to send channel data");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (rc) {
 | 
					 | 
				
			||||||
                channel->write_state = libssh2_NB_state_idle;
 | 
					 | 
				
			||||||
                return _libssh2_error(session, rc,
 | 
					 | 
				
			||||||
                                      "Unable to send channel data");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            /* Shrink local window size */
 | 
					 | 
				
			||||||
            channel->local.window_size -= channel->write_bufwrite;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            wrote += channel->write_bufwrite;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* Since _libssh2_transport_write() succeeded, we must return
 | 
					 | 
				
			||||||
               now to allow the caller to provide the next chunk of data.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
               We cannot move on to send the next piece of data that may
 | 
					 | 
				
			||||||
               already have been provided in this same function call, as we
 | 
					 | 
				
			||||||
               risk getting EAGAIN for that and we can't return information
 | 
					 | 
				
			||||||
               both about sent data as well as EAGAIN. So, by returning short
 | 
					 | 
				
			||||||
               now, the caller will call this function again with new data to
 | 
					 | 
				
			||||||
               send */
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        /* store the size here only, the buffer is passed in as-is to
 | 
				
			||||||
 | 
					           _libssh2_transport_send() */
 | 
				
			||||||
 | 
					        _libssh2_store_u32(&s, channel->write_bufwrite);
 | 
				
			||||||
 | 
					        channel->write_packet_len = s - channel->write_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _libssh2_debug(session, LIBSSH2_TRACE_CONN,
 | 
				
			||||||
 | 
					                       "Sending %d bytes on channel %lu/%lu, stream_id=%d",
 | 
				
			||||||
 | 
					                       (int) channel->write_bufwrite, channel->local.id,
 | 
				
			||||||
 | 
					                       channel->remote.id, stream_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        channel->write_state = libssh2_NB_state_created;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    channel->write_state = libssh2_NB_state_idle;
 | 
					    if (channel->write_state == libssh2_NB_state_created) {
 | 
				
			||||||
 | 
					        rc = _libssh2_transport_send(session, channel->write_packet,
 | 
				
			||||||
 | 
					                                     channel->write_packet_len,
 | 
				
			||||||
 | 
					                                     buf, channel->write_bufwrite);
 | 
				
			||||||
 | 
					        if (rc == LIBSSH2_ERROR_EAGAIN) {
 | 
				
			||||||
 | 
					            return _libssh2_error(session, rc,
 | 
				
			||||||
 | 
					                                  "Unable to send channel data");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (rc) {
 | 
				
			||||||
 | 
					            channel->write_state = libssh2_NB_state_idle;
 | 
				
			||||||
 | 
					            return _libssh2_error(session, rc,
 | 
				
			||||||
 | 
					                                  "Unable to send channel data");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /* Shrink local window size */
 | 
				
			||||||
 | 
					        channel->local.window_size -= channel->write_bufwrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return wrote;
 | 
					        wrote += channel->write_bufwrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Since _libssh2_transport_write() succeeded, we must return
 | 
				
			||||||
 | 
					           now to allow the caller to provide the next chunk of data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           We cannot move on to send the next piece of data that may
 | 
				
			||||||
 | 
					           already have been provided in this same function call, as we
 | 
				
			||||||
 | 
					           risk getting EAGAIN for that and we can't return information
 | 
				
			||||||
 | 
					           both about sent data as well as EAGAIN. So, by returning short
 | 
				
			||||||
 | 
					           now, the caller will call this function again with new data to
 | 
				
			||||||
 | 
					           send */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        channel->write_state = libssh2_NB_state_idle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return wrote;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -398,9 +398,7 @@ struct _LIBSSH2_CHANNEL
 | 
				
			|||||||
    /* State variables used in libssh2_channel_write_ex() */
 | 
					    /* State variables used in libssh2_channel_write_ex() */
 | 
				
			||||||
    libssh2_nonblocking_states write_state;
 | 
					    libssh2_nonblocking_states write_state;
 | 
				
			||||||
    unsigned char write_packet[13];
 | 
					    unsigned char write_packet[13];
 | 
				
			||||||
    unsigned char *write_s;
 | 
					 | 
				
			||||||
    size_t write_packet_len;
 | 
					    size_t write_packet_len;
 | 
				
			||||||
    size_t write_bufwrote;
 | 
					 | 
				
			||||||
    size_t write_bufwrite;
 | 
					    size_t write_bufwrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* State variables used in libssh2_channel_close() */
 | 
					    /* State variables used in libssh2_channel_close() */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user