00001
00002
00003 #include "ace/TLI_Connector.h"
00004
00005 ACE_RCSID(ace, TLI_Connector, "$Id: TLI_Connector.cpp 69051 2005-10-28 16:14:56Z ossama $")
00006
00007 #if defined (ACE_HAS_TLI)
00008
00009 #if !defined (__ACE_INLINE__)
00010 #include "ace/TLI_Connector.inl"
00011 #endif
00012
00013 #include "ace/Handle_Set.h"
00014 #include "ace/ACE.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/Time_Value.h"
00017
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 ACE_ALLOC_HOOK_DEFINE(ACE_TLI_Connector)
00021
00022 void
00023 ACE_TLI_Connector::dump (void) const
00024 {
00025 #if defined (ACE_HAS_DUMP)
00026 ACE_TRACE ("ACE_TLI_Connector::dump");
00027 #endif
00028 }
00029
00030 ACE_TLI_Connector::ACE_TLI_Connector (void)
00031 {
00032 ACE_TRACE ("ACE_TLI_Connector::ACE_TLI_Connector");
00033 }
00034
00035
00036
00037
00038
00039 int
00040 ACE_TLI_Connector::connect (ACE_TLI_Stream &new_stream,
00041 const ACE_Addr &remote_sap,
00042 ACE_Time_Value *timeout,
00043 const ACE_Addr &local_sap,
00044 int reuse_addr,
00045 int flags,
00046 int ,
00047 const char device[],
00048 struct t_info *info,
00049 int rwf,
00050 struct netbuf *udata,
00051 struct netbuf *opt)
00052 {
00053 ACE_TRACE ("ACE_TLI_Connector::connect");
00054 int result = 0;
00055
00056
00057
00058 if (new_stream.get_handle () == ACE_INVALID_HANDLE
00059 && new_stream.open (device, flags, info) == ACE_INVALID_HANDLE)
00060 return -1;
00061
00062 if (local_sap != ACE_Addr::sap_any)
00063 {
00064
00065
00066 struct t_bind *localaddr;
00067
00068 localaddr = (struct t_bind *)
00069 ACE_OS::t_alloc (new_stream.get_handle (), T_BIND, T_ADDR);
00070
00071 if (localaddr == 0)
00072 result = -1;
00073 else
00074 {
00075 int one = 1;
00076 #if !defined (ACE_HAS_FORE_ATM_XTI)
00077
00078
00079
00080
00081
00082
00083 if (reuse_addr
00084 && new_stream.set_option (SOL_SOCKET,
00085 SO_REUSEADDR,
00086 &one,
00087 sizeof one) == -1)
00088 result = -1;
00089 else
00090 #endif
00091 {
00092 void *addr_buf = local_sap.get_addr ();
00093 localaddr->addr.len = local_sap.get_size ();
00094 ACE_OS::memcpy(localaddr->addr.buf,
00095 addr_buf,
00096 localaddr->addr.len);
00097
00098 if (ACE_OS::t_bind (new_stream.get_handle (),
00099 localaddr,
00100 localaddr) == -1)
00101 result = -1;
00102
00103 ACE_OS::t_free ((char *) localaddr,
00104 T_BIND);
00105 }
00106 }
00107
00108 if (result == -1)
00109 {
00110 new_stream.close ();
00111 return -1;
00112 }
00113 }
00114
00115 else if (ACE_OS::t_bind (new_stream.get_handle (), 0, 0) == -1)
00116 return -1;
00117
00118 struct t_call *callptr = 0;
00119
00120 callptr = (struct t_call *)
00121 ACE_OS::t_alloc (new_stream.get_handle (), T_CALL, T_ADDR);
00122
00123 if (callptr == 0)
00124 {
00125 new_stream.close ();
00126 return -1;
00127 }
00128
00129 void *addr_buf = remote_sap.get_addr ();
00130 callptr->addr.len = remote_sap.get_size ();
00131 ACE_OS::memcpy (callptr->addr.buf,
00132 addr_buf,
00133 callptr->addr.len);
00134
00135
00136 if (udata != 0)
00137 ACE_OS::memcpy ((void *) &callptr->udata, (void *) udata, sizeof *udata);
00138 if (opt != 0)
00139 ACE_OS::memcpy ((void *) &callptr->opt, (void *) opt, sizeof *opt);
00140
00141
00142 #if defined (ACE_HAS_FORE_ATM_XTI)
00143
00144
00145 timeout = 0;
00146 #endif
00147
00148 if (timeout != 0)
00149 {
00150 if (new_stream.enable (ACE_NONBLOCK) == -1)
00151 result = -1;
00152
00153
00154 if (ACE_OS::t_connect (new_stream.get_handle (), callptr, 0) == -1)
00155 {
00156 result = -1;
00157
00158
00159
00160 if (t_errno == TNODATA)
00161 {
00162 if (timeout->sec () == 0 && timeout->usec () == 0)
00163 errno = EWOULDBLOCK;
00164 else
00165 result = this->complete (new_stream, 0, timeout);
00166 }
00167 else if (t_errno == TLOOK && new_stream.look () == T_DISCONNECT)
00168 new_stream.rcvdis ();
00169 }
00170 }
00171
00172 else if (ACE_OS::t_connect (new_stream.get_handle (), callptr, 0) == -1)
00173 result = -1;
00174
00175 if (result != -1)
00176 {
00177 new_stream.set_rwflag (rwf);
00178 #if defined (I_PUSH) && !defined (ACE_HAS_FORE_ATM_XTI)
00179 if (new_stream.get_rwflag ())
00180 result = ACE_OS::ioctl (new_stream.get_handle (),
00181 I_PUSH,
00182 const_cast<char *> ("tirdwr"));
00183 #endif
00184 }
00185 else if (!(errno == EWOULDBLOCK || errno == ETIME))
00186 {
00187
00188 new_stream.close ();
00189 new_stream.set_handle (ACE_INVALID_HANDLE);
00190 }
00191
00192 if (ACE_OS::t_free ((char *) callptr, T_CALL) == -1)
00193 return -1;
00194 return result;
00195 }
00196
00197
00198
00199 int
00200 ACE_TLI_Connector::complete (ACE_TLI_Stream &new_stream,
00201 ACE_Addr *remote_sap,
00202 ACE_Time_Value *tv)
00203 {
00204 ACE_TRACE ("ACE_TLI_Connector::complete");
00205 #if defined (ACE_WIN32)
00206 if (WaitForSingleObject (new_stream.get_handle(), tv->msec()) == WAIT_OBJECT_0)
00207 {
00208 if (ACE_OS::t_look (new_stream.get_handle()) == T_CONNECT)
00209 return t_rcvconnect (new_stream.get_handle(), 0);
00210 else
00211 return -1;
00212 }
00213 else
00214 return -1;
00215 #else
00216 ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
00217 tv,
00218 1);
00219 if (h == ACE_INVALID_HANDLE)
00220 {
00221 new_stream.close ();
00222 return -1;
00223 }
00224 else
00225 {
00226 if (remote_sap != 0)
00227 {
00228 #if defined (ACE_HAS_XTI) || defined (ACE_HAS_SVR4_TLI)
00229 struct netbuf name;
00230
00231 name.maxlen = remote_sap->get_size ();
00232 name.buf = (char *) remote_sap->get_addr ();
00233
00234 if (ACE_OS::t_getname (new_stream.get_handle (),
00235 &name,
00236 REMOTENAME) == -1)
00237 #else
00238 if (0)
00239 #endif
00240 {
00241 new_stream.close ();
00242 return -1;
00243 }
00244 }
00245
00246
00247 new_stream.disable (ACE_NONBLOCK);
00248
00249 return 0;
00250 }
00251 #endif
00252 }
00253
00254 ACE_END_VERSIONED_NAMESPACE_DECL
00255
00256 #endif