went back to non-blokcing IO
it looks like ssh is willing to accept a non-blocking fd when used as a transport, this seems to avoid the Solaris socketpair bug
This commit is contained in:
@@ -11,3 +11,4 @@
|
||||
#undef HAVE_GETOPT_LONG
|
||||
#undef REPLACE_INET_NTOA
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
@@ -363,7 +363,7 @@ static int start_daemon(int fd)
|
||||
|
||||
set_socket_options(fd,"SO_KEEPALIVE");
|
||||
set_socket_options(fd,lp_socket_options());
|
||||
|
||||
set_nonblocking(fd);
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
|
||||
12
io.c
12
io.c
@@ -159,6 +159,11 @@ static int read_timeout(int fd, char *buf, int len)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == -1 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (n == 0) {
|
||||
if (eof_error) {
|
||||
@@ -364,12 +369,17 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
if (FD_ISSET(fd, &w_fds)) {
|
||||
int ret, n = len-total;
|
||||
|
||||
ret = write(fd,buf+total,n?n:1);
|
||||
ret = write(fd,buf+total,n);
|
||||
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == -1 &&
|
||||
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
|
||||
8
main.c
8
main.c
@@ -417,6 +417,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
|
||||
setup_protocol(f_out, f_in);
|
||||
|
||||
set_nonblocking(f_in);
|
||||
set_nonblocking(f_out);
|
||||
|
||||
if (remote_version >= 23)
|
||||
io_start_multiplex_out(f_out);
|
||||
|
||||
@@ -440,6 +443,9 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
|
||||
extern int list_only;
|
||||
extern int remote_version;
|
||||
|
||||
set_nonblocking(f_in);
|
||||
set_nonblocking(f_out);
|
||||
|
||||
setup_protocol(f_out,f_in);
|
||||
|
||||
if (remote_version >= 23)
|
||||
@@ -695,6 +701,8 @@ int main(int argc,char *argv[])
|
||||
#endif
|
||||
|
||||
if (am_server) {
|
||||
set_nonblocking(STDIN_FILENO);
|
||||
set_nonblocking(STDOUT_FILENO);
|
||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
9
rsync.h
9
rsync.h
@@ -457,6 +457,15 @@ extern int errno;
|
||||
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
|
||||
#endif
|
||||
|
||||
/* work out what fcntl flag to use for non-blocking */
|
||||
#ifdef O_NONBLOCK
|
||||
# define NONBLOCK_FLAG O_NONBLOCK
|
||||
#elif defined(SYSV)
|
||||
# define NONBLOCK_FLAG O_NDELAY
|
||||
#else
|
||||
# define NONBLOCK_FLAG FNDELAY
|
||||
#endif
|
||||
|
||||
|
||||
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
|
||||
|
||||
|
||||
40
util.c
40
util.c
@@ -26,15 +26,47 @@
|
||||
|
||||
extern int verbose;
|
||||
|
||||
/* create a file descriptor - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes */
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
|
||||
else
|
||||
if SYSV use O_NDELAY
|
||||
if BSD use FNDELAY
|
||||
****************************************************************************/
|
||||
void set_nonblocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return;
|
||||
if (!(val & NONBLOCK_FLAG)) {
|
||||
val |= NONBLOCK_FLAG;
|
||||
fcntl(fd, F_SETFL, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* create a file descriptor pair - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes)
|
||||
|
||||
always set non-blocking
|
||||
*/
|
||||
int fd_pair(int fd[2])
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if HAVE_SOCKETPAIR
|
||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
#else
|
||||
return pipe(fd);
|
||||
ret = pipe(fd);
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
set_nonblocking(fd[0]);
|
||||
set_nonblocking(fd[1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user