2 //=============================================================================
6 * This is a test of basic ACE_FIFO_* class functionality.
7 * The test forks two processes or spawns two threads (depending
8 * upon the platform) and then tests various data exchange
11 * @author Steve Huston <shuston@riverace.com>
13 //=============================================================================
15 #include "test_config.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/OS_NS_sys_stat.h"
18 #include "ace/OS_NS_sys_wait.h"
19 #include "ace/OS_NS_unistd.h"
21 #include "ace/FIFO_Send_Msg.h"
22 #include "ace/FIFO_Recv_Msg.h"
23 #include "ace/Handle_Set.h"
24 #include "ace/Lib_Find.h"
25 #include "ace/Thread.h"
26 #include "ace/Thread_Manager.h"
28 #if !defined (ACE_LACKS_MKFIFO)
30 static const char ACE_ALPHABET
[] = "abcdefghijklmnopqrstuvwxyz";
32 // This length is used for the "big buffer" send/receive.
33 static const size_t big_size
= (BUFSIZ
* 4);
38 ACE_TCHAR
*fifo_path
= reinterpret_cast <ACE_TCHAR
*> (arg
);
39 ACE_FIFO_Send_Msg fifo
;
40 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P|%t) client opening %s\n"), fifo_path
));
41 if (fifo
.open (fifo_path
) == -1)
42 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("(%P|%t) %p\n"), fifo_path
), 0);
44 // Try some transfers - the server part is expecting this data.
45 // First, try a nice, easy send.
47 ssize_t expect
= static_cast <ssize_t
> (ACE_OS::strlen (ACE_ALPHABET
));
48 send_count
= fifo
.send (ACE_ALPHABET
, ACE_OS::strlen (ACE_ALPHABET
));
49 if (send_count
== expect
)
51 // Ok, so far so good. Now try one that will overflow the reader
52 // side to be sure it properly tosses the overflow. Then send another
53 // to be sure it finds the start of the next message ok.
55 for (size_t i
= 0; i
< big_size
; ++i
)
56 big
[i
] = (i
% 2) ? 0x05 : 0x0A; // Make nice pattern in blown stack
57 expect
= static_cast <ssize_t
> (big_size
);
58 send_count
= fifo
.send (big
, big_size
);
59 if (send_count
== expect
)
61 expect
= static_cast <ssize_t
> (ACE_OS::strlen (ACE_ALPHABET
));
62 send_count
= fifo
.send (ACE_ALPHABET
, ACE_OS::strlen (ACE_ALPHABET
));
63 if (send_count
!= expect
)
65 ACE_TEXT ("(%P|%t) Final send; sent %d, expected %d")
67 send_count
, expect
, ACE_TEXT ("send")));
69 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P|%t) All sends ok\n")));
75 ACE_TEXT ("(%P|%t) Second send expected %d; sent %d. %p\n"),
76 expect
, send_count
, ACE_TEXT ("send")));
82 ACE_TEXT ("(%P|%t) First send expected %d; sent %d. %p\n"),
83 expect
, send_count
, ACE_TEXT ("send")));
86 if (fifo
.close () != 0)
87 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("fifo close")));
95 ACE_FIFO_Recv_Msg
*fifo
= reinterpret_cast <ACE_FIFO_Recv_Msg
*> (arg
);
97 // Wait for the client to get going and open the FIFO.
100 ACE_Time_Value
delay (10);
101 h
.set_bit (fifo
->get_handle ());
102 if (ACE::select (h
.max_set () + 1, h
, &delay
) == -1)
103 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("(%P|%t) server %p\n"),
104 ACE_TEXT ("select")),
107 // On AIX, select() always seems to select a fifo handle as a normal file,
108 // always readable. Just wait a second...
109 # if defined (AIX) || defined (HPUX) || defined (__osf__)
111 # endif /* AIX || HPUX */
113 // Read the things the client is sending; alphabet, huge overflow, then
118 ssize_t expect
= static_cast <ssize_t
> (ACE_OS::strlen (ACE_ALPHABET
));
119 recv_count
= fifo
->recv (buf
, sizeof (buf
));
120 if (recv_count
!= expect
)
121 ACE_ERROR_RETURN ((LM_ERROR
,
122 ACE_TEXT ("(%P|%t) Recv 1 expected %d, got %d. %p\n"),
123 expect
, recv_count
, ACE_TEXT ("recv")),
125 buf
[recv_count
] = '\0';
126 if (ACE_OS::strcmp (buf
, ACE_ALPHABET
) != 0)
127 ACE_ERROR ((LM_ERROR
,
128 ACE_TEXT ("(%P|%t) Recv 1 expected alphabet; got %s\n"),
131 // See documented return values for ACE_FIFO_Recv_Msg...
132 // We are being sent a message much longer than BUFSIZ.
133 // If this platform has STREAM pipes, the entire message will come
134 // through and we can grab it all. If not, then ACE_FIFO_Recv_Msg ditches
135 // the part of the message we don't read. This is rather a pain in the
136 // neck, but the API doesn't return info that more data is in the message
137 // (for STREAM pipes). When non-ACE_HAS_STREAM_PIPES discards data, the
138 // returned length will be larger than requested, though only the requested
139 // number of bytes are written to the buffer.
140 #if defined (ACE_HAS_STREAM_PIPES)
141 for (size_t remaining
= big_size
;
143 remaining
-= recv_count
)
145 #endif /* ACE_HAS_STREAM_PIPES */
147 // recv_count is sizeof(buf) on ACE_HAS_STREAM_PIPES; big_size on others.
148 #if defined (ACE_HAS_STREAM_PIPES)
149 expect
= static_cast <ssize_t
> (sizeof (buf
));
151 expect
= static_cast <ssize_t
> (big_size
);
152 #endif /* ACE_HAS_STREAM_PIPES */
153 recv_count
= fifo
->recv (buf
, sizeof (buf
));
154 if (recv_count
!= expect
)
155 ACE_ERROR_RETURN ((LM_ERROR
,
156 ACE_TEXT ("(%P|%t) Recv 2 expected %d, ")
157 ACE_TEXT ("got %d. %p\n"),
158 expect
, recv_count
, ACE_TEXT ("recv")),
160 #if defined (ACE_HAS_STREAM_PIPES)
162 #endif /* ACE_HAS_STREAM_PIPES */
164 expect
= static_cast <ssize_t
> (ACE_OS::strlen (ACE_ALPHABET
));
165 recv_count
= fifo
->recv (buf
, sizeof (buf
));
166 if (recv_count
!= expect
)
167 ACE_ERROR_RETURN ((LM_ERROR
,
168 ACE_TEXT ("(%P|%t) Recv 3 expected %d, got %d. %p\n"),
169 expect
, recv_count
, ACE_TEXT ("recv")),
171 buf
[recv_count
] = '\0';
172 if (ACE_OS::strcmp (buf
, ACE_ALPHABET
) != 0)
173 ACE_ERROR ((LM_ERROR
,
174 ACE_TEXT ("(%P|%t) Recv 3 expected alphabet; got %s\n"),
177 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P|%t) All receives ok\n")));
184 // Reader side opens first - it may fail if fifo not supported on this
186 ACE_TCHAR fifo_path
[MAXPATHLEN
];
187 if (ACE::get_temp_dir (fifo_path
, MAXPATHLEN
) == -1)
188 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
189 ACE_TEXT ("get_temp_dir")), 1);
190 ACE_OS::strcat (fifo_path
, ACE_TEXT ("FIFO_Test"));
191 ACE_FIFO_Recv_Msg read_side
;
192 // Open read only, not persistent (4th arg is 0)
193 if (-1 == read_side
.open (fifo_path
,
195 ACE_DEFAULT_FILE_PERMS
,
198 #if defined (ACE_WIN32)
199 if (errno
== ENOTSUP
)
201 ACE_DEBUG ((LM_DEBUG
,
202 ACE_TEXT ("FIFO not supported on Win32; ")
203 ACE_TEXT ("this is correct.\n")));
206 #endif /* ACE_WIN32 */
207 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
208 ACE_TEXT ("ACE_FIFO_Recv_Msg::open")),
212 // Ok, the FIFO opened clean for read. Now it's safe to spawn a
213 // process/thread and test some transfers.
215 int status
= 0; // Test status; innocent until proven guilty.
217 #if !defined (ACE_LACKS_FORK)
218 switch (ACE_OS::fork (ACE_TEXT ("child")))
221 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("fork failed")));
232 #elif defined (ACE_HAS_THREADS)
233 if (ACE_Thread_Manager::instance ()->spawn
234 (ACE_THR_FUNC (server
),
236 THR_NEW_LWP
| THR_DETACHED
) == -1)
238 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("server spawn")));
242 if (ACE_Thread_Manager::instance ()->spawn
243 (ACE_THR_FUNC (client
),
245 THR_NEW_LWP
| THR_DETACHED
) == -1)
247 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("client spawn")));
251 // Wait for the threads to exit.
252 ACE_Thread_Manager::instance ()->wait ();
255 ACE_TEXT ("This test requires multiple threads ")
256 ACE_TEXT ("or processes.\n")));
257 #endif /* ACE_HAS_THREADS */
259 if (read_side
.remove () != 0)
261 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("fifo remove")));
266 if (ACE_OS::stat (fifo_path
, &fifo_stat
) == 0)
268 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("FIFO %s should be gone but isn't\n"),
271 ACE_OS::unlink (fifo_path
); // Try to get rid of it.
278 run_main (int, ACE_TCHAR
*[])
280 ACE_START_TEST (ACE_TEXT ("FIFO_Test"));
283 errors
+= test_fifo_msg ();
292 run_main (int, ACE_TCHAR
*[])
294 ACE_START_TEST (ACE_TEXT ("FIFO_Test"));
296 ACE_ERROR ((LM_INFO
, ACE_TEXT ("FIFOs are not supported on this platform\n")));
302 #endif /* !ACE_LACKS_MKFIFO */