File descriptors in pipe.c

Ajay Tanpure
Thu, 31 Jan 2013 03:05:49 -0000

I am working on rsync tool.

As rsync sends data over SSH in non-daemon mode, it forks the SSH process
in pipe.c function.
For the communication between the parent rsync and child SSH, it uses the
socket pairs.

As socket pairs are bidirectional, only one pair can be used for
communication between the parent and child.
e.g. socketpair(xx,xx,xx,xx) returns -> to_child_pipe[2]={3,4} then these
two file descriptors 3 and 4 can be used one at each end for reading and
writing.

But in the rsync code, two pairs are created as to_child_pipe and
from_child_pipe


------------------------------------------------------------
---------------------
 if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {

                rsyserr(FERROR, errno, "pipe");

                exit_cleanup(RERR_IPC);

        }

        //to_pipe_child[]={3,4}
        //from_pipe_child[]={5,6}

        pid = do_fork();

        printf("value of pid is %d",pid);
        if (pid == -1) {
                rsyserr(FERROR, errno, "fork");

                exit_cleanup(RERR_IPC);

        }

        if (pid == 0) {
                printf("\n inside the if statement");
                if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||

                        close(to_child_pipe[1]) < 0 ||
  // fd 4 closed
                        close(from_child_pipe[0]) < 0 ||
  // fd 5 closed
                     dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {

                        rsyserr(FERROR, errno, "Failed to dup/close");

                        exit_cleanup(RERR_IPC);
                }
                if (to_child_pipe[0] != STDIN_FILENO)
                        close(to_child_pipe[0]);
                if (from_child_pipe[1] != STDOUT_FILENO)

                        close(from_child_pipe[1]);

                set_blocking(STDIN_FILENO);
                if (blocking_io > 0)
                        set_blocking(STDOUT_FILENO);
                execvp(command[0], command); // command is "SSH -l user
192.168.xx.xx rsync --server -vlogxxxxx "
                rsyserr(FERROR, errno, "Failed to exec %s",
command[0]);

                exit_cleanup(RERR_IPC);

        }


        if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0)
{
     // in parent fd 3, 6 closed
                rsyserr(FERROR, errno, "Failed to close");

                exit_cleanup(RERR_IPC);

        }
------------------------------------------------------------
-----------------------------------------------------

In child block(i.e. if(pid == 0) ), each end of two socket pairs is closed.
and in parent process, fd 3 and 6 closed. In the subsequent write and read
operation in rsync, it uses fd 5 for reading and 4 for writing as
f_in = 5 and f_out = 4
My problem is why two socket pairs are used and how fd 5 and 4 are used for
reading and writing?

Please reply if you have any idea.
Thank you
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.samba.org/pipermail/rsync/attachments/20130131/44b09715/attachment.html>