source: rtems-libbsd/testsuite/loopback01/test_main.c @ 37b0ab6

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 37b0ab6 was 37b0ab6, checked in by Sebastian Huber <sebastian.huber@…>, on 10/25/13 at 13:37:06

loopback01: Wait for client termination

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 *  This is the body of the test. It does not do much except ensure
3 *  that the target is alive after initializing the TCP/IP stack.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8
9#include <rtems/bsd/sys/param.h>
10#include <sys/socket.h>
11#include <netinet/in.h>
12
13#define TEST_NAME "LIBBSD LOOPBACK 1"
14
15#include <rtems/error.h>
16#include <assert.h>
17#include <stdio.h>
18#include <stdarg.h>
19#include <stdlib.h>
20#include <string.h>
21#include <errno.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <sysexits.h>
25
26#include <machine/rtems-bsd-commands.h>
27
28#include <rtems.h>
29
30static rtems_id masterTask;
31
32/*
33 * Thread-safe output routines
34 */
35static rtems_id printMutex;
36static void printSafe(const char *fmt, ...)
37{
38    va_list args;
39    va_start(args, fmt);
40    rtems_semaphore_obtain(printMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
41    vprintf(fmt, args);
42    rtems_semaphore_release(printMutex);
43    va_end(args);
44}
45#define printf printSafe
46
47static void
48setSelfPrio(rtems_task_priority prio)
49{
50        rtems_status_code sc;
51
52        sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
53        assert(sc == RTEMS_SUCCESSFUL);
54}
55
56static rtems_event_set argToClientEvent(rtems_task_argument arg)
57{
58    return 1U << arg;
59}
60
61static void
62sendClientEventToMasterTask(rtems_task_argument arg)
63{
64    rtems_status_code sc;
65
66    sc = rtems_event_send(masterTask, argToClientEvent(arg));
67    assert(sc == RTEMS_SUCCESSFUL);
68}
69
70static void
71waitForClientEvents(rtems_event_set which)
72{
73    rtems_status_code sc;
74    rtems_event_set events;
75
76    sc = rtems_event_receive(
77        which,
78        RTEMS_EVENT_ALL | RTEMS_WAIT,
79        RTEMS_NO_TIMEOUT,
80        &events
81    );
82    assert(sc == RTEMS_SUCCESSFUL);
83}
84
85/*
86 * Spawn a task
87 */
88static void spawnTask(rtems_task_entry entryPoint, rtems_task_priority priority, rtems_task_argument arg)
89{
90    rtems_status_code sc;
91    rtems_id tid;
92
93    sc = rtems_task_create(rtems_build_name('t','a','s','k'),
94            priority,
95            RTEMS_MINIMUM_STACK_SIZE+(8*1024),
96            RTEMS_PREEMPT|RTEMS_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
97            RTEMS_FLOATING_POINT|RTEMS_LOCAL,
98            &tid);
99    if (sc != RTEMS_SUCCESSFUL)
100        rtems_panic("Can't create task: %s", rtems_status_text(sc));
101    sc = rtems_task_start(tid, entryPoint, arg);
102    if (sc != RTEMS_SUCCESSFUL)
103        rtems_panic("Can't start task: %s", rtems_status_text(sc));
104}
105
106/*
107 * Server subtask
108 */
109static rtems_task workerTask(rtems_task_argument arg)
110{
111    int s = arg;
112    char msg[80];
113    char reply[100];
114    int i;
115
116    for (;;) {
117        if ((i = read(s, msg, sizeof msg)) < 0) {
118            printf("Server couldn't read message from client: %s\n", strerror(errno));
119            break;
120        }
121        if (i == 0)
122            break;
123        i = sprintf(reply, "Server received %d (%s)", i, msg);
124        if ((i = write(s, reply, i+1)) < 0) {
125            printf("Server couldn't write message to client: %s\n", strerror(errno));
126            break;
127        }
128    }
129    if (close(s) < 0)
130        printf("Can't close worker task socket: %s\n", strerror(errno));
131    printf("Worker task terminating.\n");
132    rtems_task_delete(RTEMS_SELF);
133}
134
135/*
136 * Server Task
137 */
138static rtems_task serverTask(rtems_task_argument arg)
139{
140    int s, s1;
141    socklen_t addrlen;
142  struct sockaddr_in myAddr, farAddr;
143    rtems_task_priority myPriority;
144
145  printf("Create socket.\n");
146  s = socket(AF_INET, SOCK_STREAM, 0);
147  if (s < 0)
148    rtems_panic("Can't create socket: %s\n", strerror(errno));
149    memset(&myAddr, 0, sizeof myAddr);
150  myAddr.sin_family = AF_INET;
151  myAddr.sin_port = htons(1234);
152  myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
153  printf("Bind socket.\n");
154  if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
155    rtems_panic("Can't bind socket: %s\n", strerror(errno));
156  if (listen(s, 5) < 0)
157    printf("Can't listen on socket: %s\n", strerror(errno));
158    rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &myPriority);
159    for(;;) {
160        addrlen = sizeof farAddr;
161        s1 = accept(s, (struct sockaddr *)&farAddr, &addrlen);
162        if (s1 < 0)
163            rtems_panic("Can't accept connection: %s", strerror(errno));
164        else
165            printf("ACCEPTED:%lX\n", ntohl(farAddr.sin_addr.s_addr));
166        spawnTask(workerTask, myPriority, s1);
167    }
168}
169
170/*
171 * The real part of the client
172 */
173static rtems_task clientWorker(int arg)
174{
175  int s;
176  struct sockaddr_in myAddr, farAddr;
177  char cbuf[50];
178  int i;
179
180  s = socket(AF_INET, SOCK_STREAM, 0);
181  if (s < 0) {
182    printf("Can't create client socket: %s\n", strerror(errno));
183    return;
184  }
185  memset(&myAddr, 0, sizeof myAddr);
186  myAddr.sin_family = AF_INET;
187  myAddr.sin_port = htons(0);
188  myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
189  if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
190    printf("Can't bind socket: %s\n", strerror(errno));
191    goto close;
192  }
193
194  memset(&farAddr, 0, sizeof farAddr);
195  farAddr.sin_family = AF_INET;
196  farAddr.sin_port = htons(1234);
197  farAddr.sin_addr.s_addr = htonl(INADDR_ANY);
198  printf("Connect to server.\n");
199  if (connect(s, (struct sockaddr *)&farAddr, sizeof farAddr) < 0) {
200    printf("Can't connect to server: %s\n", strerror(errno));
201        goto close;
202    }
203    i = sprintf(cbuf, "Hi there, server (%d).", arg);
204    i++;    /* Send the '\0', too */
205    printf("Write %d-byte message to server.\n", i);
206    if (write(s, cbuf, i) < 0) {
207      printf("Can't write to server: %s\n", strerror(errno));
208      goto close;
209    }
210    if ((i = read(s, cbuf, sizeof cbuf)) < 0) {
211      printf("Can't read from server: %s\n", strerror(errno));
212      goto close;
213    }
214    printf("Read %d from server: %.*s\n", i, i, cbuf);
215  close:
216    printf("Client closing connection.\n");
217    if (close(s) < 0)
218        printf("Can't close client task socket: %s\n", strerror(errno));
219}
220
221/*
222 * Client Task
223 */
224static rtems_task clientTask(rtems_task_argument arg)
225{
226    clientWorker(arg);
227    sendClientEventToMasterTask(arg);
228    printf("Client task terminating.\n");
229    rtems_task_delete( RTEMS_SELF );
230}
231
232/*
233 * RTEMS Startup Task
234 */
235static void test_main(void)
236{
237  rtems_status_code    sc;
238  rtems_task_priority  old;
239  int                  exit_code;
240  char *lo0[] = {
241    "ifconfig",
242    "lo0",
243    "inet",
244    "127.0.0.1",
245    "netmask",
246    "255.255.255.0",
247    NULL
248  };
249
250  masterTask = rtems_task_self();
251
252  setSelfPrio(RTEMS_MAXIMUM_PRIORITY - 1);
253
254  sc = rtems_semaphore_create(
255    rtems_build_name('P','m','t','x'),
256    1,
257    RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|
258      RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
259    0,
260    &printMutex
261  );
262  if (sc != RTEMS_SUCCESSFUL)
263    rtems_panic("Can't create printf mutex:", rtems_status_text(sc));
264
265  sc = rtems_task_set_priority( RTEMS_SELF, 50, &old );
266  if (sc != RTEMS_SUCCESSFUL)
267    rtems_panic("Can't create printf mutex:", rtems_status_text(sc));
268
269  /*
270   *  Network is initialized when we get her
271   */
272
273  printf("Try running client with no server present.\n");
274  printf("Should fail with `connection refused'.\n");
275  clientWorker(0);
276
277  exit_code = rtems_bsd_command_ifconfig(nitems(lo0) - 1, lo0);
278  assert(exit_code == EX_OK);
279
280  printf("\nStart server.\n");
281  spawnTask(serverTask, 110, 0);
282
283  printf("\nTry running client with server present.\n");
284  spawnTask(clientTask, 120, 1);
285  waitForClientEvents(argToClientEvent(1));
286
287  printf("\nTry running two clients.\n");
288  spawnTask(clientTask, 120, 2);
289  spawnTask(clientTask, 120, 3);
290  waitForClientEvents(argToClientEvent(2) | argToClientEvent(3));
291
292  printf("\nTry running three clients.\n");
293  spawnTask(clientTask, 120, 4);
294  spawnTask(clientTask, 120, 5);
295  spawnTask(clientTask, 120, 6);
296  waitForClientEvents(argToClientEvent(4) | argToClientEvent(5) | argToClientEvent(6));
297
298  puts( "*** END OF " TEST_NAME " TEST ***" );
299  exit( 0 );
300}
301
302#include <rtems/bsd/test/default-init.h>
Note: See TracBrowser for help on using the repository browser.