initiate disconnect on timeout in NETWrite

This commit is contained in:
zolliker
2008-01-18 07:14:13 +00:00
parent 87cef1c2a9
commit 59cf229551

124
network.c
View File

@ -39,6 +39,7 @@
----------------------------------------------------------------------------*/
#include "fortify.h"
#include "network.h"
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
@ -64,10 +65,15 @@ struct timeval lastclose={-1,0};
*/
#include "Scommon.h"
extern void SICSLogWrite(char *pText, OutCode eCode); /* servlog.c */
void WriteToCommandLog(char *p, char *t);
static void NetError(char *pText)
{
/*
SICSLogWrite(pText,eError);
*/
WriteToCommandLog("NET>", pText);
}
/* ---------------------------- Local ------------------------------------
@ -404,6 +410,7 @@ CreateSocketAdress(
else
{
strncpy(pCompost,host->h_name,iBufLen);
pCompost[iBufLen-1]='\0';
}
}
return 1;
@ -411,11 +418,15 @@ CreateSocketAdress(
/*--------------------------------------------------------------------------*/
int NETWrite(mkChannel *self, char *buffer, long lLen)
{
int iRet;
long iRet;
fd_set lMask;
struct timeval tmo ={0,1};
struct timeval tmo;
char buf[256];
time_t expire, delta;
char *pos;
long l;
int disconnected;
if(!VerifyChannel(self))
{
return 0;
@ -429,48 +440,83 @@ CreateSocketAdress(
* Check if the we can write to the socket first....
* Well, this how it should be. However, on linux I observe that
* there is a problem with Java clients not reliably receiving data when
* this is active.
* this is active.
*/
#ifndef CYGNUS
tmo.tv_usec = 10;
FD_ZERO(&lMask);
FD_SET(self->sockid,&lMask);
if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) )
/* invalid descriptor */
{
return -1; /* eof */
/* invalid descriptor */
return 0;
}
iRet = select( (self->sockid + 1),NULL, &lMask, NULL,&tmo);
if( iRet <= 0)
{
/* failure, or no data */
return -1;
}
/* blocking on write */
if(!FD_ISSET(self->sockid,&lMask))
{
return -2;
}
#endif
#ifdef DO_NOT_SELECT_BEFORE_SEND
iRet = send(self->sockid,buffer,lLen,0);
if(iRet != lLen)
{
if(iRet < 0)
{
if (errno != EPIPE) { /* do not write "broken pipe" error */
printf("System error: %s\n",strerror(errno));
}
} else {
printf("Incomplete send: %d to %ld\n",iRet,lLen);
}
if (iRet != lLen) {
self->iType = 0;
if (iRet < 0) {
if (errno == EPIPE) { /* do not write "broken pipe" error */
return 0;
}
else
{
return 1;
}
snprintf(buf, sizeof buf, "NETWrite: send system error: %s (socket %d)",
strerror(errno), self->sockid);
} else {
snprintf(buf, sizeof buf, "NETWrite: only %ld of %ld bytes sent (socket %d)",
iRet, lLen, self->sockid);
}
NetError(buf);
return 0;
} else {
return 1;
}
#endif
pos = buffer;
l = lLen;
FD_ZERO(&lMask);
disconnected = 0;
#define TIMEOUT 10
expire = time(NULL) + TIMEOUT;
while (l > 0) {
delta = expire - time(NULL);
if (delta <= 0) break;
FD_SET(self->sockid,&lMask);
tmo.tv_usec = 0;
tmo.tv_sec = delta;
iRet = select( (self->sockid + 1),NULL, &lMask, NULL,&tmo);
if (iRet < 0) {
/* failure, or no data */
self->iType = 0;
snprintf(buf, sizeof buf,
"NETWrite: failure on select before send: %s (socket %d)",
strerror(errno), self->sockid);
NetError(buf);
return 0;
}
if (!FD_ISSET(self->sockid,&lMask)) break;
iRet = send(self->sockid,pos,l,0);
disconnected = (iRet == 0);
if (iRet < 0) {
self->iType = 0;
if (errno == EPIPE || errno == ECONNRESET) { /* do not write these errors */
return 0;
}
snprintf(buf, sizeof buf, "NETWrite: send system error: %s (socket %d)",
strerror(errno), self->sockid);
NetError(buf);
return 0;
}
l -= iRet;
pos += iRet;
}
if (l > 0) {
self->iType = 0;
if (!disconnected) { /* do not write an error message on disconnect */
snprintf(buf, sizeof buf, "NETWrite: timeout, only %ld of %ld bytes sent (socket %d)",
lLen - l, lLen, self->sockid);
NetError(buf);
}
return 0;
}
return 1;
}
/* -------------------------------------------------------------------------*/
long NETRead(mkChannel *self, char *buffer, long lLen, long timeout)