mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
replaced the select() calls by poll()
This commit is contained in:
parent
5251c21479
commit
a1c0e96592
9 changed files with 118 additions and 70 deletions
3
CHANGES
3
CHANGES
|
@ -22,6 +22,9 @@ corrections:
|
||||||
|
|
||||||
improved test.sh script
|
improved test.sh script
|
||||||
|
|
||||||
|
replaced the select() calls by poll() to cleanly fix the problems with
|
||||||
|
many file descriptors already open
|
||||||
|
|
||||||
####################### V 1.6.0.1:
|
####################### V 1.6.0.1:
|
||||||
|
|
||||||
new features:
|
new features:
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics"
|
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll"
|
||||||
|
|
4
error.h
4
error.h
|
@ -50,6 +50,8 @@
|
||||||
#define Error6(m,a1,a2,a3,a4,a5,a6) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6)
|
#define Error6(m,a1,a2,a3,a4,a5,a6) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6)
|
||||||
#define Error7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7)
|
#define Error7(m,a1,a2,a3,a4,a5,a6,a7) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7)
|
||||||
#define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8)
|
#define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
|
#define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9)
|
||||||
|
#define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) msg(E_ERROR,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
#else /* !(WITH_MSGLEVEL >= E_ERROR) */
|
#else /* !(WITH_MSGLEVEL >= E_ERROR) */
|
||||||
#define Error(m)
|
#define Error(m)
|
||||||
#define Error1(m,a1)
|
#define Error1(m,a1)
|
||||||
|
@ -60,6 +62,8 @@
|
||||||
#define Error6(m,a1,a2,a3,a4,a5,a6)
|
#define Error6(m,a1,a2,a3,a4,a5,a6)
|
||||||
#define Error7(m,a1,a2,a3,a4,a5,a6,a7)
|
#define Error7(m,a1,a2,a3,a4,a5,a6,a7)
|
||||||
#define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8)
|
#define Error8(m,a1,a2,a3,a4,a5,a6,a7,a8)
|
||||||
|
#define Error9(m,a1,a2,a3,a4,a5,a6,a7,a8,a9)
|
||||||
|
#define Error10(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
|
||||||
#endif /* !(WITH_MSGLEVEL <= E_ERROR) */
|
#endif /* !(WITH_MSGLEVEL <= E_ERROR) */
|
||||||
|
|
||||||
#if WITH_MSGLEVEL <= E_WARN
|
#if WITH_MSGLEVEL <= E_WARN
|
||||||
|
|
110
socat.c
110
socat.c
|
@ -83,12 +83,16 @@ bool havelock;
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
const char **arg1, *a;
|
const char **arg1, *a;
|
||||||
|
char *mainwaitstring;
|
||||||
char buff[10];
|
char buff[10];
|
||||||
double rto;
|
double rto;
|
||||||
int i, argc0, result;
|
int i, argc0, result;
|
||||||
struct utsname ubuf;
|
struct utsname ubuf;
|
||||||
int lockrc;
|
int lockrc;
|
||||||
|
|
||||||
|
if (mainwaitstring = getenv("SOCAT_MAIN_WAIT")) {
|
||||||
|
sleep(atoi(mainwaitstring));
|
||||||
|
}
|
||||||
diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
|
diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
|
||||||
|
|
||||||
/* we must init before applying options because env settings have lower
|
/* we must init before applying options because env settings have lower
|
||||||
|
@ -642,37 +646,32 @@ int socat(const char *address1, const char *address2) {
|
||||||
returns >0 if child died and left data
|
returns >0 if child died and left data
|
||||||
*/
|
*/
|
||||||
int childleftdata(xiofile_t *xfd) {
|
int childleftdata(xiofile_t *xfd) {
|
||||||
fd_set in, out, expt;
|
struct pollfd in;
|
||||||
|
int timeout = 0; /* milliseconds */
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* have to check if a child process died before, but left read data */
|
/* have to check if a child process died before, but left read data */
|
||||||
if (XIO_READABLE(xfd) &&
|
if (XIO_READABLE(xfd) &&
|
||||||
(XIO_RDSTREAM(xfd)->howtoend == END_KILL ||
|
(XIO_RDSTREAM(xfd)->howtoend == END_KILL ||
|
||||||
XIO_RDSTREAM(xfd)->howtoend == END_CLOSE_KILL ||
|
XIO_RDSTREAM(xfd)->howtoend == END_CLOSE_KILL ||
|
||||||
XIO_RDSTREAM(xfd)->howtoend == END_SHUTDOWN_KILL) &&
|
XIO_RDSTREAM(xfd)->howtoend == END_SHUTDOWN_KILL) &&
|
||||||
XIO_RDSTREAM(xfd)->para.exec.pid == 0) {
|
XIO_RDSTREAM(xfd)->para.exec.pid == 0) {
|
||||||
struct timeval time0 = { 0,0 };
|
|
||||||
|
|
||||||
FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
|
|
||||||
if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) {
|
if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) {
|
||||||
FD_SET(XIO_GETRDFD(xfd), &in);
|
in.fd = XIO_GETRDFD(xfd);
|
||||||
/*0 FD_SET(XIO_GETRDFD(xfd), &expt);*/
|
in.events = POLLIN/*|POLLRDBAND*/;
|
||||||
|
in.revents = 0;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
retval = Select(FD_SETSIZE, &in, &out, &expt, &time0);
|
retval = xiopoll(&in, 1, timeout);
|
||||||
} while (retval < 0 && errno == EINTR);
|
} while (retval < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
#if HAVE_FDS_BITS
|
Error4("xiopoll({%d,%0o}, 1, %d): %s",
|
||||||
Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s",
|
in.fd, in.events, timeout, strerror(errno));
|
||||||
FD_SETSIZE, in.fds_bits[0], out.fds_bits[0],
|
|
||||||
expt.fds_bits[0], strerror(errno));
|
|
||||||
#else
|
|
||||||
Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s",
|
|
||||||
FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0],
|
|
||||||
expt.__fds_bits[0], strerror(errno));
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
} else if (retval == 0) {
|
}
|
||||||
|
if (retval == 0) {
|
||||||
Info("terminated child did not leave data for us");
|
Info("terminated child did not leave data for us");
|
||||||
XIO_RDSTREAM(xfd)->eof = 2;
|
XIO_RDSTREAM(xfd)->eof = 2;
|
||||||
xfd->stream.eof = 2;
|
xfd->stream.eof = 2;
|
||||||
|
@ -694,7 +693,11 @@ bool maywr2; /* sock2 can be written to, according to select() */
|
||||||
and their options are set/applied
|
and their options are set/applied
|
||||||
returns -1 on error or 0 on success */
|
returns -1 on error or 0 on success */
|
||||||
int _socat(void) {
|
int _socat(void) {
|
||||||
fd_set in, out, expt;
|
struct pollfd fds[4],
|
||||||
|
*fd1in = &fds[0],
|
||||||
|
*fd1out = &fds[1],
|
||||||
|
*fd2in = &fds[2],
|
||||||
|
*fd2out = &fds[3];
|
||||||
int retval;
|
int retval;
|
||||||
unsigned char *buff;
|
unsigned char *buff;
|
||||||
ssize_t bytes1, bytes2;
|
ssize_t bytes1, bytes2;
|
||||||
|
@ -747,7 +750,7 @@ int _socat(void) {
|
||||||
XIO_GETRDFD(sock2), XIO_GETWRFD(sock2));
|
XIO_GETRDFD(sock2), XIO_GETWRFD(sock2));
|
||||||
while (XIO_RDSTREAM(sock1)->eof <= 1 ||
|
while (XIO_RDSTREAM(sock1)->eof <= 1 ||
|
||||||
XIO_RDSTREAM(sock2)->eof <= 1) {
|
XIO_RDSTREAM(sock2)->eof <= 1) {
|
||||||
struct timeval timeout, *to = NULL;
|
int timeout;
|
||||||
|
|
||||||
Debug6("data loop: sock1->eof=%d, sock2->eof=%d, closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}",
|
Debug6("data loop: sock1->eof=%d, sock2->eof=%d, closing=%d, wasaction=%d, total_to={"F_tv_sec"."F_tv_usec"}",
|
||||||
XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof,
|
XIO_RDSTREAM(sock1)->eof, XIO_RDSTREAM(sock2)->eof,
|
||||||
|
@ -783,59 +786,77 @@ int _socat(void) {
|
||||||
|
|
||||||
if (polling) {
|
if (polling) {
|
||||||
/* there is a ignoreeof poll timeout, use it */
|
/* there is a ignoreeof poll timeout, use it */
|
||||||
timeout = socat_opts.pollintv;
|
timeout = 1000*socat_opts.pollintv.tv_sec +
|
||||||
to = &timeout;
|
socat_opts.pollintv.tv_usec/1000; /*!!! overflow?*/
|
||||||
} else if (socat_opts.total_timeout.tv_sec != 0 ||
|
} else if (socat_opts.total_timeout.tv_sec != 0 ||
|
||||||
socat_opts.total_timeout.tv_usec != 0) {
|
socat_opts.total_timeout.tv_usec != 0) {
|
||||||
/* there might occur a total inactivity timeout */
|
/* there might occur a total inactivity timeout */
|
||||||
timeout = socat_opts.total_timeout;
|
timeout = 1000*socat_opts.total_timeout.tv_sec +
|
||||||
to = &timeout;
|
socat_opts.total_timeout.tv_usec/1000;
|
||||||
} else {
|
} else {
|
||||||
to = NULL;
|
timeout = -1; /* forever */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closing>=1) {
|
if (closing>=1) {
|
||||||
/* first eof already occurred, start end timer */
|
/* first eof already occurred, start end timer */
|
||||||
timeout = socat_opts.closwait;
|
timeout = 1000*socat_opts.closwait.tv_sec +
|
||||||
to = &timeout;
|
socat_opts.closwait.tv_usec/1000;
|
||||||
closing = 2;
|
closing = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int _errno;
|
int _errno;
|
||||||
FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
|
|
||||||
|
|
||||||
childleftdata(sock1);
|
childleftdata(sock1);
|
||||||
childleftdata(sock2);
|
childleftdata(sock2);
|
||||||
|
|
||||||
if (closing>=1) {
|
if (closing>=1) {
|
||||||
/* first eof already occurred, start end timer */
|
/* first eof already occurred, start end timer */
|
||||||
timeout = socat_opts.closwait;
|
timeout = 1000*socat_opts.closwait.tv_sec +
|
||||||
to = &timeout;
|
socat_opts.closwait.tv_usec/1000;
|
||||||
closing = 2;
|
closing = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now the fds are assigned */
|
||||||
if (XIO_READABLE(sock1) &&
|
if (XIO_READABLE(sock1) &&
|
||||||
!(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) &&
|
!(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) &&
|
||||||
!socat_opts.righttoleft) {
|
!socat_opts.righttoleft) {
|
||||||
if (!mayrd1) {
|
if (!mayrd1) {
|
||||||
FD_SET(XIO_GETRDFD(sock1), &in);
|
fd1in->fd = XIO_GETRDFD(sock1);
|
||||||
|
fd1in->events = POLLIN;
|
||||||
|
} else {
|
||||||
|
fd1in->fd = -1;
|
||||||
}
|
}
|
||||||
if (!maywr2) {
|
if (!maywr2) {
|
||||||
FD_SET(XIO_GETWRFD(sock2), &out);
|
fd2out->fd = XIO_GETWRFD(sock2);
|
||||||
|
fd2out->events = POLLOUT;
|
||||||
|
} else {
|
||||||
|
fd2out->fd = -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fd1in->fd = -1;
|
||||||
|
fd2out->fd = -1;
|
||||||
}
|
}
|
||||||
if (XIO_READABLE(sock2) &&
|
if (XIO_READABLE(sock2) &&
|
||||||
!(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) &&
|
!(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) &&
|
||||||
!socat_opts.lefttoright) {
|
!socat_opts.lefttoright) {
|
||||||
if (!mayrd2) {
|
if (!mayrd2) {
|
||||||
FD_SET(XIO_GETRDFD(sock2), &in);
|
fd2in->fd = XIO_GETRDFD(sock2);
|
||||||
|
fd2in->events = POLLIN;
|
||||||
|
} else {
|
||||||
|
fd2in->fd = -1;
|
||||||
}
|
}
|
||||||
if (!maywr1) {
|
if (!maywr1) {
|
||||||
FD_SET(XIO_GETWRFD(sock1), &out);
|
fd1out->fd = XIO_GETWRFD(sock1);
|
||||||
|
fd1out->events = POLLOUT;
|
||||||
|
} else {
|
||||||
|
fd1out->fd = -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fd1out->fd = -1;
|
||||||
|
fd2in->fd = -1;
|
||||||
}
|
}
|
||||||
retval = Select(FD_SETSIZE, &in, &out, &expt, to);
|
retval = xiopoll(fds, 4, timeout);
|
||||||
_errno = errno;
|
_errno = errno;
|
||||||
if (retval < 0 && errno == EINTR) {
|
if (retval < 0 && errno == EINTR) {
|
||||||
Info1("select(): %s", strerror(errno));
|
Info1("select(): %s", strerror(errno));
|
||||||
|
@ -849,17 +870,10 @@ int _socat(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
#if HAVE_FDS_BITS
|
Error10("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, %d): %s",
|
||||||
Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s",
|
fds[0].fd, fds[0].events, fds[1].fd, fds[1].events,
|
||||||
FD_SETSIZE, in.fds_bits[0], out.fds_bits[0],
|
fds[2].fd, fds[2].events, fds[3].fd, fds[3].events,
|
||||||
expt.fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
|
timeout, strerror(errno));
|
||||||
strerror(errno));
|
|
||||||
#else
|
|
||||||
Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s",
|
|
||||||
FD_SETSIZE, in.__fds_bits[0], out.__fds_bits[0],
|
|
||||||
expt.__fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
|
|
||||||
strerror(errno));
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
} else if (retval == 0) {
|
} else if (retval == 0) {
|
||||||
Info2("select timed out (no data within %ld.%06ld seconds)",
|
Info2("select timed out (no data within %ld.%06ld seconds)",
|
||||||
|
@ -884,17 +898,17 @@ int _socat(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 &&
|
if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 &&
|
||||||
FD_ISSET(XIO_GETRDFD(sock1), &in)) {
|
(fd1in->revents&(POLLIN|POLLHUP|POLLERR))) {
|
||||||
mayrd1 = true;
|
mayrd1 = true;
|
||||||
}
|
}
|
||||||
if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 &&
|
if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 &&
|
||||||
FD_ISSET(XIO_GETRDFD(sock2), &in)) {
|
(fd2in->revents&(POLLIN|POLLHUP|POLLERR))) {
|
||||||
mayrd2 = true;
|
mayrd2 = true;
|
||||||
}
|
}
|
||||||
if (XIO_GETWRFD(sock1) >= 0 && FD_ISSET(XIO_GETWRFD(sock1), &out)) {
|
if (XIO_GETWRFD(sock1) >= 0 && (fd1out->revents&(POLLOUT|POLLERR))) {
|
||||||
maywr1 = true;
|
maywr1 = true;
|
||||||
}
|
}
|
||||||
if (XIO_GETWRFD(sock2) >= 0 && FD_ISSET(XIO_GETWRFD(sock2), &out)) {
|
if (XIO_GETWRFD(sock2) >= 0 && (fd2out->revents&(POLLOUT|POLLERR))) {
|
||||||
maywr2 = true;
|
maywr2 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
sycls.c
16
sycls.c
|
@ -677,9 +677,21 @@ int Chmod(const char *path, mode_t mode) {
|
||||||
/* we only show the first struct pollfd; hope this is enough for most cases. */
|
/* we only show the first struct pollfd; hope this is enough for most cases. */
|
||||||
int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||||
int result;
|
int result;
|
||||||
Debug4("poll({%d, 0x%02hx, }, %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout);
|
if (nfds == 4) {
|
||||||
|
Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, , %u, %d)",
|
||||||
|
ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events,
|
||||||
|
ufds[2].fd, ufds[2].events, ufds[3].fd, ufds[3].events,
|
||||||
|
nfds, timeout);
|
||||||
|
} else {
|
||||||
|
Debug4("poll({%d,0x%02hx,}, , %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout);
|
||||||
|
}
|
||||||
result = poll(ufds, nfds, timeout);
|
result = poll(ufds, nfds, timeout);
|
||||||
Debug2("poll(, {,, 0x%02hx}) -> %d", ufds[0].revents, result);
|
if (nfds == 4) {
|
||||||
|
Debug5("poll(, {,,0x%02hx}{,,0x%02hx}{,,0x%02hx}{,,0x%02hx}) -> %d",
|
||||||
|
ufds[0].revents, ufds[1].revents, ufds[2].revents, ufds[3].revents, result);
|
||||||
|
} else {
|
||||||
|
Debug2("poll(, {,,0x%02hx}) -> %d", ufds[0].revents, result);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_POLL */
|
#endif /* HAVE_POLL */
|
||||||
|
|
13
sysutils.c
13
sysutils.c
|
@ -1,5 +1,5 @@
|
||||||
/* source: sysutils.c */
|
/* source: sysutils.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2007 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* translate socket addresses into human readable form */
|
/* translate socket addresses into human readable form */
|
||||||
|
@ -400,6 +400,17 @@ const char *hstrerror(int err) {
|
||||||
return h_messages[err];
|
return h_messages[err];
|
||||||
}
|
}
|
||||||
#endif /* !HAVE_HSTRERROR */
|
#endif /* !HAVE_HSTRERROR */
|
||||||
|
|
||||||
|
|
||||||
|
/* this function behaves like poll(). It tries to do so even when the poll()
|
||||||
|
system call is not available. */
|
||||||
|
int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout) {
|
||||||
|
#if HAVE_POLL
|
||||||
|
return Poll(fds, nfds, timeout);
|
||||||
|
#else /* HAVE_POLL */
|
||||||
|
/*!!! wrap around Select() */
|
||||||
|
#endif /* !HAVE_POLL */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if WITH_TCP || WITH_UDP
|
#if WITH_TCP || WITH_UDP
|
||||||
|
|
|
@ -90,6 +90,8 @@ extern int getusergroups(const char *user, gid_t *list, size_t *ngroups);
|
||||||
extern const char *hstrerror(int err);
|
extern const char *hstrerror(int err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout);
|
||||||
|
|
||||||
extern int parseport(const char *portname, int proto);
|
extern int parseport(const char *portname, int proto);
|
||||||
|
|
||||||
extern int ifindexbyname(const char *ifname);
|
extern int ifindexbyname(const char *ifname);
|
||||||
|
|
30
xio-socket.c
30
xio-socket.c
|
@ -269,19 +269,21 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
||||||
if (errno == EINPROGRESS) {
|
if (errno == EINPROGRESS) {
|
||||||
if (xfd->para.socket.connect_timeout.tv_sec != 0 ||
|
if (xfd->para.socket.connect_timeout.tv_sec != 0 ||
|
||||||
xfd->para.socket.connect_timeout.tv_usec != 0) {
|
xfd->para.socket.connect_timeout.tv_usec != 0) {
|
||||||
struct timeval timeout;
|
int timeout;
|
||||||
fd_set readfds, writefds, exceptfds;
|
struct pollfd writefd;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
Info4("connect(%d, %s, "F_Zd"): %s",
|
Info4("connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
timeout = xfd->para.socket.connect_timeout;
|
timeout = 1000*xfd->para.socket.connect_timeout.tv_sec +
|
||||||
FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
|
xfd->para.socket.connect_timeout.tv_usec/1000;
|
||||||
FD_SET(xfd->fd, &readfds); FD_SET(xfd->fd, &writefds);
|
writefd.fd = xfd->fd;
|
||||||
result =
|
writefd.events = (POLLIN|POLLHUP|POLLERR);
|
||||||
Select(xfd->fd+1, &readfds, &writefds, &exceptfds, &timeout);
|
result = Poll(&writefd, 1, timeout);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg2(level, "select(%d,,,,): %s", xfd->fd+1, strerror(errno));
|
Msg3(level, "poll({%d,POLLIN|POLLHUP|POLLER},,%d): %s",
|
||||||
|
xfd->fd, timeout, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
@ -290,7 +292,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
||||||
strerror(ETIMEDOUT));
|
strerror(ETIMEDOUT));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if (FD_ISSET(xfd->fd, &readfds)) {
|
if (writefd.revents & POLLOUT) {
|
||||||
#if 0
|
#if 0
|
||||||
unsigned char dummy[1];
|
unsigned char dummy[1];
|
||||||
Read(xfd->fd, &dummy, 1); /* get error message */
|
Read(xfd->fd, &dummy, 1); /* get error message */
|
||||||
|
@ -726,16 +728,16 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
|
|
||||||
/* loop until select() returns valid */
|
/* loop until select() returns valid */
|
||||||
do {
|
do {
|
||||||
fd_set in, out, expt;
|
struct pollfd readfd;
|
||||||
/*? int level = E_ERROR;*/
|
/*? int level = E_ERROR;*/
|
||||||
if (us != NULL) {
|
if (us != NULL) {
|
||||||
Notice1("receiving on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname)));
|
Notice1("receiving on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname)));
|
||||||
} else {
|
} else {
|
||||||
Notice1("receiving IP protocol %u", proto);
|
Notice1("receiving IP protocol %u", proto);
|
||||||
}
|
}
|
||||||
FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
|
readfd.fd = xfd->fd;
|
||||||
FD_SET(xfd->fd, &in);
|
readfd.events = POLLIN;
|
||||||
if (Select(xfd->fd+1, &in, &out, &expt, NULL) > 0) {
|
if (Poll(&readfd, 1, -1) > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,7 +745,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg2(level, "select(, {%d}): %s", xfd->fd, strerror(errno));
|
Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(xfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
|
@ -84,7 +84,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
union sockaddr_union themunion;
|
union sockaddr_union themunion;
|
||||||
union sockaddr_union *them = &themunion;
|
union sockaddr_union *them = &themunion;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
fd_set in, out, expt;
|
struct pollfd readfd;
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char *rangename;
|
char *rangename;
|
||||||
|
@ -205,9 +205,9 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
Notice1("listening on UDP %s",
|
Notice1("listening on UDP %s",
|
||||||
sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
|
||||||
FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
|
readfd.fd = fd->stream.fd;
|
||||||
FD_SET(fd->stream.fd, &in);
|
readfd.events = POLLIN|POLLERR;
|
||||||
while (Select(fd->stream.fd+1, &in, &out, &expt, NULL) < 0) {
|
while (Poll(&readfd, 1, -1) < 0) {
|
||||||
if (errno != EINTR) break;
|
if (errno != EINTR) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue