Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Sendfile_Test.cpp
blob153d256f67e0ecd49d8091863a09d6cc36184131
1 /**
2 * @file Sendfile_Test.cpp
4 * This is a test of the @c ACE_OS::sendfile() wrapper function. It
5 * is primarily meant to test the case when ACE_HAS_SENDFILE is not
6 * defined, i.e. when sendfile() support is emulated.
8 * @author
9 * Steve Huston <shuston@riverace.com>
10 * Ossama Othman <ossama@dre.vanderbilt.edu>
13 #include "test_config.h"
14 #include "ace/Lib_Find.h"
15 #include "ace/OS_NS_string.h"
16 #include "ace/OS_NS_sys_wait.h"
17 #include "ace/OS_NS_unistd.h"
18 #include "ace/OS_NS_fcntl.h"
19 #include "ace/Thread.h"
20 #include "ace/Thread_Manager.h"
21 #include "ace/Time_Value.h"
22 #include "ace/SOCK_Connector.h"
23 #include "ace/SOCK_Acceptor.h"
24 #include "ace/SOCK_Stream.h"
25 #include "ace/OS_NS_sys_sendfile.h"
27 // Change to non-zero if test fails
28 static int Test_Result = 0;
30 #if !defined (ACE_LACKS_FORK) || defined (ACE_HAS_THREADS)
32 // This test sends a large amount of data. The purpose is to overflow the
33 // TCP send window, causing the sender to block (it's a send_n). This value
34 // is the amount to send. The assumption is that no implementation has a
35 // receive window larger than 128K bytes. If one is found, this is the place
36 // to change it.
37 // For some odd reason, NT will try to send a single large buffer, but not
38 // multiple smaller ones that add up to the large size.
39 const size_t Test3_Send_Size = 4*1024;
40 const size_t Test3_Loops = 10;
42 static void *
43 client (void *arg)
45 ACE_INET_Addr *remote_addr = reinterpret_cast<ACE_INET_Addr *> (arg);
46 ACE_INET_Addr server_addr (remote_addr->get_port_number (),
47 ACE_LOCALHOST);
48 ACE_SOCK_Stream cli_stream;
49 ACE_SOCK_Connector con;
50 ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
52 ACE_DEBUG ((LM_DEBUG,
53 ACE_TEXT ("(%P|%t) Connecting to port %d\n"),
54 server_addr.get_port_number()));
56 // Initiate connection with server; don't wait forever
57 if (con.connect (cli_stream,
58 server_addr,
59 &timeout) == -1)
61 ACE_ERROR ((LM_ERROR,
62 ACE_TEXT ("(%P|%t) %p\n"),
63 ACE_TEXT ("connection failed")));
64 Test_Result = 1;
65 return 0;
68 ACE_DEBUG ((LM_DEBUG,
69 ACE_TEXT ("(%P|%t) connected to %C\n"),
70 server_addr.get_host_name ()));
72 //******************* TEST 1 ******************************
74 // Send the 255 byte buffer in 5 chunks. The
75 // server will verify that the correct data is sent, and that there
76 // is no more and no less.
78 u_char buffer[255];
79 size_t i;
80 ssize_t byte_count = 0;
81 ssize_t len = 0;
82 off_t offset = 0;
84 // The server will verify that this data pattern gets there intact.
86 for (i = 0; i < sizeof buffer; ++i)
87 buffer[i] = static_cast<u_char> (i);
89 const ACE_TCHAR file[] = ACE_TEXT ("Sendfile_Test_File");
90 static const size_t file_sz = sizeof (file) / sizeof (file[0]);
91 ACE_TCHAR test_file[MAXPATHLEN + 1];
92 ACE_HANDLE in_fd = ACE_INVALID_HANDLE;
93 if (ACE::get_temp_dir (test_file, MAXPATHLEN - file_sz) == -1
94 || ACE_OS::strcat (test_file, file) == 0
95 || (in_fd = ACE_OS::open (test_file, O_CREAT | O_RDWR | O_TRUNC,
96 ACE_DEFAULT_FILE_PERMS)) == ACE_INVALID_HANDLE)
98 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) open %p\n"), test_file));
99 Test_Result = 1;
100 goto cleanup;
103 ACE_OS::unlink (test_file);
105 byte_count = ACE_OS::write (in_fd, buffer, sizeof (buffer));
107 if (byte_count != static_cast<ssize_t> (sizeof (buffer)))
109 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) write %p\n"), test_file));
110 Test_Result = 1;
113 len = ACE_OS::sendfile (cli_stream.get_handle (),
114 in_fd,
115 &offset,
116 byte_count);
118 if (len == -1)
120 ACE_ERROR ((LM_ERROR,
121 ACE_TEXT ("(%P|%t) %p\n"),
122 ACE_TEXT ("Test 1, sendfile failed")));
123 Test_Result = 1;
124 goto cleanup;
126 else if (len != 255)
127 ACE_ERROR ((LM_ERROR,
128 ACE_TEXT ("(%P|%t) sendfile len %b; should be 255\n"),
129 len));
131 //******************* TEST 2 ******************************
133 // The same data is coming back - receive it using recv (size_t n,
134 // ...) and compare it to the original data.
136 u_char buffer2[255];
137 // Give it a chance to get here
138 ACE_OS::sleep (2);
139 #ifndef ACE_LACKS_VA_FUNCTIONS
140 len = cli_stream.recv (4,
141 buffer2,
142 150,
143 &buffer2[150],
144 105);
145 #endif
147 if (len != 255)
149 ACE_ERROR ((LM_ERROR,
150 ACE_TEXT ("(%P|%t) recv len is %b, but should be 255!\n"),
151 len));
154 for (i = 0; i < static_cast<size_t>(len); i++)
155 if (buffer2[i] != buffer[i])
157 ACE_ERROR ((LM_ERROR,
158 ACE_TEXT ("(%P|%t) Test 2, rcvd byte %B is %d, not %d\n"),
159 i, buffer2[i], buffer[i]));
160 Test_Result = 1;
163 cleanup:
164 cli_stream.close ();
165 if (in_fd != ACE_INVALID_HANDLE)
166 (void) ACE_OS::close (in_fd);
168 return 0;
171 static void *
172 server (void *arg)
174 ACE_SOCK_Acceptor *peer_acceptor = (ACE_SOCK_Acceptor *) arg;
175 ACE_SOCK_Stream sock_str;
176 ACE_INET_Addr cli_addr;
177 ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
179 // Accept the connection over which the stream tests will run.
180 // Don't lock up if client doesn't connect
181 if (peer_acceptor->accept (sock_str,
182 &cli_addr,
183 &timeout) == -1)
185 ACE_ERROR ((LM_ERROR,
186 ACE_TEXT ("(%P|%t) %p\n"),
187 ACE_TEXT ("accept")));
188 Test_Result = 1;
189 return 0;
192 ACE_DEBUG ((LM_DEBUG,
193 ACE_TEXT ("(%P|%t) client %C connected from %d\n"),
194 cli_addr.get_host_name (),
195 cli_addr.get_port_number ()));
197 //******************* TEST 1 ******************************
199 // Do a iovec recvv - the client should send 255 bytes, which we
200 // will be detected and read into a ACE-allocated buffer. Use a 5
201 // second timeout to give the client a chance to send it all.
203 ACE_OS::sleep (5);
205 u_char buffer[255];
206 ssize_t len;
207 int i;
209 len = sock_str.recv (buffer, 255);
210 if (len == -1)
212 ACE_ERROR ((LM_ERROR,
213 ACE_TEXT ("(%P|%t) %p\n"),
214 ACE_TEXT ("Test 1, recv failed")));
215 Test_Result = 1;
218 if (len != 255)
220 ACE_ERROR ((LM_ERROR,
221 ACE_TEXT ("(%P|%t) recv len is %b, but should be 255!\n"),
222 len));
225 for (i = 0; i < static_cast<int>(len); i++)
226 if (buffer[i] != i)
228 ACE_ERROR ((LM_ERROR,
229 ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
231 buffer[i],
232 i));
233 Test_Result = 1;
236 //******************* TEST 2 ******************************
238 // Send the buffer back, using send (size_t n, ...) in 3 pieces.
240 #ifndef ACE_LACKS_VA_FUNCTIONS
241 len = sock_str.send (6,
242 buffer,
244 &buffer[42],
245 189,
246 &buffer[231],
247 24);
248 #endif
250 if (len != 255)
252 ACE_ERROR ((LM_ERROR,
253 ACE_TEXT ("(%P|%t) send len is %b, but should be 255!\n"),
254 len));
257 sock_str.close();
259 return 0;
262 #endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
264 void
265 spawn ()
267 // Acceptor
268 ACE_SOCK_Acceptor peer_acceptor;
270 // Create a server address.
271 ACE_INET_Addr server_addr;
273 // Bind listener to any port and then find out what the port was.
274 if (peer_acceptor.open (ACE_Addr::sap_any) == -1
275 || peer_acceptor.get_local_addr (server_addr) == -1)
276 ACE_ERROR ((LM_ERROR,
277 ACE_TEXT ("(%P|%t) %p\n"),
278 ACE_TEXT ("open")));
279 else
281 ACE_DEBUG ((LM_DEBUG,
282 ACE_TEXT ("(%P|%t) starting server at port %d\n"),
283 server_addr.get_port_number ()));
285 #if !defined (ACE_LACKS_FORK)
286 switch (ACE_OS::fork (ACE_TEXT ("child")))
288 case -1:
289 ACE_ERROR ((LM_ERROR,
290 ACE_TEXT ("(%P|%t) %p\n"),
291 ACE_TEXT ("fork failed"),
292 1));
293 ACE_OS::abort ();
294 case 0:
295 client (&server_addr);
296 ACE_OS::exit (0);
297 /* NOTREACHED */
298 default:
299 server (reinterpret_cast<void *> (&peer_acceptor));
300 ACE_OS::wait ();
302 #elif defined (ACE_HAS_THREADS)
303 if (ACE_Thread_Manager::instance ()->spawn
304 (ACE_THR_FUNC (server),
305 reinterpret_cast<void *> (&peer_acceptor),
306 THR_NEW_LWP | THR_DETACHED) == -1)
307 ACE_ERROR ((LM_ERROR,
308 ACE_TEXT ("(%P|%t) %p\n%a"),
309 ACE_TEXT ("thread create failed"),
310 1));
312 if (ACE_Thread_Manager::instance ()->spawn
313 (ACE_THR_FUNC (client),
314 reinterpret_cast<void *> (&server_addr),
315 THR_NEW_LWP | THR_DETACHED) == -1)
316 ACE_ERROR ((LM_ERROR,
317 ACE_TEXT ("(%P|%t) %p\n%a"),
318 ACE_TEXT ("thread create failed"),
319 1));
321 // Wait for the threads to exit.
322 ACE_Thread_Manager::instance ()->wait ();
323 #else
324 ACE_ERROR ((LM_INFO,
325 ACE_TEXT ("(%P|%t) ")
326 ACE_TEXT ("only one thread may be run ")
327 ACE_TEXT ("in a process on this platform\n")));
328 #endif /* ACE_HAS_THREADS */
330 peer_acceptor.close ();
335 run_main (int, ACE_TCHAR *[])
337 ACE_START_TEST (ACE_TEXT ("Sendfile_Test"));
339 #ifndef ACE_LACKS_ACCEPT
340 spawn ();
341 #endif
343 ACE_END_TEST;
344 return Test_Result;