Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / SOCK_Dgram_Bcast_Test.cpp
blob950aeeb67e99dfa34535a9ad1ebe973638845abd
1 //=============================================================================
2 /**
3 * @file SOCK_Dgram_Bcast_Test.cpp
5 * This simple broadcast test is intended to check if ACE is capable
6 * of sending and receiving broadcasts. In single host environment most
7 * errors related to invalid broadcast initialization will not manifest
8 * themself, because usually broadcast on localhost interface works
9 * correctly. For this reason one should run also this test on two distinct
10 * hosts in single LAN.
11 * Tests that a call to open with an any address binds to the any address
12 * for the protocol passed in.
14 * @author Marek Brudka (mbrudka@elka.pw.edu.pl)
16 //=============================================================================
19 #include "test_config.h"
20 #include "ace/OS_NS_string.h"
21 #include "ace/OS_NS_unistd.h"
22 #include "ace/OS_NS_sys_time.h"
23 #include "ace/Log_Msg.h"
24 #include "ace/Get_Opt.h"
25 #include "ace/SOCK_Dgram_Bcast.h"
26 #include "ace/Thread_Manager.h"
27 #include "ace/Process.h"
28 #include "ace/Process_Manager.h"
30 static int dgram_port = 14521;
31 static int dgrams_no = 10;
32 static ACE_Time_Value dgram_recv_timeout( 5, 0 );
33 static ACE_exitcode receiver_exit_code = 0;
35 /*\brief Create and send single datagram
36 \param socket broadcast over this socket
37 \param datagram_no datagram identifier
38 \return -1 if error, 0 if OK
40 int send_datagram (ACE_SOCK_Dgram_Bcast &socket, int datagram_no)
42 static char dgram_buffer[BUFSIZ];
44 ACE_OS::snprintf (dgram_buffer, sizeof(dgram_buffer),
45 "Datagram %d", datagram_no);
46 if (socket.send (dgram_buffer,
47 ACE_OS::strlen (dgram_buffer) + 1,
48 dgram_port) < 0 )
49 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
50 ACE_TEXT ("Cannot broadcast datagram")), -1);
51 else
52 ACE_DEBUG ((LM_INFO, ACE_TEXT ("%C sent\n"), dgram_buffer));
53 return 0;
56 /*\brief Send a sequence of datagrams with 1 second period
57 \note Th function employs dgram_port and dgrams_no global variables
58 \retval -1 if error
59 \retval 0 if sent
61 int run_sender( )
63 ACE_DEBUG ((LM_INFO,
64 ACE_TEXT ("Sending %d datagrams on port %d\n"),
65 dgrams_no,
66 dgram_port));
67 ACE_SOCK_Dgram_Bcast socket;
69 if (socket.open (ACE_Addr::sap_any) != -1)
71 while (dgrams_no-- != 0)
73 if (send_datagram (socket, dgrams_no) < 0)
74 break;
75 ACE_OS::sleep (1);
77 socket.close ();
78 return (0);
81 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
82 ACE_TEXT ("Cannot open broadcast socket")), -1);
85 /*\brief Receive single datagram
86 \note The function employes dgram_port and dgram_recv_timeout variables
87 \retval -1 if not received,
88 \retval 0 received a datagrams
90 int run_receiver ()
92 ACE_DEBUG
93 ((LM_INFO,
94 ACE_TEXT ("Receiving datagrams from port %d with timeout %d ms\n"),
95 dgram_port, dgram_recv_timeout.msec ()));
97 ACE_SOCK_Dgram socket;
98 ACE_INET_Addr remote ;
99 static char dgram_buffer[BUFSIZ];
101 if (socket.open (ACE_INET_Addr (dgram_port)) != -1)
102 if (socket.recv (dgram_buffer, sizeof (dgram_buffer),
103 remote, 0, &dgram_recv_timeout) > 0)
105 ACE_DEBUG ((LM_INFO, ACE_TEXT ("%C received\n"), dgram_buffer));
106 return 0;
108 else
110 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
111 ACE_TEXT ("Cannot receive datagrams")), -1);
113 else
115 ACE_ERROR_RETURN ((LM_ERROR,
116 ACE_TEXT ("%p: %d\n"),
117 ACE_TEXT ("Cannot open broadcast socket on port"), dgram_port), -1);
121 #if !defined (ACE_HAS_PROCESS_SPAWN) && defined (ACE_HAS_THREADS)
122 /* \brief Thread main function to run run_receiver function
123 \note run_receiver return valu is stored in receiver_exit_code global variable
125 static ACE_THR_FUNC_RETURN run_thread_receiver (void *)
127 receiver_exit_code = run_receiver ();
128 return 0;
130 #endif /* !defined (ACE_HAS_PROCESS_SPAWN) && defined (ACE_HAS_THREADS) */
132 /* \brief Just runs automatic tests
134 Function sends a number of datagrams, spawns child thread or process and
135 tries to receive at least one datagram.
136 \retval 0 datagram was received
137 \retval -1 datagram was not received
139 int run_auto_test (const ACE_TCHAR *prog_name)
141 #if defined (ACE_HAS_PROCESS_SPAWN)
142 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in process mode\n")));
144 ACE_Process_Options opts;
145 pid_t child_pid;
146 opts.command_line (ACE_TEXT ("%s -p %d -t %d -a -r"),
147 prog_name, dgram_port, static_cast<int>(dgram_recv_timeout.msec ()));
148 if ((child_pid = ACE_Process_Manager::instance ()->spawn (opts)) == -1)
149 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n()")), -1);
151 #elif defined (ACE_HAS_THREADS)
152 ACE_UNUSED_ARG (prog_name);
153 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in thread mode\n")));
154 if (ACE_Thread_Manager::instance ()->spawn (run_thread_receiver) == -1)
155 ACE_ERROR_RETURN ((LM_ERROR,
156 ACE_TEXT ("%p\n"),
157 ACE_TEXT ("spawn_n ()")), -1);
158 #else
159 ACE_ERROR_RETURN ((LM_ERROR,
160 ACE_TEXT ("Cannot run in auto_test mode without fork or threads.\n")),
161 -1);
162 #endif /* defined (ACE_HAS_PROCESS_SPAWN) */
164 ACE_DEBUG ((LM_INFO,
165 ACE_TEXT ("Sending datagrams on port %d in auto_test mode\n"),
166 dgram_port));
168 ACE_SOCK_Dgram_Bcast socket;
170 if (socket.open (ACE_Addr::sap_any) != -1)
172 // send datagrams until child finishes
173 while (1)
175 send_datagram (socket, dgrams_no--);
176 ACE_Time_Value child_timeout (1);
177 #if defined (ACE_HAS_PROCESS_SPAWN)
179 if (ACE_Process_Manager::instance ()->wait (child_pid,
180 child_timeout,
181 &receiver_exit_code) == child_pid)
182 break;
183 #else /* ACE_HAS_THREADS */
184 // sleep 1 second or wait for child thread
185 child_timeout += ACE_OS::gettimeofday () ;
186 if (ACE_Thread_Manager::instance ()->wait (&child_timeout) == 0)
187 break;
188 #endif
190 socket.close ();
191 ACE_DEBUG ((LM_INFO, ACE_TEXT ("Child finished with %d exit code\n"),
192 receiver_exit_code));
194 else
195 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
196 ACE_TEXT ("Cannot open broadcast socket")), -1);
197 return (receiver_exit_code);
200 void print_usage ()
202 ACE_OS::printf("Usage:SOCK_Dgram_Bast_Test [-p port] [-n dgrams_no] [-t timeout_ms] [-s] [-r]\n"
203 "\tp broadcast port [14521]\n"
204 "\tn number of datagrams to broadcast [30] (<0 infinite)\n"
205 "\tt timeout in seconds for receive [5] (<=0 infinite)\n"
206 "\ts send datagrams and exit\n"
207 "\tr receive one datagram and exit\n\n"
208 "\t run auto-test when no r and s option is passed\n"
209 "\t test failures are manifested by -1 exit value, otherwise 0\n");
212 int run_main (int argc, ACE_TCHAR *argv[])
214 // parse options and run in appropriate mode
215 int opt = 0;
216 int auto_test_recv = 0;
217 int result = 0;
218 ACE_Get_Opt opts (argc, argv, ACE_TEXT ("p:t:n:sra"));
219 while ((opt = opts ()) != -1)
220 switch (opt)
222 case 'a':
223 auto_test_recv = 1;
224 break;
225 case 's':
226 return (run_sender());
227 case 'r':
229 if (auto_test_recv)
231 ACE_START_TEST (ACE_TEXT ("SOCK_Dgram_Bcast_Test_Child"));
232 result = run_receiver ();
233 ACE_END_TEST;
234 return result;
236 return (run_receiver ());
238 case 'n':
239 dgrams_no = ACE_OS::atoi (opts.opt_arg ());
240 break;
241 case 't':
242 dgram_recv_timeout.msec (ACE_OS::atoi (opts.opt_arg ()));
243 break;
244 case 'p':
245 dgram_port = ACE_OS::atoi (opts.opt_arg ());
246 break;
247 default:
248 print_usage ();
249 return -1;
251 ACE_START_TEST (ACE_TEXT ("SOCK_Dgram_Bcast_Test"));
253 #ifndef ACE_LACKS_IOCTL
254 result = run_auto_test (argc > 0 ? argv[0] : ACE_TEXT ("SOCK_Dgram_Bcast_Test"));
255 #endif
257 ACE_END_TEST;
258 return result;