source: rtems-libbsd/testsuite/program01/test_main.c @ 666a568

55-freebsd-126-freebsd-12
Last change on this file since 666a568 was 666a568, checked in by Sebastian Huber <sebastian.huber@…>, on 08/25/17 at 12:23:18

Include missing <string.h> and <limits.h>

Fix warnings.

Update #2132.
Update #2133.

  • Property mode set to 100644
File size: 13.0 KB
Line 
1/*
2 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <err.h>
33#include <assert.h>
34#include <errno.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38#include <syslog.h>
39#include <sys/socket.h>
40#include <fcntl.h>
41
42#define RTEMS_BSD_PROGRAM_NO_EXIT_WRAP
43#define RTEMS_BSD_PROGRAM_NO_PRINTF_WRAP
44#include <machine/rtems-bsd-program.h>
45#include <machine/pcpu.h>
46
47#include <rtems.h>
48#include <rtems/libcsupport.h>
49
50#define TEST_NAME "LIBBSD SYSCALLS 1"
51
52struct alloc_ctx {
53        enum alloc_type {
54                ALLOC_MALLOC = 0,
55                ALLOC_CALLOC = 1,
56                ALLOC_REALLOC = 2,
57                ALLOC_STRDUP = 3,
58                ALLOC_ASPRINTF = 4,
59                ALLOC_LAST = 5,
60        } type;
61        unsigned free;
62#define ALLOC_FREE_NONE         0x0
63#define ALLOC_FREE_FIRST        0x1
64#define ALLOC_FREE_SECOND       0x2
65#define ALLOC_FREE_THIRD        0x4
66#define ALLOC_FREE_ALL          (ALLOC_FREE_FIRST | \
67                                ALLOC_FREE_SECOND | \
68                                ALLOC_FREE_THIRD)
69};
70
71typedef void (*no_mem_test_body)(int fd);
72
73typedef struct {
74        no_mem_test_body body;
75        int fd;
76        rtems_id master_task;
77} no_mem_test;
78
79static void
80no_mem_task(rtems_task_argument arg)
81{
82        const no_mem_test *self = (const no_mem_test *) arg;
83        rtems_status_code sc;
84        void *greedy;
85
86        assert(rtems_configuration_get_unified_work_area());
87
88        greedy = rtems_workspace_greedy_allocate(NULL, 0);
89        (*self->body)(self->fd);
90        rtems_workspace_greedy_free(greedy);
91
92        sc = rtems_event_transient_send(self->master_task);
93        assert(sc == RTEMS_SUCCESSFUL);
94
95        sc = rtems_task_suspend(RTEMS_SELF);
96        assert(sc == RTEMS_SUCCESSFUL);
97}
98
99void
100do_no_mem_test(no_mem_test_body body, int fd)
101{
102        no_mem_test test = {
103                .body = body,
104                .fd = fd,
105                .master_task = rtems_task_self()
106        };
107        rtems_status_code sc;
108        rtems_id id;
109        rtems_resource_snapshot snapshot;
110
111        rtems_resource_snapshot_take(&snapshot);
112
113        sc = rtems_task_create(
114                rtems_build_name('N', 'M', 'E', 'M'),
115                RTEMS_MINIMUM_PRIORITY,
116                RTEMS_MINIMUM_STACK_SIZE,
117                RTEMS_DEFAULT_MODES,
118                RTEMS_FLOATING_POINT,
119                &id
120        );
121        assert(sc == RTEMS_SUCCESSFUL);
122
123        sc = rtems_task_start(id, no_mem_task, (rtems_task_argument) &test);
124        assert(sc == RTEMS_SUCCESSFUL);
125
126        sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
127        assert(sc == RTEMS_SUCCESSFUL);
128
129        sc = rtems_task_delete(id);
130        assert(sc == RTEMS_SUCCESSFUL);
131
132        assert(rtems_resource_snapshot_check(&snapshot));
133}
134
135static const char prog_name[] = "prog";
136
137static int
138invalid_prog(void *ctx)
139{
140        (void) ctx;
141
142        assert(0);
143}
144
145static int
146invalid_main(int argc, char **argv)
147{
148        (void) argc;
149        (void) argv;
150
151        assert(0);
152}
153
154static void *const some_context = (void *) 0xcafe;
155
156static int
157some_prog(void *ctx)
158{
159        assert(ctx == some_context);
160        assert(strcmp(rtems_bsd_program_get_name(), prog_name) == 0);
161        assert(rtems_bsd_program_get_context() == some_context);
162        errno = 0;
163        rtems_bsd_program_exit(456);
164}
165
166static const int some_argc = 1;
167
168static char *some_argv[] = { "a", NULL };
169
170static int
171some_main(int argc, char **argv)
172{
173        assert(argc == some_argc);
174        assert(argv == some_argv);
175        assert(strcmp(rtems_bsd_program_get_name(), prog_name) == 0);
176        errno = 0;
177        rtems_bsd_program_exit(789);
178}
179
180static void
181no_mem_bsd_program(int fd)
182{
183        (void) fd;
184
185        assert(rtems_bsd_program_call(prog_name, invalid_prog, NULL)
186            == EXIT_FAILURE);
187        assert(rtems_bsd_program_call_main(prog_name, invalid_main, some_argc,
188            some_argv) == EXIT_FAILURE);
189        assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
190        assert(rtems_bsd_program_get_context() == NULL);
191}
192
193#define OVERWRITE_CONTENT       "Some test pattern"
194#define OVERWRITE_AFTER_RESTORE "xxxxxtestxxxxxxxx"
195#define OVERWRITE_RESTORE_FIRST (5)
196#define OVERWRITE_RESTORE_SIZE (4)
197static const char overwrite_compare[] = OVERWRITE_AFTER_RESTORE;
198static char overwrite_me[] = OVERWRITE_CONTENT;
199
200static int
201overwrite_main(int argc, char **argv)
202{
203        size_t len = strlen(overwrite_me);
204        memset(overwrite_me, 'x', len);
205        assert(strcmp(overwrite_me, overwrite_compare) != 0);
206        errno = 0;
207        rtems_bsd_program_exit(1012);
208}
209
210static void
211test_bsd_program(void)
212{
213        rtems_resource_snapshot snapshot;
214        int exit_code;
215        void *greedy;
216        char *invalid_argv[2] = { "a", "b" };
217        struct thread *td;
218
219        assert(rtems_configuration_get_unified_work_area());
220
221        puts("test BSD program");
222
223        /* Needs to be called once before the snapshot is taken so that the
224         * thread structure is already created. */
225        td = rtems_bsd_get_curthread_or_null();
226        assert(td != NULL);
227
228        rtems_resource_snapshot_take(&snapshot);
229
230        do_no_mem_test(no_mem_bsd_program, -1);
231
232        greedy = rtems_workspace_greedy_allocate(NULL, 0);
233        no_mem_bsd_program(-1);
234        rtems_workspace_greedy_free(greedy);
235
236        assert(rtems_resource_snapshot_check(&snapshot));
237
238        errno = 0;
239        exit_code = rtems_bsd_program_call_main(prog_name, NULL, 1, invalid_argv);
240        assert(errno == EFAULT);
241        assert(exit_code == EXIT_FAILURE);
242
243        assert(rtems_resource_snapshot_check(&snapshot));
244
245        errno = EINVAL;
246        exit_code = rtems_bsd_program_call(prog_name, some_prog, some_context);
247        assert(errno == 0);
248        assert(exit_code == 456);
249        assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
250        assert(rtems_bsd_program_get_context() == NULL);
251
252        assert(rtems_resource_snapshot_check(&snapshot));
253
254        errno = EINVAL;
255        exit_code = rtems_bsd_program_call_main(prog_name, some_main,
256            some_argc, some_argv);
257        assert(errno == 0);
258        assert(exit_code == 789);
259        assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
260        assert(rtems_bsd_program_get_context() == NULL);
261
262        assert(rtems_resource_snapshot_check(&snapshot));
263
264        exit_code = rtems_bsd_program_call_main_with_data_restore(prog_name,
265            overwrite_main, some_argc, some_argv,
266            overwrite_me + OVERWRITE_RESTORE_FIRST, OVERWRITE_RESTORE_SIZE);
267        assert(errno == 0);
268        assert(exit_code == 1012);
269        assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
270        assert(rtems_bsd_program_get_context() == NULL);
271        assert(strcmp(overwrite_me, overwrite_compare) == 0);
272
273        assert(rtems_resource_snapshot_check(&snapshot));
274}
275
276static void
277test_warn(void)
278{
279        puts("test warn");
280
281        errno = EAGAIN;
282        warn("%s", "warn");
283
284        errno = ENAMETOOLONG;
285        warn(NULL);
286
287        errno = 0;
288        warnc(EDOM, "%s", "warnc");
289
290        errno = 0;
291        warnc(ERANGE, NULL);
292
293        warnx("%s", "warnx");
294
295        warnx(NULL);
296}
297
298static int
299call_err(void *ctx)
300{
301        errno = EAGAIN;
302        err(10, "%s", "call_err");
303}
304
305static int
306call_err_null(void *ctx)
307{
308        errno = ENAMETOOLONG;
309        err(11, NULL);
310}
311
312static int
313call_errc(void *ctx)
314{
315        errc(12, EDOM, "%s", "call_errc");
316}
317
318static int
319call_errc_null(void *ctx)
320{
321        errc(13, ERANGE, NULL);
322}
323
324static int
325call_errx(void *ctx)
326{
327        errx(14, "%s", "call_errx");
328}
329
330static int
331call_errx_null(void *ctx)
332{
333        errx(15, NULL);
334}
335
336static void
337test_err(void)
338{
339        int exit_code;
340
341        puts("test err");
342
343        exit_code = rtems_bsd_program_call("err", call_err, NULL);
344        assert(exit_code == 10);
345
346        exit_code = rtems_bsd_program_call("err", call_err_null, NULL);
347        assert(exit_code == 11);
348
349        exit_code = rtems_bsd_program_call("errc", call_errc, NULL);
350        assert(exit_code == 12);
351
352        exit_code = rtems_bsd_program_call("errc", call_errc_null, NULL);
353        assert(exit_code == 13);
354
355        exit_code = rtems_bsd_program_call("errx", call_errx, NULL);
356        assert(exit_code == 14);
357
358        exit_code = rtems_bsd_program_call("errx", call_errx_null, NULL);
359        assert(exit_code == 15);
360}
361
362static int
363call_socket(void *ctx)
364{
365        int fd = socket(PF_INET, SOCK_DGRAM, 0);
366        assert (fd != -1);
367        return 0;
368}
369
370static int
371call_socket_close(void *ctx)
372{
373        int rv;
374        int fd = socket(PF_INET, SOCK_DGRAM, 0);
375        assert (fd != -1);
376
377        rv = close(fd);
378        assert(rv == 0);
379
380        return 0;
381}
382
383static int
384call_open(void *ctx)
385{
386        int fd = open("/testfile", O_RDWR | O_CREAT, S_IRWXU);
387        assert (fd != -1);
388        return 0;
389}
390
391static int
392call_open_close(void *ctx)
393{
394        int rv;
395        int fd = open("/testfile", O_RDWR);
396        assert (fd != -1);
397
398        rv = close(fd);
399        assert(rv == 0);
400
401        return 0;
402}
403
404static int
405call_fopen(void *ctx)
406{
407        FILE *file = fopen("/testfile", "rw");
408        assert (file != NULL);
409        return 0;
410}
411
412static int
413call_fopen_fclose(void *ctx)
414{
415        int rv;
416
417        FILE *file = fopen("/testfile", "rw");
418        assert (file != NULL);
419
420        rv = fclose(file);
421        assert(rv == 0);
422
423        return 0;
424}
425
426static void
427test_open_close(void)
428{
429        int exit_code;
430        rtems_resource_snapshot snapshot;
431
432        puts("test open, socket and close");
433
434        /* Call a first time to create all resources before taking a memory
435         * snapshot. */
436        exit_code = rtems_bsd_program_call("socket", call_socket, NULL);
437        assert(exit_code == 0);
438        exit_code = rtems_bsd_program_call("open", call_open, NULL);
439        assert(exit_code == 0);
440        exit_code = rtems_bsd_program_call("fopen", call_fopen, NULL);
441        assert(exit_code == 0);
442
443        rtems_resource_snapshot_take(&snapshot);
444
445        exit_code = rtems_bsd_program_call("open", call_open, NULL);
446        assert(exit_code == 0);
447        assert(rtems_resource_snapshot_check(&snapshot));
448
449        exit_code = rtems_bsd_program_call("open_close", call_open_close, NULL);
450        assert(exit_code == 0);
451        assert(rtems_resource_snapshot_check(&snapshot));
452
453        rtems_resource_snapshot_take(&snapshot);
454
455        exit_code = rtems_bsd_program_call("socket", call_socket, NULL);
456        assert(exit_code == 0);
457        assert(rtems_resource_snapshot_check(&snapshot));
458
459        exit_code = rtems_bsd_program_call("socket_close", call_socket_close,
460            NULL);
461        assert(exit_code == 0);
462        assert(rtems_resource_snapshot_check(&snapshot));
463
464        exit_code = rtems_bsd_program_call("fopen", call_fopen, NULL);
465        assert(exit_code == 0);
466        assert(rtems_resource_snapshot_check(&snapshot));
467
468        exit_code = rtems_bsd_program_call("fopen_fclose", call_fopen_fclose,
469            NULL);
470        assert(exit_code == 0);
471        assert(rtems_resource_snapshot_check(&snapshot));
472}
473
474static int
475call_alloc(void *ctx)
476{
477        struct alloc_ctx *context = ctx;
478        char *first, *second, *third;
479        const int random_size = 64;
480        const char teststring[] = "test";
481
482        switch(context->type) {
483        case ALLOC_MALLOC:
484                first = malloc(random_size * sizeof(int));
485                second = malloc(random_size * sizeof(int));
486                third = malloc(random_size * sizeof(int));
487                break;
488        case ALLOC_CALLOC:
489                first = calloc(random_size, sizeof(int));
490                second = calloc(random_size, sizeof(int));
491                third = calloc(random_size, sizeof(int));
492                break;
493        case ALLOC_REALLOC:
494                first = malloc(sizeof(int));
495                second = malloc(sizeof(int));
496                third = malloc(sizeof(int));
497                assert(first != NULL);
498                assert(second != NULL);
499                assert(third != NULL);
500                first = realloc(first, sizeof(int) * random_size);
501                second = realloc(second, sizeof(int) * random_size);
502                third = realloc(third, sizeof(int) * random_size);
503                break;
504        case ALLOC_STRDUP:
505                first = strdup(teststring);
506                second = strdup(teststring);
507                third = strdup(teststring);
508                break;
509        case ALLOC_ASPRINTF:
510                asprintf(&first, "a number %d", 0x123456);
511                asprintf(&second, "some string: %s", "abcdefghijklm");
512                asprintf(&third, "just something");
513                break;
514        default:
515                assert(false);
516                break;
517        }
518
519        assert(first != NULL);
520        assert(second != NULL);
521        assert(third != NULL);
522
523        if((context->free & ALLOC_FREE_FIRST) != 0) {
524                free(first);
525        }
526        if((context->free & ALLOC_FREE_SECOND) != 0) {
527                free(second);
528        }
529        if((context->free & ALLOC_FREE_THIRD) != 0) {
530                free(third);
531        }
532
533        return 0;
534}
535
536static int
537call_free_on_null(void *ctx)
538{
539        void *new = NULL;
540        free(new);
541        return 0;
542}
543
544static void
545test_alloc_free(void)
546{
547        int exit_code;
548        rtems_resource_snapshot snapshot;
549        struct alloc_ctx context;
550        enum alloc_type type;
551
552        puts("test alloc and free");
553
554        rtems_resource_snapshot_take(&snapshot);
555
556        for(type = ALLOC_MALLOC; type < ALLOC_LAST; ++type) {
557                unsigned free;
558
559                for(free = ALLOC_FREE_NONE; free < ALLOC_FREE_ALL; ++free) {
560                        context.type = type;
561                        context.free = free;
562
563                        exit_code = rtems_bsd_program_call("alloc", call_alloc,
564                            &context);
565                        assert(exit_code == 0);
566                        assert(rtems_resource_snapshot_check(&snapshot));
567                }
568        }
569
570        exit_code = rtems_bsd_program_call("free_on_null", call_free_on_null,
571            NULL);
572        assert(exit_code == 0);
573        assert(rtems_resource_snapshot_check(&snapshot));
574}
575
576static void
577test_main(void)
578{
579        test_bsd_program();
580        test_warn();
581        test_err();
582        test_open_close();
583        test_alloc_free();
584
585        exit(0);
586}
587
588#include <rtems/bsd/test/default-init.h>
Note: See TracBrowser for help on using the repository browser.