00001
00002
00003 #include "ace/SPIPE_Acceptor.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_sys_stat.h"
00006 #include "ace/OS_NS_sys_time.h"
00007
00008 #if defined (ACE_HAS_STREAM_PIPES)
00009 # include "ace/OS_NS_unistd.h"
00010 #endif // ACE_HAS_STREAM_PIPES
00011
00012 ACE_RCSID(ace, SPIPE_Acceptor, "SPIPE_Acceptor.cpp,v 4.36 2006/05/04 21:19:07 shuston Exp")
00013
00014 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00015
00016 ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (void)
00017 #if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00018 : sa_ (0), pipe_handle_ (ACE_INVALID_HANDLE)
00019 #endif
00020 {
00021 ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
00022 }
00023
00024 int
00025 ACE_SPIPE_Acceptor::remove (void)
00026 {
00027 ACE_TRACE ("ACE_SPIPE_Acceptor::remove");
00028 #if defined (ACE_HAS_STREAM_PIPES)
00029 int result = this->close ();
00030
00031
00032 return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1
00033 || result == -1 ? -1 : 0;
00034 #else
00035 this->close ();
00036 return 0;
00037 #endif
00038 }
00039
00040 ACE_ALLOC_HOOK_DEFINE (ACE_SPIPE_Acceptor)
00041
00042 void
00043 ACE_SPIPE_Acceptor::dump (void) const
00044 {
00045 #if defined (ACE_HAS_DUMP)
00046 ACE_TRACE ("ACE_SPIPE_Acceptor::dump");
00047 #endif
00048 }
00049
00050
00051
00052 int
00053 ACE_SPIPE_Acceptor::open (const ACE_SPIPE_Addr &local_sap,
00054 int reuse_addr,
00055 int perms,
00056 LPSECURITY_ATTRIBUTES sa,
00057 int pipe_mode)
00058 {
00059 ACE_TRACE ("ACE_SPIPE_Acceptor::open");
00060 ACE_UNUSED_ARG (reuse_addr);
00061
00062 this->local_addr_ = local_sap;
00063 this->set_handle (ACE_INVALID_HANDLE);
00064 #if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00065 this->sa_ = sa;
00066 this->pipe_mode_ = pipe_mode;
00067 #else
00068 ACE_UNUSED_ARG (sa);
00069 ACE_UNUSED_ARG (pipe_mode);
00070 #endif
00071
00072 return this->create_new_instance (perms);
00073 }
00074
00075 int
00076 ACE_SPIPE_Acceptor::create_new_instance (int perms)
00077 {
00078 #if defined (ACE_HAS_STREAM_PIPES)
00079 ACE_HANDLE spipe[2];
00080 char module[] = "connld";
00081
00082 ACE_HANDLE handle = ACE_OS::creat (this->local_addr_.get_path_name (),
00083 perms);
00084 if (handle == ACE_INVALID_HANDLE)
00085 return -1;
00086 else if (ACE_OS::close (handle) == -1)
00087 return -1;
00088 else if (ACE_OS::pipe (spipe) == -1)
00089 return -1;
00090 else if (ACE_OS::ioctl (spipe[0],
00091 I_PUSH,
00092 module) == -1)
00093 return -1;
00094 else if (-1 == ACE_OS::fattach
00095 (spipe[0],
00096 ACE_TEXT_ALWAYS_CHAR (this->local_addr_.get_path_name ())))
00097 return -1;
00098
00099 this->set_duplex_handle (spipe[0]);
00100 this->set_handle (spipe[1]);
00101 return 0;
00102
00103 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00104
00105
00106
00107
00108
00109
00110 ACE_UNUSED_ARG (perms);
00111 ACE_TRACE ("ACE_SPIPE_Acceptor::create_new_instance");
00112 int status;
00113
00114
00115 this->pipe_handle_ =
00116 #if defined (ACE_USES_WCHAR)
00117 ::CreateNamedPipeW (
00118 #else
00119 ::CreateNamedPipeA (
00120 #endif
00121 this->local_addr_.get_path_name (),
00122 PIPE_ACCESS_DUPLEX
00123 | FILE_FLAG_OVERLAPPED,
00124 pipe_mode_,
00125 PIPE_UNLIMITED_INSTANCES,
00126 1024 * 10,
00127 1024 * 10,
00128 ACE_DEFAULT_TIMEOUT,
00129 this->sa_);
00130
00131 if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00132 return -1;
00133 else
00134 {
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 this->already_connected_ = 0;
00145 this->set_handle (this->event_.handle ());
00146 this->overlapped_.hEvent = this->event_.handle ();
00147 this->event_.reset ();
00148
00149 BOOL result = ::ConnectNamedPipe (this->pipe_handle_,
00150 &this->overlapped_);
00151 ACE_UNUSED_ARG (result);
00152
00153
00154 ACE_ASSERT (!result);
00155
00156 status = ::GetLastError ();
00157 switch (status)
00158 {
00159 case ERROR_IO_PENDING:
00160 break;
00161 case ERROR_PIPE_CONNECTED:
00162 case ERROR_NO_DATA:
00163 this->already_connected_ = 1;
00164
00165
00166 this->event_.signal ();
00167 break;
00168 default:
00169 ACE_ASSERT (FALSE);
00170 this->close ();
00171 break;
00172 }
00173 }
00174 return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0;
00175 #else
00176 ACE_UNUSED_ARG (perms);
00177 ACE_NOTSUP_RETURN (-1);
00178 #endif
00179 }
00180
00181 int
00182 ACE_SPIPE_Acceptor::close (void)
00183 {
00184 ACE_TRACE ("ACE_SPIPE_Acceptor::close");
00185
00186 #if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00187
00188
00189 if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00190 return -1;
00191
00192
00193
00194
00195 this->set_handle (this->pipe_handle_);
00196
00197 #endif
00198
00199
00200 int result = this->ACE_SPIPE::close ();
00201 this->set_handle (ACE_INVALID_HANDLE);
00202
00203 #if defined (ACE_HAS_STREAM_PIPES)
00204 ACE_OS::fdetach (ACE_TEXT_ALWAYS_CHAR (this->local_addr_.get_path_name ()));
00205 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00206
00207
00208
00209
00210
00211 if (this->already_connected_ == 0)
00212 {
00213 if (this->event_.wait () != -1)
00214 {
00215
00216
00217 DWORD unused;
00218 ::GetOverlappedResult (this->pipe_handle_,
00219 &this->overlapped_,
00220 &unused,
00221 FALSE);
00222 }
00223 this->pipe_handle_ = ACE_INVALID_HANDLE;
00224 this->already_connected_ = 0;
00225 }
00226 #endif
00227
00228 return result;
00229 }
00230
00231 ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (const ACE_SPIPE_Addr &local_sap,
00232 int reuse_addr,
00233 int perms,
00234 LPSECURITY_ATTRIBUTES sa,
00235 int pipe_mode)
00236 {
00237 ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
00238
00239 if (this->open (local_sap, reuse_addr, perms, sa, pipe_mode) == -1)
00240 ACE_ERROR ((LM_ERROR,
00241 ACE_LIB_TEXT ("%p\n"),
00242 ACE_LIB_TEXT ("ACE_SPIPE_Acceptor")));
00243 }
00244
00245
00246
00247 int
00248 ACE_SPIPE_Acceptor::accept (ACE_SPIPE_Stream &new_io,
00249 ACE_SPIPE_Addr *remote_addr,
00250 ACE_Time_Value *timeout,
00251 int restart,
00252 int reset_new_handle)
00253 {
00254 ACE_TRACE ("ACE_SPIPE_Acceptor::accept");
00255 ACE_UNUSED_ARG (reset_new_handle);
00256
00257 #if defined (ACE_HAS_STREAM_PIPES)
00258 strrecvfd r_handle;
00259
00260
00261
00262
00263
00264 if (timeout != 0 &&
00265 ACE::handle_timed_accept (this->get_handle (),
00266 timeout,
00267 restart) == -1)
00268 return -1;
00269 else if (ACE_OS::ioctl (this->get_handle (),
00270 I_RECVFD,
00271 &r_handle) == -1)
00272 return -1;
00273
00274 new_io.set_handle (r_handle.fd);
00275 new_io.local_addr_ = this->local_addr_;
00276 new_io.remote_addr_.set_size (sizeof r_handle.gid + sizeof r_handle.uid);
00277 new_io.remote_addr_.group_id (r_handle.gid);
00278 new_io.remote_addr_.user_id (r_handle.uid);
00279
00280
00281
00282 if (remote_addr != 0)
00283 *remote_addr = new_io.remote_addr_;
00284
00285 return 0;
00286 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00287 ACE_UNUSED_ARG (restart);
00288 ACE_UNUSED_ARG (remote_addr);
00289
00290
00291 if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00292 return -1;
00293
00294
00295
00296 if (this->already_connected_ == 0)
00297 {
00298 if (timeout != 0)
00299 {
00300 ACE_Time_Value abstime (ACE_OS::gettimeofday () + *timeout);
00301 if (this->event_.wait (&abstime) == -1)
00302 return -1;
00303 }
00304 else
00305 if (this->event_.wait () == -1)
00306 return -1;
00307
00308
00309
00310 DWORD unused;
00311 this->already_connected_ = ::GetOverlappedResult (this->pipe_handle_,
00312 &this->overlapped_,
00313 &unused,
00314 FALSE);
00315 }
00316
00317 if (this->already_connected_)
00318 {
00319 new_io.set_handle (this->pipe_handle_);
00320 this->pipe_handle_ = ACE_INVALID_HANDLE;
00321 new_io.local_addr_ = this->local_addr_;
00322
00323
00324 this->create_new_instance ();
00325 return 0;
00326 }
00327 return -1;
00328 #else
00329 ACE_UNUSED_ARG (restart);
00330 ACE_UNUSED_ARG (timeout);
00331 ACE_UNUSED_ARG (remote_addr);
00332 ACE_UNUSED_ARG (new_io);
00333 ACE_NOTSUP_RETURN (-1);
00334 #endif
00335 }
00336
00337 ACE_END_VERSIONED_NAMESPACE_DECL