source: rtems-libbsd/rtemsbsd/rtems/rtems-bsd-program.c @ d01564c

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since d01564c was d01564c, checked in by Sebastian Huber <sebastian.huber@…>, on 10/17/13 at 08:38:34

Move program control to thread structure

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