XrdNetConnect.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                      X r d N e t C o n n e c t . c c                       */
00004 /*                                                                            */
00005 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdNetConnect.cc 22437 2008-03-04 14:35:16Z rdm $
00012 
00013 const char *XrdNetConnectCVSID = "$Id: XrdNetConnect.cc 22437 2008-03-04 14:35:16Z rdm $";
00014 
00015 #include "errno.h"
00016 #include "fcntl.h"
00017 #ifndef WIN32
00018 #include "poll.h"
00019 #include "unistd.h"
00020 #include <sys/types.h>
00021 #include <sys/socket.h>
00022 #endif
00023 
00024 #include "XrdNet/XrdNetConnect.hh"
00025 #include "XrdSys/XrdSysPlatform.hh"
00026 
00027 /******************************************************************************/
00028 /*                               C o n n e c t                                */
00029 /******************************************************************************/
00030   
00031 int XrdNetConnect::Connect(             int       fd,
00032                            const struct sockaddr *name, 
00033                                         int       namelen, 
00034                                         int       tsec)
00035 {
00036    int old_flags, new_flags, myRC;
00037    SOCKLEN_t myRClen = sizeof(myRC);
00038 
00039 // If no timeout wanted, do a plain connect() which will timeout after 3
00040 // minutes on most platforms.
00041 //
00042    if (!tsec)
00043       {if (connect(fd, name, namelen)) return errno;
00044        return 0;
00045       }
00046 
00047 // If a timeout is wanted, then we must convert this file descriptor to be
00048 // non-blocking so that if a connection is not made immediately we can get
00049 // control back and poll for completion for the specified amount of time.
00050 // Regardless of outcome we will restore the original fd settings.
00051 //
00052    old_flags = fcntl(fd, F_GETFL, 0);
00053    new_flags = old_flags | O_NDELAY | O_NONBLOCK;
00054    fcntl(fd, F_SETFL, new_flags);
00055    if (!connect(fd, name, namelen))  myRC = 0;
00056       else if (EINPROGRESS != net_errno) myRC = net_errno;
00057               else {struct pollfd polltab = {fd, POLLOUT|POLLWRNORM, 0};
00058                     do {myRC = poll(&polltab, 1, tsec*1000);} 
00059                        while(myRC < 0 && errno == EINTR);
00060                     if (myRC != 1) myRC = ETIMEDOUT;
00061                        else getsockopt(fd,SOL_SOCKET,SO_ERROR,(Sokdata_t)&myRC,&myRClen);
00062                    }
00063    fcntl(fd, F_SETFD, old_flags);
00064    return myRC;
00065 }

Generated on Tue Jul 5 14:46:43 2011 for ROOT_528-00b_version by  doxygen 1.5.1