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