Refactor _write_socket
Call real_write_all in write_lines and write_line. This should fix debian bug #542291. BIG thanks to Zygo Blaxell.
This commit is contained in:
parent
7546daa276
commit
70fbf99c7f
|
@ -235,46 +235,42 @@ static int _write_socket(connection_t *cn, char *message)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
size = strlen(message);
|
size = strlen(message);
|
||||||
|
if (size == 0)
|
||||||
|
return WRITE_OK;
|
||||||
|
/* loop if we wrote some data but not everything, or if error is
|
||||||
|
* EINTR */
|
||||||
do {
|
do {
|
||||||
count = write(cn->handle, ((const char *)message) + tcount,
|
count = write(cn->handle, ((const char *)message) + tcount,
|
||||||
size - tcount);
|
size - tcount);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
tcount += count;
|
tcount += count;
|
||||||
if (tcount == size)
|
if (tcount == size)
|
||||||
break;
|
return WRITE_OK;
|
||||||
}
|
}
|
||||||
} while (count < 0 && errno == EINTR);
|
} while (count > 0 || (count < 0 && errno == EINTR));
|
||||||
|
|
||||||
#if 0
|
/* If we reach this point, we have a partial write */
|
||||||
if (count <= 0 && tcount > 0)
|
assert(count != 0);
|
||||||
fatal("shit happens errno:%d count:%d tcount:%d (%s)\n", errno,
|
|
||||||
count, tcount, message);
|
|
||||||
#endif
|
|
||||||
if (tcount < size) {
|
|
||||||
/*
|
|
||||||
* if no fatal error, return WRITE_KEEP, which makes caller
|
|
||||||
* keep line in its FIFO
|
|
||||||
*
|
|
||||||
* Shitty: we might have written a partial line, so we hack the
|
|
||||||
* line...
|
|
||||||
* callers of _write_socket muse provide a writable memspace
|
|
||||||
*/
|
|
||||||
if (count < 0 && (errno == EAGAIN || errno == EINPROGRESS)) {
|
|
||||||
memmove(message, message + tcount, size - tcount + 1);
|
|
||||||
return WRITE_KEEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cn_is_connected(cn)) {
|
/* if no fatal error, return WRITE_KEEP, which makes caller keep line
|
||||||
mylog(LOG_DEBUGVERB, "write(fd %d) : %s", cn->handle,
|
* in its FIFO
|
||||||
strerror(errno));
|
*
|
||||||
connection_close(cn);
|
* Shitty: we might have written a partial line, so we hack the line...
|
||||||
cn->connected = CONN_ERROR;
|
* Callers of _write_socket muse provide a writable message
|
||||||
}
|
*/
|
||||||
mylog(LOG_DEBUGVERB, "write : %s", strerror(errno));
|
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
|
||||||
return WRITE_ERROR;
|
memmove(message, message + tcount, size - tcount + 1);
|
||||||
|
return WRITE_KEEP;
|
||||||
}
|
}
|
||||||
mylog(LOG_DEBUGVERB, "%d/%d bytes sent !", tcount, size);
|
/* other errors, EPIPE or worse, close the connection, repport error */
|
||||||
return WRITE_OK;
|
if (cn_is_connected(cn)) {
|
||||||
|
if (errno != EPIPE)
|
||||||
|
mylog(LOG_INFO, "Broken socket: %s.", strerror(errno));
|
||||||
|
connection_close(cn);
|
||||||
|
cn->connected = CONN_ERROR;
|
||||||
|
}
|
||||||
|
mylog(LOG_DEBUGVERB, "write: %d, %s", cn->handle, strerror(errno));
|
||||||
|
return WRITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_socket(connection_t *cn, char *line)
|
static int write_socket(connection_t *cn, char *line)
|
||||||
|
@ -343,12 +339,9 @@ void write_line_fast(connection_t *cn, char *line)
|
||||||
r = write_socket(cn, nline);
|
r = write_socket(cn, nline);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case WRITE_KEEP:
|
case WRITE_KEEP:
|
||||||
list_add_first(cn->outgoing, nline);
|
cn->partial = nline;
|
||||||
break;
|
break;
|
||||||
case WRITE_ERROR:
|
case WRITE_ERROR:
|
||||||
cn->connected = CONN_ERROR;
|
|
||||||
free(nline);
|
|
||||||
break;
|
|
||||||
case WRITE_OK:
|
case WRITE_OK:
|
||||||
free(nline);
|
free(nline);
|
||||||
break;
|
break;
|
||||||
|
@ -362,11 +355,13 @@ void write_line_fast(connection_t *cn, char *line)
|
||||||
void write_lines(connection_t *cn, list_t *lines)
|
void write_lines(connection_t *cn, list_t *lines)
|
||||||
{
|
{
|
||||||
list_append(cn->outgoing, lines);
|
list_append(cn->outgoing, lines);
|
||||||
|
real_write_all(cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_line(connection_t *cn, char *line)
|
void write_line(connection_t *cn, char *line)
|
||||||
{
|
{
|
||||||
list_add_last(cn->outgoing, bip_strdup(line));
|
list_add_last(cn->outgoing, bip_strdup(line));
|
||||||
|
real_write_all(cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_t *read_lines(connection_t *cn, int *error)
|
list_t *read_lines(connection_t *cn, int *error)
|
||||||
|
|
Loading…
Reference in New Issue