summaryrefslogtreecommitdiff
path: root/lib/ZSendPkt.c
diff options
context:
space:
mode:
authorGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-05-16 23:09:00 +0000
committerGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-05-16 23:09:00 +0000
commitbd309016f254cedf2e00adaf1a0a739980e7125d (patch)
tree625def204c442d953bb46ac895fd5e76de5da333 /lib/ZSendPkt.c
parent6bd590358e9245aa37ef332d9a40c45e5f999cd2 (diff)
Really use select(), instead of just pretending to. Don't check if no
data is available.
Diffstat (limited to 'lib/ZSendPkt.c')
-rw-r--r--lib/ZSendPkt.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/lib/ZSendPkt.c b/lib/ZSendPkt.c
index bb45b1e..b4d6b1e 100644
--- a/lib/ZSendPkt.c
+++ b/lib/ZSendPkt.c
@@ -29,8 +29,9 @@ Code_t ZSendPacket(packet, len, waitforack)
int wait_for_hmack();
Code_t retval;
struct sockaddr_in dest;
- struct timeval tv;
- int i;
+ struct timeval tv, t0;
+ fd_set zfdmask;
+ int i, zfd;
ZNotice_t notice, acknotice;
if (!packet || len < 0)
@@ -55,25 +56,47 @@ Code_t ZSendPacket(packet, len, waitforack)
if ((retval = ZParseNotice(packet, len, &notice)) != ZERR_NONE)
return (retval);
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
-
- for (i=0;i<HM_TIMEOUT*2;i++) {
- if (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv) < 0)
- return (errno);
+ tv.tv_sec = HM_TIMEOUT;
+ tv.tv_usec = 0;
+ /* It is documented in select(2) that future versions of select
+ will adjust the passed timeout to indicate the time remaining.
+ When this is done, the variable t0 and all references to it
+ can be removed. */
+ gettimeofday(&t0, 0);
+ FD_ZERO(&zfdmask);
+ zfd = ZGetFD();
+ FD_SET(zfd, &zfdmask);
+ while(1) {
+ i = select(zfd + 1, &zfdmask, (fd_set *) 0, (fd_set *) 0, &tv);
+ if(i > 0) {
retval = ZCheckIfNotice(&acknotice, (struct sockaddr_in *)0,
wait_for_hmack, (char *)&notice.z_uid);
if (retval == ZERR_NONE) {
- ZFreeNotice(&acknotice);
- return (ZERR_NONE);
+ ZFreeNotice(&acknotice);
+ return (ZERR_NONE);
}
if (retval != ZERR_NONOTICE)
- return (retval);
+ return (retval);
+ } else if(i == 0) { /* time out */
+ return ZERR_HMDEAD;
+ } else if(i < 0 && errno != EINTR) {
+ return errno;
+ }
+ /* Here to end of loop deleted if/when select modifies passed timeout */
+ gettimeofday(&tv, 0);
+ tv.tv_usec = tv.tv_usec - t0.tv_usec;
+ if(tv.tv_usec < 0)
+ {
+ tv.tv_usec += 1000000;
+ tv.tv_sec = HM_TIMEOUT - 1 + tv.tv_sec - t0.tv_sec;
+ } else {
+ tv.tv_sec = HM_TIMEOUT + tv.tv_sec - t0.tv_sec;
+ }
}
return (ZERR_HMDEAD);
}
-static wait_for_hmack(notice, uid)
+static int wait_for_hmack(notice, uid)
ZNotice_t *notice;
ZUnique_Id_t *uid;
{