2 //=============================================================================
6 * This is a simple test of Named Pipes that uses
7 * ACE_SPIPE_Acceptor and ACE_SPIPE_Connector classes. The test
8 * forks two processes or spawns two threads (depending upon the
9 * platform) and then executes the client and server allowing
10 * them to use the named pipe to exchange data. No user input is
11 * required as far as command line arguments are concerned.
13 * @author Prashant Jain <pjain@cs.wustl.edu>
15 //=============================================================================
18 #include "test_config.h"
19 #include "ace/Thread.h"
20 #include "ace/Thread_Manager.h"
21 #include "ace/SPIPE_Addr.h"
22 #include "ace/SPIPE_Connector.h"
23 #include "ace/SPIPE_Acceptor.h"
24 #include "ace/OS_NS_string.h"
25 #include "ace/OS_NS_unistd.h"
28 #if defined (ACE_HAS_STREAM_PIPES) || defined (ACE_HAS_WIN32_NAMED_PIPES)
29 # define TEST_HAS_STREAM_PIPES
32 #if defined (TEST_HAS_STREAM_PIPES)
34 static const char ACE_ALPHABET
[] = "abcdefghijklmnopqrstuvwxyz";
37 static const ACE_TCHAR
*PIPE_NAME
= ACE_TEXT ("ace_pipe_name");
42 const ACE_TCHAR
*rendezvous
= PIPE_NAME
;
43 ACE_SPIPE_Stream cli_stream
;
44 ACE_SPIPE_Connector con
;
48 if (con
.connect (cli_stream
, ACE_SPIPE_Addr (rendezvous
)) == -1)
49 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), rendezvous
, 1));
51 for (const char *c
= ACE_ALPHABET
; *c
!= '\0'; c
++)
52 if (cli_stream
.send (c
, 1) == -1)
53 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("send")));
55 if (cli_stream
.close () == -1)
56 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("close")));
58 #if defined (ACE_HAS_WIN32_NAMED_PIPES)
60 // Wait for server to get ready...
63 // Connect in bytestream-oriented mode.
64 if (con
.connect (cli_stream
,
65 ACE_SPIPE_Addr (rendezvous
),
72 PIPE_READMODE_BYTE
) == -1)
73 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), rendezvous
, 1));
76 // Write out the alphabet all at once.
77 if (cli_stream
.send_n (ACE_ALPHABET
,
78 ACE_OS::strlen (ACE_ALPHABET
)) != (ssize_t
) ACE_OS::strlen (ACE_ALPHABET
))
79 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("send_n")));
81 // Write out the alphabet one byte at a time
82 for (const char *d
= ACE_ALPHABET
; *d
!= '\0'; d
++)
83 if (cli_stream
.send (d
, 1) == -1)
84 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("send")));
86 if (cli_stream
.close () == -1)
87 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("close")));
90 #if !defined (ACE_WIN32)
99 ACE_SPIPE_Acceptor acceptor
;
100 ACE_SPIPE_Stream new_stream
;
102 const char *t
= ACE_ALPHABET
;
104 const ACE_TCHAR
*rendezvous
= PIPE_NAME
;
106 // Initialize named pipe listener.
108 if (acceptor
.open (ACE_SPIPE_Addr (rendezvous
)) == -1)
109 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("open"), 1));
111 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("waiting for connection\n")));
113 // Accept a client connection
114 if (acceptor
.accept (new_stream
, 0) == -1)
115 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("accept"), 1));
117 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Accepted connection\n")));
119 while (new_stream
.recv (buf
, 1) > 0)
121 ACE_TEST_ASSERT (*t
== buf
[0]);
124 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("End of connection. Closing handle\n")));
128 #if defined (ACE_HAS_WIN32_NAMED_PIPES)
129 // Initialize an NT bytestream named pipe listener.
130 if (acceptor
.open (ACE_SPIPE_Addr (rendezvous
),
134 PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
) == -1)
135 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("open"), 1));
137 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("waiting for connection\n")));
139 // Accept a client connection
140 if (acceptor
.accept (new_stream
, 0) == -1)
141 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("accept"), 1));
143 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Accepted connection\n")));
145 // The client will write the entire buffer at once, verify that we
146 // can stream it in one byte at a time.
147 for (t
= ACE_ALPHABET
; *t
; t
++)
149 if (new_stream
.recv (buf
, 1) <= 0)
151 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("recv"), 1));
154 ACE_TEST_ASSERT (*t
== buf
[0]);
157 // Wait for the client to stream in the buffer one byte at a time.
161 // Verify that we can read the stream of individual bytes all at
163 if (new_stream
.recv (buf
, sizeof(buf
)) != (ssize_t
) ACE_OS::strlen (ACE_ALPHABET
))
164 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("recv"), 1));
166 ACE_TEST_ASSERT(ACE_OS::memcmp(ACE_ALPHABET
, buf
, ACE_OS::strlen (ACE_ALPHABET
)) == 0);
168 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("End of connection. Closing handle\n")));
171 #endif /* defined (ACE_HAS_WIN32NAMED_PIPES) */
175 #endif /* TEST_HAS_STREAM_PIPES */
178 run_main (int, ACE_TCHAR
*[])
180 ACE_START_TEST (ACE_TEXT ("SPIPE_Test"));
182 #if defined (TEST_HAS_STREAM_PIPES)
183 #if !defined (ACE_LACKS_FORK)
184 switch (ACE_OS::fork ())
187 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("fork failed")));
194 #elif defined (ACE_HAS_THREADS)
195 if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (client
),
197 THR_NEW_LWP
| THR_DETACHED
) == -1)
198 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("thread create failed")));
200 if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (server
),
202 THR_NEW_LWP
| THR_DETACHED
) == -1)
203 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n%a"), ACE_TEXT ("thread create failed")));
205 ACE_Thread_Manager::instance ()->wait ();
206 #endif /* !ACE_LACKS_EXEC */
209 ACE_TEXT ("SPIPE is not supported on this platform\n")));
210 #endif /* TEST_HAS_STREAM_PIPES */