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