#include /*
* connect within given timeout
*/
int
connect_timo(struct in_addr addr, u_short port, int seconds)
{
struct sockaddr_in server;
int sock;
fd_set fdw;
struct timeval timeout;
int fflag;
int errcode;
int errlen;
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = addr.s_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return -1;
}
if ((fflag = fcntl(sock, F_GETFL, 0)) < 0) {
close(sock);
return -2;
}
if (fcntl(sock, F_SETFL, fflag|O_NDELAY) < 0) {
close(sock);
return -3;
}
connect(sock, (struct sockaddr *)&server, sizeof(server));
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
FD_ZERO(&fdw);
FD_SET(sock, &fdw);
CNNT_AGAIN:
switch (select(sock + 1, NULL, &fdw, NULL, &timeout)) {
case -1:
if (errno == EINTR)
goto CNNT_AGAIN;
close(sock);
return -4;
case 0:
close(sock);
return -5;
default:
if (FD_ISSET(sock, &fdw)) {
errlen = sizeof(errcode);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR,
&errcode, (socklen_t *)&errlen) < 0) {
close(sock);
return -6;
}
if (errcode == 0) {
if (fcntl(sock, F_SETFL, fflag) < 0) {
close(sock);
return -7;
}
return (sock);
} else {
close(sock);
return -8;
}
}
}
return -1;
}
/*
* write exactly n chars
*/
int
writen(int fd, char *buffer, int length)
{
char *ptr;
int n, left = length;
ptr = buffer;
while (left) {
if ((n = send(fd, ptr, left, 0)) > 0) {
left -= n;
ptr += n;
} else
return -1;
}
return length;
}
/*
* read exactly n chars within given timeout
*/
int
readn(int fd, char *buffer, int length, int timo)
{
char *ptr;
int n, left = length;
fd_set fds;
int i, res, maxrcv = 16;
struct timeval wait;
wait.tv_sec = timo;
wait.tv_usec = 0;
if (length > 1024 * 16)
maxrcv = length / 1024;
ptr = buffer;
i = 0;
while (i++ < maxrcv && left != 0) {
FD_ZERO(&fds);
FD_SET(fd, &fds);
res = select(fd + 1, &fds, NULL, NULL, &wait);
if (res < 0) {
if (errno == EINTR) continue;
return -1;
} else if (res == 0) {
return (length - left);
}
n = recv(fd, ptr, left, 0);
if (n > 0) {
left -= n;
ptr += n;
} else if (n == 0) {
return (length - left);
} else {
return -1;
}
}
return (length - left);
}
---结束 ---