version 1.80, 2016/08/18 16:23:06 |
version 1.81, 2016/08/20 20:18:42 |
|
|
* FTP User Program -- Misc support routines |
* FTP User Program -- Misc support routines |
*/ |
*/ |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
|
#include <sys/socket.h> |
#include <sys/time.h> |
#include <sys/time.h> |
#include <arpa/ftp.h> |
#include <arpa/ftp.h> |
|
|
|
|
#endif /* !SMALL */ |
#endif /* !SMALL */ |
|
|
/* |
/* |
* Wrapper for connect(2) that restarts the syscall when |
* Wait for an asynchronous connect(2) attempt to finish. |
* interrupted and operates synchronously. |
|
*/ |
*/ |
int |
int |
connect_sync(int s, const struct sockaddr *name, socklen_t namelen) |
connect_wait(int s) |
{ |
{ |
struct pollfd pfd[1]; |
struct pollfd pfd[1]; |
int error = 0; |
int error = 0; |
socklen_t len = sizeof(error); |
socklen_t len = sizeof(error); |
|
|
if (connect(s, name, namelen) < 0) { |
|
if (errno != EINTR) |
|
return -1; |
|
} |
|
|
|
/* An interrupted connect(2) continues asyncronously. */ |
|
pfd[0].fd = s; |
pfd[0].fd = s; |
pfd[0].events = POLLOUT; |
pfd[0].events = POLLOUT; |
for (;;) { |
|
if (poll(pfd, 1, -1) == -1) { |
if (poll(pfd, 1, -1) == -1) |
if (errno != EINTR) |
return -1; |
return -1; |
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0) |
continue; |
return -1; |
} |
if (error != 0) { |
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0) |
errno = error; |
return -1; |
return -1; |
if (error != 0) |
|
errno = error; |
|
break; |
|
} |
} |
return (error ? -1 : 0); |
return 0; |
} |
} |