source: rtems-libbsd/rtemsbsd/rtems/rtems-kernel-program.c @ 3d1e767

5-freebsd-12freebsd-9.3
Last change on this file since 3d1e767 was 3d1e767, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 27, 2016 at 8:25:22 AM

Directly use <sys/types.h> provided by Newlib

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_rtems
5 *
6 * @brief TODO.
7 */
8
9/*
10 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40#include <machine/rtems-bsd-kernel-space.h>
41#include <machine/rtems-bsd-thread.h>
42
43#include <rtems/bsd/sys/param.h>
44#include <sys/types.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/proc.h>
48#include <sys/malloc.h>
49#include <rtems/bsd/sys/lock.h>
50#include <sys/mutex.h>
51
52#include <setjmp.h>
53#include <stdlib.h>
54
55#undef printf
56#include <machine/rtems-bsd-program.h>
57
58struct rtems_bsd_program_control {
59        void *context;
60        int exit_code;
61        const char *name;
62        jmp_buf return_context;
63};
64
65int
66rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
67{
68        struct thread *td = rtems_bsd_get_curthread_or_null();
69        int exit_code = EXIT_FAILURE;
70
71        if (td != NULL) {
72                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
73
74                if (prog_ctrl == NULL) {
75                        prog_ctrl = malloc(sizeof(*prog_ctrl), M_TEMP, 0);
76
77                        if (prog_ctrl != NULL) {
78                                td->td_prog_ctrl = prog_ctrl;
79
80                                prog_ctrl->context = context;
81                                prog_ctrl->name = name;
82                                prog_ctrl->exit_code = exit_code;
83
84                                if (setjmp(prog_ctrl->return_context) == 0) {
85                                        exit_code = (*prog)(context);
86                                } else {
87                                        exit_code = prog_ctrl->exit_code;
88                                }
89
90                                td->td_prog_ctrl = NULL;
91                                free(prog_ctrl, M_TEMP);
92                        } else {
93                                errno = ENOMEM;
94                        }
95                } else {
96                        panic("unexpected BSD program state");
97                }
98        } else {
99                errno = ENOMEM;
100        }
101
102        return exit_code;
103}
104
105void
106rtems_bsd_program_exit(int exit_code)
107{
108        struct thread *td = rtems_bsd_get_curthread_or_null();
109
110        if (td != NULL) {
111                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
112
113                if (prog_ctrl != NULL) {
114                        prog_ctrl->exit_code = exit_code;
115                        longjmp(prog_ctrl->return_context, 1);
116                }
117        }
118
119        panic("unexpected BSD program exit");
120}
121
122void
123rtems_bsd_program_error(const char *fmt, ...)
124{
125        va_list list;
126        va_start(list, fmt);
127        vfprintf(stderr, fmt, list);
128        fprintf(stderr, "\n");
129        va_end(list);
130        rtems_bsd_program_exit(1);
131}
132
133const char *
134rtems_bsd_program_get_name(void)
135{
136        struct thread *td = rtems_bsd_get_curthread_or_null();
137        const char *name = "?";
138
139        if (td != NULL) {
140                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
141
142                if (prog_ctrl != NULL) {
143                        name = prog_ctrl->name;
144                }
145        }
146
147        return name;
148}
149
150void *
151rtems_bsd_program_get_context(void)
152{
153        struct thread *td = rtems_bsd_get_curthread_or_null();
154        void *context = NULL;
155
156        if (td != NULL) {
157                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
158
159                if (prog_ctrl != NULL) {
160                        context = prog_ctrl->context;
161                }
162        }
163
164        return context;
165}
166
167struct main_context {
168        int argc;
169        char **argv;
170        int (*main)(int, char **);
171};
172
173static int
174call_main(void *ctx)
175{
176        const struct main_context *mc = ctx;
177
178        return (*mc->main)(mc->argc, mc->argv);
179}
180
181int
182rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
183    int argc, char **argv)
184{
185        struct main_context mc = {
186                .argc = argc,
187                .argv = argv,
188                .main = main
189        };
190        int exit_code;
191
192        if (argv[argc] == NULL) {
193                exit_code = rtems_bsd_program_call(name, call_main, &mc);
194        } else {
195                errno = EFAULT;
196                exit_code = EXIT_FAILURE;
197        }
198
199        return exit_code;
200}
201
202static struct mtx program_mtx;
203
204MTX_SYSINIT(rtems_bsd_program, &program_mtx, "BSD program", MTX_DEF);
205
206void
207rtems_bsd_program_lock(void)
208{
209        mtx_lock(&program_mtx);
210}
211
212void
213rtems_bsd_program_unlock(void)
214{
215        mtx_unlock(&program_mtx);
216}
Note: See TracBrowser for help on using the repository browser.