source: rtems-libbsd/rtemsbsd/rtems/rtems-kernel-program.c @ 32fd702

5-freebsd-12freebsd-9.3
Last change on this file since 32fd702 was 32fd702, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 23, 2016 at 12:06:21 PM

Update due to RTEMS printer API changes

  • 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 <stdarg.h>
54#include <stdlib.h>
55
56#undef printf
57#include <machine/rtems-bsd-program.h>
58
59struct rtems_bsd_program_control {
60        void *context;
61        int exit_code;
62        const char *name;
63        jmp_buf return_context;
64};
65
66int
67rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
68{
69        struct thread *td = rtems_bsd_get_curthread_or_null();
70        int exit_code = EXIT_FAILURE;
71
72        if (td != NULL) {
73                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
74
75                if (prog_ctrl == NULL) {
76                        prog_ctrl = malloc(sizeof(*prog_ctrl), M_TEMP, 0);
77
78                        if (prog_ctrl != NULL) {
79                                td->td_prog_ctrl = prog_ctrl;
80
81                                prog_ctrl->context = context;
82                                prog_ctrl->name = name;
83                                prog_ctrl->exit_code = exit_code;
84
85                                if (setjmp(prog_ctrl->return_context) == 0) {
86                                        exit_code = (*prog)(context);
87                                } else {
88                                        exit_code = prog_ctrl->exit_code;
89                                }
90
91                                td->td_prog_ctrl = NULL;
92                                free(prog_ctrl, M_TEMP);
93                        } else {
94                                errno = ENOMEM;
95                        }
96                } else {
97                        panic("unexpected BSD program state");
98                }
99        } else {
100                errno = ENOMEM;
101        }
102
103        return exit_code;
104}
105
106void
107rtems_bsd_program_exit(int exit_code)
108{
109        struct thread *td = rtems_bsd_get_curthread_or_null();
110
111        if (td != NULL) {
112                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
113
114                if (prog_ctrl != NULL) {
115                        prog_ctrl->exit_code = exit_code;
116                        longjmp(prog_ctrl->return_context, 1);
117                }
118        }
119
120        panic("unexpected BSD program exit");
121}
122
123void
124rtems_bsd_program_error(const char *fmt, ...)
125{
126        va_list list;
127        va_start(list, fmt);
128        vfprintf(stderr, fmt, list);
129        fprintf(stderr, "\n");
130        va_end(list);
131        rtems_bsd_program_exit(1);
132}
133
134const char *
135rtems_bsd_program_get_name(void)
136{
137        struct thread *td = rtems_bsd_get_curthread_or_null();
138        const char *name = "?";
139
140        if (td != NULL) {
141                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
142
143                if (prog_ctrl != NULL) {
144                        name = prog_ctrl->name;
145                }
146        }
147
148        return name;
149}
150
151void *
152rtems_bsd_program_get_context(void)
153{
154        struct thread *td = rtems_bsd_get_curthread_or_null();
155        void *context = NULL;
156
157        if (td != NULL) {
158                struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
159
160                if (prog_ctrl != NULL) {
161                        context = prog_ctrl->context;
162                }
163        }
164
165        return context;
166}
167
168struct main_context {
169        int argc;
170        char **argv;
171        int (*main)(int, char **);
172};
173
174static int
175call_main(void *ctx)
176{
177        const struct main_context *mc = ctx;
178
179        return (*mc->main)(mc->argc, mc->argv);
180}
181
182int
183rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
184    int argc, char **argv)
185{
186        struct main_context mc = {
187                .argc = argc,
188                .argv = argv,
189                .main = main
190        };
191        int exit_code;
192
193        if (argv[argc] == NULL) {
194                exit_code = rtems_bsd_program_call(name, call_main, &mc);
195        } else {
196                errno = EFAULT;
197                exit_code = EXIT_FAILURE;
198        }
199
200        return exit_code;
201}
202
203static struct mtx program_mtx;
204
205MTX_SYSINIT(rtems_bsd_program, &program_mtx, "BSD program", MTX_DEF);
206
207void
208rtems_bsd_program_lock(void)
209{
210        mtx_lock(&program_mtx);
211}
212
213void
214rtems_bsd_program_unlock(void)
215{
216        mtx_unlock(&program_mtx);
217}
Note: See TracBrowser for help on using the repository browser.