mirror of
https://github.com/curl/curl.git
synced 2025-10-01 00:16:48 +03:00
Fixed a problem where telnet data would be lost if an EWOULDBLOCK
condition were encountered.
This commit is contained in:
parent
ea86edbd82
commit
6f0a2608b4
4
CHANGES
4
CHANGES
|
@ -7,6 +7,10 @@
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
|
||||||
|
Daniel Fandrich (3 Jun 2008)
|
||||||
|
- Fixed a problem where telnet data would be lost if an EWOULDBLOCK
|
||||||
|
condition were encountered.
|
||||||
|
|
||||||
Marty Kuhrt (1 Jun 2008)
|
Marty Kuhrt (1 Jun 2008)
|
||||||
- Updated main.c to return CURLE_OK if PARAM_HELP_REQUESTED was returned
|
- Updated main.c to return CURLE_OK if PARAM_HELP_REQUESTED was returned
|
||||||
from getparameter instead of CURLE_FAILED_INIT. No point in returning
|
from getparameter instead of CURLE_FAILED_INIT. No point in returning
|
||||||
|
|
|
@ -40,6 +40,7 @@ This release includes the following bugfixes:
|
||||||
o follow redirect with only a new query string
|
o follow redirect with only a new query string
|
||||||
o SCP and SFTP memory leaks on aborted transfers
|
o SCP and SFTP memory leaks on aborted transfers
|
||||||
o curl_multi_socket() and HTTP pipelining transfer stalls
|
o curl_multi_socket() and HTTP pipelining transfer stalls
|
||||||
|
o lost telnet data on an EWOULDBLOCK condition
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
|
|
104
lib/telnet.c
104
lib/telnet.c
|
@ -1117,6 +1117,46 @@ void telrcv(struct connectdata *conn,
|
||||||
bufferflush();
|
bufferflush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Escape and send a telnet data block */
|
||||||
|
/* TODO: write large chunks of data instead of one byte at a time */
|
||||||
|
static CURLcode send_telnet_data(struct connectdata *conn,
|
||||||
|
char *buffer, ssize_t nread)
|
||||||
|
{
|
||||||
|
unsigned char outbuf[2];
|
||||||
|
ssize_t bytes_written, total_written;
|
||||||
|
int out_count;
|
||||||
|
CURLcode rc = CURLE_OK;
|
||||||
|
|
||||||
|
while(rc == CURLE_OK && nread--) {
|
||||||
|
outbuf[0] = *buffer++;
|
||||||
|
out_count = 1;
|
||||||
|
if(outbuf[0] == CURL_IAC)
|
||||||
|
outbuf[out_count++] = CURL_IAC;
|
||||||
|
|
||||||
|
total_written = 0;
|
||||||
|
do {
|
||||||
|
/* Make sure socket is writable to avoid EWOULDBLOCK condition */
|
||||||
|
struct pollfd pfd[1];
|
||||||
|
pfd[0].fd = conn->sock[FIRSTSOCKET];
|
||||||
|
pfd[0].events = POLLOUT;
|
||||||
|
switch (Curl_poll(pfd, 1, -1)) {
|
||||||
|
case -1: /* error, abort writing */
|
||||||
|
case 0: /* timeout (will never happen) */
|
||||||
|
rc = CURLE_SEND_ERROR;
|
||||||
|
break;
|
||||||
|
default: /* write! */
|
||||||
|
bytes_written = 0;
|
||||||
|
rc = Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf+total_written,
|
||||||
|
out_count-total_written, &bytes_written);
|
||||||
|
total_written += bytes_written;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* handle partial write */
|
||||||
|
} while (rc == CURLE_OK && total_written < out_count);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode telnet_done(struct connectdata *conn,
|
static CURLcode telnet_done(struct connectdata *conn,
|
||||||
CURLcode status, bool premature)
|
CURLcode status, bool premature)
|
||||||
{
|
{
|
||||||
|
@ -1270,63 +1310,45 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||||
switch(waitret) {
|
switch(waitret) {
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
{
|
{
|
||||||
unsigned char outbuf[2];
|
|
||||||
int out_count = 0;
|
|
||||||
ssize_t bytes_written;
|
|
||||||
char *buffer = buf;
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
|
if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
|
code = CURLE_READ_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nread = readfile_read;
|
|
||||||
|
|
||||||
if(!nread)
|
if(!readfile_read)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||||
&readfile_read, NULL)) {
|
&readfile_read, NULL)) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
|
code = CURLE_READ_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nread = readfile_read;
|
|
||||||
|
|
||||||
while(nread--) {
|
code = send_telnet_data(conn, buf, readfile_read);
|
||||||
outbuf[0] = *buffer++;
|
if(code) {
|
||||||
out_count = 1;
|
keepon = FALSE;
|
||||||
if(outbuf[0] == CURL_IAC)
|
break;
|
||||||
outbuf[out_count++] = CURL_IAC;
|
}
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
|
||||||
out_count, &bytes_written);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
{
|
{
|
||||||
unsigned char outbuf[2];
|
|
||||||
int out_count = 0;
|
|
||||||
ssize_t bytes_written;
|
|
||||||
char *buffer = buf;
|
|
||||||
|
|
||||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||||
&readfile_read, NULL)) {
|
&readfile_read, NULL)) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
|
code = CURLE_READ_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nread = readfile_read;
|
|
||||||
|
|
||||||
while(nread--) {
|
code = send_telnet_data(conn, buf, readfile_read);
|
||||||
outbuf[0] = *buffer++;
|
if(code) {
|
||||||
out_count = 1;
|
keepon = FALSE;
|
||||||
if(outbuf[0] == CURL_IAC)
|
break;
|
||||||
outbuf[out_count++] = CURL_IAC;
|
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
|
||||||
out_count, &bytes_written);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1389,22 +1411,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||||
break;
|
break;
|
||||||
default: /* read! */
|
default: /* read! */
|
||||||
if(pfd[1].revents & POLLIN) { /* read from stdin */
|
if(pfd[1].revents & POLLIN) { /* read from stdin */
|
||||||
unsigned char outbuf[2];
|
|
||||||
int out_count = 0;
|
|
||||||
ssize_t bytes_written;
|
|
||||||
char *buffer = buf;
|
|
||||||
|
|
||||||
nread = read(0, buf, 255);
|
nread = read(0, buf, 255);
|
||||||
|
code = send_telnet_data(conn, buf, nread);
|
||||||
while(nread--) {
|
if(code) {
|
||||||
outbuf[0] = *buffer++;
|
keepon = FALSE;
|
||||||
out_count = 1;
|
break;
|
||||||
if(outbuf[0] == CURL_IAC)
|
}
|
||||||
outbuf[out_count++] = CURL_IAC;
|
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
|
||||||
out_count, &bytes_written);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pfd[0].revents & POLLIN) {
|
if(pfd[0].revents & POLLIN) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user