2 #include "ace/SOCK_Acceptor.h"
3 #include "ace/SOCK_Connector.h"
4 #include "ace/Log_Category.h"
5 #include "ace/OS_NS_stdio.h"
6 #include "ace/OS_NS_sys_socket.h"
7 #include "ace/OS_Memory.h"
8 #include "ace/Truncate.h"
9 #include "ace/Malloc_Base.h"
11 #if defined (ACE_HAS_STREAM_PIPES) || defined (__QNX__)
12 # include "ace/OS_NS_unistd.h"
13 #endif // ACE_HAS_STREAM_PIPES || __QNX__
15 #if defined (ACE_LACKS_LISTEN) && defined (ACE_LACKS_SOCKETPAIR) \
16 && !defined (ACE_HAS_STREAM_PIPES)
17 # include "ace/OS_NS_time.h"
18 # include "ace/os_include/sys/os_un.h"
21 #include "ace/os_include/netinet/os_tcp.h"
23 #if !defined (__ACE_INLINE__)
24 #include "ace/Pipe.inl"
25 #endif /* __ACE_INLINE__ */
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
32 ACE_Pipe::dump (void) const
34 #if defined (ACE_HAS_DUMP)
35 ACE_TRACE ("ACE_Pipe::dump");
36 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
37 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("handles_[0] = %d"), this->handles_
[0]));
38 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhandles_[1] = %d\n"), this->handles_
[1]));
39 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
40 #endif /* ACE_HAS_DUMP */
44 ACE_Pipe::open (int buffer_size
)
46 ACE_TRACE ("ACE_Pipe::open");
48 #if defined (ACE_LACKS_LISTEN) && defined (ACE_LACKS_SOCKETPAIR) \
49 && !defined (ACE_HAS_STREAM_PIPES)
50 ACE_UNUSED_ARG (buffer_size
);
52 if ((this->handles_
[0] = ACE_OS::socket (AF_LOCAL
, SOCK_DGRAM
, 0)) == -1)
58 #if defined(ACE_VXWORKS) || defined(__APPLE__)
62 unsigned seed
= static_cast<unsigned> (ACE_OS::time ());
63 ACE_OS::snprintf (addr
.sun_path
, sizeof addr
.sun_path
, "/tmp/ACE-Pipe-%d-%p",
64 ACE_OS::rand_r (&seed
), this);
66 if (ACE_OS::bind (this->handles_
[0], (sockaddr
*) &addr
, sizeof addr
) == -1)
72 if ((this->handles_
[1] = ACE_OS::socket (AF_LOCAL
, SOCK_DGRAM
, 0)) == -1 ||
73 ACE_OS::connect (this->handles_
[1], (sockaddr
*) &addr
, sizeof addr
) == -1)
75 ACE_OS::unlink (addr
.sun_path
);
80 ACE_OS::unlink (addr
.sun_path
);
82 #elif defined (ACE_LACKS_SOCKETPAIR)
83 ACE_INET_Addr my_addr
;
84 ACE_SOCK_Acceptor acceptor
;
85 ACE_SOCK_Connector connector
;
86 ACE_SOCK_Stream reader
;
87 ACE_SOCK_Stream writer
;
89 # if defined (ACE_WIN32)
90 ACE_INET_Addr
local_any (static_cast<u_short
> (0), ACE_LOCALHOST
);
92 ACE_Addr local_any
= ACE_Addr::sap_any
;
93 # endif /* ACE_WIN32 */
95 // Bind listener to any port and then find out what the port was.
96 if (acceptor
.open (local_any
) == -1
97 || acceptor
.get_local_addr (my_addr
) == -1)
101 ACE_INET_Addr
sv_addr (my_addr
.get_port_number (),
104 // Establish a connection within the same process.
105 if (connector
.connect (writer
, sv_addr
) == -1)
107 else if (acceptor
.accept (reader
) == -1)
114 // Close down the acceptor endpoint since we don't need it anymore.
119 this->handles_
[0] = reader
.get_handle ();
120 this->handles_
[1] = writer
.get_handle ();
122 # if !defined (ACE_LACKS_TCP_NODELAY)
125 // Make sure that the TCP stack doesn't try to buffer small writes.
126 // Since this communication is purely local to the host it doesn't
127 // affect network performance.
129 if (writer
.set_option (ACE_IPPROTO_TCP
,
137 # endif /* ! ACE_LACKS_TCP_NODELAY */
139 # if defined (ACE_LACKS_SO_RCVBUF) && defined (ACE_LACKS_SO_SNDBUF)
140 ACE_UNUSED_ARG (buffer_size
);
142 # if !defined (ACE_LACKS_SO_RCVBUF)
143 if (reader
.set_option (SOL_SOCKET
,
145 reinterpret_cast <void *> (&buffer_size
),
146 sizeof (buffer_size
)) == -1
152 # endif /* !ACE_LACKS_SO_RCVBUF */
153 # if !defined (ACE_LACKS_SO_SNDBUF)
154 if (writer
.set_option (SOL_SOCKET
,
156 reinterpret_cast <void *> (&buffer_size
),
157 sizeof (buffer_size
)) == -1
163 # endif /* !ACE_LACKS_SO_SNDBUF */
165 #elif defined (ACE_HAS_STREAM_PIPES) || defined (__QNX__)
166 ACE_UNUSED_ARG (buffer_size
);
167 if (ACE_OS::pipe (this->handles_
) == -1)
168 ACELIB_ERROR_RETURN ((LM_ERROR
,
173 # if !defined(__QNX__)
176 // Enable "msg no discard" mode, which ensures that record
177 // boundaries are maintained when messages are sent and received.
178 if (ACE_OS::ioctl (this->handles_
[0],
181 || ACE_OS::ioctl (this->handles_
[1],
186 ACELIB_ERROR_RETURN ((LM_ERROR
,
188 ACE_TEXT ("ioctl")), -1);
190 # endif /* __QNX__ */
192 #else /* ! ACE_LACKS_SOCKETPAIR && ! ACE_HAS_STREAM_PIPES */
193 if (ACE_OS::socketpair (AF_UNIX
,
196 this->handles_
) == -1)
197 ACELIB_ERROR_RETURN ((LM_ERROR
,
199 ACE_TEXT ("socketpair")),
201 # if defined (ACE_LACKS_SO_SNDBUF) && defined (ACE_LACKS_SO_RCVBUF)
202 ACE_UNUSED_ARG (buffer_size
);
204 # if !defined (ACE_LACKS_SO_RCVBUF)
205 if (ACE_OS::setsockopt (this->handles_
[0],
208 reinterpret_cast <const char *> (&buffer_size
),
209 sizeof (buffer_size
)) == -1
216 # if !defined (ACE_LACKS_SO_SNDBUF)
217 if (ACE_OS::setsockopt (this->handles_
[1],
220 reinterpret_cast <const char *> (&buffer_size
),
221 sizeof (buffer_size
)) == -1
227 # endif /* ! ACE_LACKS_SO_SNDBUF */
228 # if defined (ACE_OPENVMS) && !defined (ACE_LACKS_TCP_NODELAY)
230 // OpenVMS implements socketpair(AF_UNIX...) by returning AF_INET sockets.
231 // Since these are plagued by Nagle as any other INET socket we need to set
232 // TCP_NODELAY on the write handle.
233 if (ACE_OS::setsockopt (this->handles_
[1],
236 reinterpret_cast <const char *> (&one
),
242 # endif /* ACE_OPENVMS && !ACE_LACKS_TCP_NODELAY */
243 #endif /* ! ACE_LACKS_SOCKETPAIR && ! ACE_HAS_STREAM_PIPES */
244 // Point both the read and write HANDLES to the appropriate socket
251 ACE_Pipe::open (ACE_HANDLE handles
[2])
253 ACE_TRACE ("ACE_Pipe::open");
255 if (this->open () == -1)
259 handles
[0] = this->handles_
[0];
260 handles
[1] = this->handles_
[1];
267 ACE_Pipe::ACE_Pipe (void)
269 ACE_TRACE ("ACE_Pipe::ACE_Pipe");
271 this->handles_
[0] = ACE_INVALID_HANDLE
;
272 this->handles_
[1] = ACE_INVALID_HANDLE
;
275 ACE_Pipe::ACE_Pipe (ACE_HANDLE handles
[2])
277 ACE_TRACE ("ACE_Pipe::ACE_Pipe");
279 if (this->open (handles
) == -1)
280 ACELIB_ERROR ((LM_ERROR
,
281 ACE_TEXT ("ACE_Pipe::ACE_Pipe")));
284 ACE_Pipe::ACE_Pipe (ACE_HANDLE read
,
287 ACE_TRACE ("ACE_Pipe::ACE_Pipe");
288 this->handles_
[0] = read
;
289 this->handles_
[1] = write
;
293 ACE_Pipe::close (void)
295 ACE_TRACE ("ACE_Pipe::close");
297 int result
= this->close_read ();
298 result
|= this->close_write ();
303 ACE_Pipe::close_read (void)
305 return this->close_handle (0);
308 int ACE_Pipe::close_write (void)
310 return this->close_handle (1);
313 // Send N char *ptrs and int lengths. Note that the char *'s precede
314 // the ints (basically, an varargs version of writev). The count N is
315 // the *total* number of trailing arguments, *not* a couple of the
316 // number of tuple pairs!
317 #if !defined (ACE_LACKS_VA_FUNCTIONS)
319 ACE_Pipe::send (size_t n
, ...) const
321 ACE_TRACE ("ACE_Pipe::send");
323 int total_tuples
= ACE_Utils::truncate_cast
<int> (n
/ 2);
325 #if defined (ACE_HAS_ALLOCA)
326 iovp
= (iovec
*) alloca (total_tuples
* sizeof (iovec
));
328 # ifdef ACE_HAS_ALLOC_HOOKS
329 ACE_ALLOCATOR_RETURN (iovp
, (iovec
*)
330 ACE_Allocator::instance ()->malloc (total_tuples
*
334 ACE_NEW_RETURN (iovp
,
337 # endif /* ACE_HAS_ALLOC_HOOKS */
338 #endif /* !defined (ACE_HAS_ALLOCA) */
342 for (int i
= 0; i
< total_tuples
; ++i
)
344 iovp
[i
].iov_base
= va_arg (argp
, char *);
345 iovp
[i
].iov_len
= va_arg (argp
, int);
348 #if defined (ACE_WIN32)
349 ssize_t result
= ACE::sendv (this->write_handle (),
353 ssize_t result
= ACE_OS::writev (this->write_handle (),
356 #endif /* ACE_WIN32 */
358 #if !defined (ACE_HAS_ALLOCA)
359 # ifdef ACE_HAS_ALLOC_HOOKS
360 ACE_Allocator::instance ()->free (iovp
);
363 # endif /* ACE_HAS_ALLOC_HOOKS */
364 #endif /* !defined (ACE_HAS_ALLOCA) */
369 // This is basically an interface to ACE_OS::readv, that doesn't use
370 // the struct iovec explicitly. The ... can be passed as an arbitrary
371 // number of (char *ptr, int len) tuples. However, the count N is the
372 // *total* number of trailing arguments, *not* a couple of the number
376 ACE_Pipe::recv (size_t n
, ...) const
378 ACE_TRACE ("ACE_Pipe::recv");
380 int total_tuples
= ACE_Utils::truncate_cast
<int> (n
/ 2);
382 #if defined (ACE_HAS_ALLOCA)
383 iovp
= (iovec
*) alloca (total_tuples
* sizeof (iovec
));
385 # ifdef ACE_HAS_ALLOC_HOOKS
386 ACE_ALLOCATOR_RETURN (iovp
, (iovec
*)
387 ACE_Allocator::instance ()->malloc (total_tuples
*
391 ACE_NEW_RETURN (iovp
,
394 # endif /* ACE_HAS_ALLOC_HOOKS */
395 #endif /* !defined (ACE_HAS_ALLOCA) */
399 for (int i
= 0; i
< total_tuples
; ++i
)
401 iovp
[i
].iov_base
= va_arg (argp
, char *);
402 iovp
[i
].iov_len
= va_arg (argp
, int);
405 #if defined (ACE_WIN32)
406 ssize_t
const result
= ACE::recvv (this->read_handle (),
410 ssize_t
const result
= ACE_OS::readv (this->read_handle (),
413 #endif /* ACE_WIN32 */
415 #if !defined (ACE_HAS_ALLOCA)
416 # ifdef ACE_HAS_ALLOC_HOOKS
417 ACE_Allocator::instance ()->free (iovp
);
420 # endif /* ACE_HAS_ALLOC_HOOKS */
421 #endif /* !defined (ACE_HAS_ALLOCA) */
425 #endif /* !ACE_LACKS_VA_FUNCTIONS */
427 ACE_END_VERSIONED_NAMESPACE_DECL