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 HAVE_GETOPT_LONG
|
||||||
#undef REPLACE_INET_NTOA
|
#undef REPLACE_INET_NTOA
|
||||||
#undef HAVE_GETTIMEOFDAY_TZ
|
#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,"SO_KEEPALIVE");
|
||||||
set_socket_options(fd,lp_socket_options());
|
set_socket_options(fd,lp_socket_options());
|
||||||
|
set_nonblocking(fd);
|
||||||
|
|
||||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n == -1 &&
|
||||||
|
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
if (eof_error) {
|
if (eof_error) {
|
||||||
@@ -364,12 +369,17 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
|||||||
if (FD_ISSET(fd, &w_fds)) {
|
if (FD_ISSET(fd, &w_fds)) {
|
||||||
int ret, n = len-total;
|
int ret, n = len-total;
|
||||||
|
|
||||||
ret = write(fd,buf+total,n?n:1);
|
ret = write(fd,buf+total,n);
|
||||||
|
|
||||||
if (ret == -1 && errno == EINTR) {
|
if (ret == -1 && errno == EINTR) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == -1 &&
|
||||||
|
(errno == EWOULDBLOCK || errno == EAGAIN)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
|
||||||
exit_cleanup(RERR_STREAMIO);
|
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);
|
setup_protocol(f_out, f_in);
|
||||||
|
|
||||||
|
set_nonblocking(f_in);
|
||||||
|
set_nonblocking(f_out);
|
||||||
|
|
||||||
if (remote_version >= 23)
|
if (remote_version >= 23)
|
||||||
io_start_multiplex_out(f_out);
|
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 list_only;
|
||||||
extern int remote_version;
|
extern int remote_version;
|
||||||
|
|
||||||
|
set_nonblocking(f_in);
|
||||||
|
set_nonblocking(f_out);
|
||||||
|
|
||||||
setup_protocol(f_out,f_in);
|
setup_protocol(f_out,f_in);
|
||||||
|
|
||||||
if (remote_version >= 23)
|
if (remote_version >= 23)
|
||||||
@@ -695,6 +701,8 @@ int main(int argc,char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (am_server) {
|
if (am_server) {
|
||||||
|
set_nonblocking(STDIN_FILENO);
|
||||||
|
set_nonblocking(STDOUT_FILENO);
|
||||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
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))
|
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
|
||||||
#endif
|
#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))
|
#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;
|
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 fd_pair(int fd[2])
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
#if HAVE_SOCKETPAIR
|
#if HAVE_SOCKETPAIR
|
||||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||||
#else
|
#else
|
||||||
return pipe(fd);
|
ret = pipe(fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
set_nonblocking(fd[0]);
|
||||||
|
set_nonblocking(fd[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user