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.
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
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;
45 ACE_INET_Addr
*remote_addr
= reinterpret_cast<ACE_INET_Addr
*> (arg
);
46 ACE_INET_Addr
server_addr (remote_addr
->get_port_number (),
48 ACE_SOCK_Stream cli_stream
;
49 ACE_SOCK_Connector con
;
50 ACE_Time_Value
timeout (ACE_DEFAULT_TIMEOUT
);
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
,
62 ACE_TEXT ("(%P|%t) %p\n"),
63 ACE_TEXT ("connection failed")));
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.
80 ssize_t byte_count
= 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
));
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
));
113 len
= ACE_OS::sendfile (cli_stream
.get_handle (),
120 ACE_ERROR ((LM_ERROR
,
121 ACE_TEXT ("(%P|%t) %p\n"),
122 ACE_TEXT ("Test 1, sendfile failed")));
127 ACE_ERROR ((LM_ERROR
,
128 ACE_TEXT ("(%P|%t) sendfile len %b; should be 255\n"),
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.
137 // Give it a chance to get here
139 #ifndef ACE_LACKS_VA_FUNCTIONS
140 len
= cli_stream
.recv (4,
149 ACE_ERROR ((LM_ERROR
,
150 ACE_TEXT ("(%P|%t) recv len is %b, but should be 255!\n"),
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
]));
165 if (in_fd
!= ACE_INVALID_HANDLE
)
166 (void) ACE_OS::close (in_fd
);
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
,
185 ACE_ERROR ((LM_ERROR
,
186 ACE_TEXT ("(%P|%t) %p\n"),
187 ACE_TEXT ("accept")));
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.
209 len
= sock_str
.recv (buffer
, 255);
212 ACE_ERROR ((LM_ERROR
,
213 ACE_TEXT ("(%P|%t) %p\n"),
214 ACE_TEXT ("Test 1, recv failed")));
220 ACE_ERROR ((LM_ERROR
,
221 ACE_TEXT ("(%P|%t) recv len is %b, but should be 255!\n"),
225 for (i
= 0; i
< static_cast<int>(len
); i
++)
228 ACE_ERROR ((LM_ERROR
,
229 ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
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,
252 ACE_ERROR ((LM_ERROR
,
253 ACE_TEXT ("(%P|%t) send len is %b, but should be 255!\n"),
262 #endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
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"),
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")))
289 ACE_ERROR ((LM_ERROR
,
290 ACE_TEXT ("(%P|%t) %p\n"),
291 ACE_TEXT ("fork failed"),
295 client (&server_addr
);
299 server (reinterpret_cast<void *> (&peer_acceptor
));
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"),
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"),
321 // Wait for the threads to exit.
322 ACE_Thread_Manager::instance ()->wait ();
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