mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 19:29:21 +08:00
Move program control to thread structure
This commit is contained in:
parent
c333babc98
commit
d01564c473
3
Makefile
3
Makefile
@ -70,6 +70,7 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-page.c
|
|||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-panic.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-panic.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_bus.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_bus.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_cfgreg.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_cfgreg.c
|
||||||
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-program.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-rwlock.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-rwlock.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-shell.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-shell.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-signal.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-signal.c
|
||||||
@ -86,10 +87,8 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-taskqueue.c
|
|||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-thread.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-thread.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-timesupport.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-timesupport.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-vm_glue.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-vm_glue.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-getprogname.c
|
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-kvm.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-kvm.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-net-setup.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-net-setup.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-shell.c
|
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-syslog-initialize.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-syslog-initialize.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-syspoll.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-syspoll.c
|
||||||
LIB_C_FILES += rtemsbsd/rtems/rtems-uthread_kevent.c
|
LIB_C_FILES += rtemsbsd/rtems/rtems-uthread_kevent.c
|
||||||
|
@ -627,6 +627,7 @@ rtems.addRTEMSSourceFiles(
|
|||||||
'rtems/rtems-bsd-panic.c',
|
'rtems/rtems-bsd-panic.c',
|
||||||
'rtems/rtems-bsd-pci_bus.c',
|
'rtems/rtems-bsd-pci_bus.c',
|
||||||
'rtems/rtems-bsd-pci_cfgreg.c',
|
'rtems/rtems-bsd-pci_cfgreg.c',
|
||||||
|
'rtems/rtems-bsd-program.c',
|
||||||
'rtems/rtems-bsd-rwlock.c',
|
'rtems/rtems-bsd-rwlock.c',
|
||||||
'rtems/rtems-bsd-shell.c',
|
'rtems/rtems-bsd-shell.c',
|
||||||
'rtems/rtems-bsd-signal.c',
|
'rtems/rtems-bsd-signal.c',
|
||||||
@ -643,10 +644,8 @@ rtems.addRTEMSSourceFiles(
|
|||||||
'rtems/rtems-bsd-thread.c',
|
'rtems/rtems-bsd-thread.c',
|
||||||
'rtems/rtems-bsd-timesupport.c',
|
'rtems/rtems-bsd-timesupport.c',
|
||||||
'rtems/rtems-bsd-vm_glue.c',
|
'rtems/rtems-bsd-vm_glue.c',
|
||||||
'rtems/rtems-getprogname.c',
|
|
||||||
'rtems/rtems-kvm.c',
|
'rtems/rtems-kvm.c',
|
||||||
'rtems/rtems-net-setup.c',
|
'rtems/rtems-net-setup.c',
|
||||||
'rtems/rtems-shell.c',
|
|
||||||
'rtems/rtems-syslog-initialize.c',
|
'rtems/rtems-syslog-initialize.c',
|
||||||
'rtems/rtems-syspoll.c',
|
'rtems/rtems-syspoll.c',
|
||||||
'rtems/rtems-uthread_kevent.c',
|
'rtems/rtems-uthread_kevent.c',
|
||||||
|
@ -47,19 +47,6 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include <rtems/bsd/sys/_types.h>
|
#include <rtems/bsd/sys/_types.h>
|
||||||
|
|
||||||
#ifdef __rtems__
|
|
||||||
#include <setjmp.h>
|
|
||||||
typedef struct rtems_shell_globals_s {
|
|
||||||
jmp_buf exit_jmp;
|
|
||||||
int exit_code;
|
|
||||||
} rtems_shell_globals_t;
|
|
||||||
extern rtems_shell_globals_t *rtems_shell_globals;
|
|
||||||
void rtems_shell_exit (int code);
|
|
||||||
|
|
||||||
#define exit rtems_shell_exit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
void err(int, const char *, ...) __dead2 __printf0like(2, 3);
|
void err(int, const char *, ...) __dead2 __printf0like(2, 3);
|
||||||
void verr(int, const char *, __va_list) __dead2 __printf0like(2, 0);
|
void verr(int, const char *, __va_list) __dead2 __printf0like(2, 0);
|
||||||
@ -74,8 +61,10 @@ void warnc(int, const char *, ...) __printf0like(2, 3);
|
|||||||
void vwarnc(int, const char *, __va_list) __printf0like(2, 0);
|
void vwarnc(int, const char *, __va_list) __printf0like(2, 0);
|
||||||
void warnx(const char *, ...) __printflike(1, 2);
|
void warnx(const char *, ...) __printflike(1, 2);
|
||||||
void vwarnx(const char *, __va_list) __printflike(1, 0);
|
void vwarnx(const char *, __va_list) __printflike(1, 0);
|
||||||
|
#ifndef __rtems__
|
||||||
void err_set_file(void *);
|
void err_set_file(void *);
|
||||||
void err_set_exit(void (*)(int));
|
void err_set_exit(void (*)(int));
|
||||||
|
#endif /* __rtems__ */
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /* !_ERR_H_ */
|
#endif /* !_ERR_H_ */
|
||||||
|
@ -46,9 +46,16 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "libc_private.h"
|
#include "libc_private.h"
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
static FILE *err_file; /* file to use for error output */
|
static FILE *err_file; /* file to use for error output */
|
||||||
static void (*err_exit)(int);
|
static void (*err_exit)(int);
|
||||||
|
#else /* __rtems__ */
|
||||||
|
#include <machine/rtems-bsd-program.h>
|
||||||
|
#define err_file stderr
|
||||||
|
#define err_set_file(x) do { } while (0)
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
/*
|
/*
|
||||||
* This is declared to take a `void *' so that the caller is not required
|
* This is declared to take a `void *' so that the caller is not required
|
||||||
* to include <stdio.h> first. However, it is really a `FILE *', and the
|
* to include <stdio.h> first. However, it is really a `FILE *', and the
|
||||||
@ -68,6 +75,7 @@ err_set_exit(void (*ef)(int))
|
|||||||
{
|
{
|
||||||
err_exit = ef;
|
err_exit = ef;
|
||||||
}
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
__weak_reference(_err, err);
|
__weak_reference(_err, err);
|
||||||
|
|
||||||
@ -109,8 +117,10 @@ verrc(int eval, int code, const char *fmt, va_list ap)
|
|||||||
fprintf(err_file, ": ");
|
fprintf(err_file, ": ");
|
||||||
}
|
}
|
||||||
fprintf(err_file, "%s\n", strerror(code));
|
fprintf(err_file, "%s\n", strerror(code));
|
||||||
|
#ifndef __rtems__
|
||||||
if (err_exit)
|
if (err_exit)
|
||||||
err_exit(eval);
|
err_exit(eval);
|
||||||
|
#endif /* __rtems__ */
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,8 +142,10 @@ verrx(int eval, const char *fmt, va_list ap)
|
|||||||
if (fmt != NULL)
|
if (fmt != NULL)
|
||||||
vfprintf(err_file, fmt, ap);
|
vfprintf(err_file, fmt, ap);
|
||||||
fprintf(err_file, "\n");
|
fprintf(err_file, "\n");
|
||||||
|
#ifndef __rtems__
|
||||||
if (err_exit)
|
if (err_exit)
|
||||||
err_exit(eval);
|
err_exit(eval);
|
||||||
|
#endif /* __rtems__ */
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,25 +114,6 @@ static struct afswtch *af_getbyname(const char *name);
|
|||||||
static struct afswtch *af_getbyfamily(int af);
|
static struct afswtch *af_getbyfamily(int af);
|
||||||
static void af_other_status(int);
|
static void af_other_status(int);
|
||||||
|
|
||||||
#ifdef __rtems__
|
|
||||||
static int main_ifconfig(int argc, char *argv[]);
|
|
||||||
static int rtems_shell_main_ifconfig(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
rtems_shell_globals_t ifconfig_globals;
|
|
||||||
rtems_shell_globals = &ifconfig_globals;
|
|
||||||
memset (rtems_shell_globals, 0, sizeof (ifconfig_globals));
|
|
||||||
descr = NULL;
|
|
||||||
descrlen = 64;
|
|
||||||
newaddr = 1;
|
|
||||||
supmedia = 0;
|
|
||||||
printkeys = 0;
|
|
||||||
ifconfig_globals.exit_code = 1;
|
|
||||||
if (setjmp (ifconfig_globals.exit_jmp) == 0)
|
|
||||||
return main_ifconfig ( argc, argv);
|
|
||||||
return ifconfig_globals.exit_code;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
static struct ifconfig_option *opts = NULL;
|
static struct ifconfig_option *opts = NULL;
|
||||||
|
|
||||||
@ -182,12 +163,23 @@ usage(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
int
|
#include <machine/rtems-bsd-program.h>
|
||||||
main_ifconfig(int argc, char *argv[])
|
|
||||||
#else
|
static int main(int argc, char *argv[]);
|
||||||
|
|
||||||
|
static int rtems_shell_main_ifconfig(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
descr = NULL;
|
||||||
|
descrlen = 64;
|
||||||
|
newaddr = 1;
|
||||||
|
supmedia = 0;
|
||||||
|
printkeys = 0;
|
||||||
|
|
||||||
|
return rtems_bsd_program_call_main("ifconfig", main, argc, argv);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int c, all, namesonly, downonly, uponly;
|
int c, all, namesonly, downonly, uponly;
|
||||||
const struct afswtch *afp = NULL;
|
const struct afswtch *afp = NULL;
|
||||||
|
@ -218,44 +218,39 @@ static void tvsub(struct timeval *, struct timeval *);
|
|||||||
static void usage(void) __dead2;
|
static void usage(void) __dead2;
|
||||||
|
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
static int main_ping(int argc, char *const *argv);
|
#include <machine/rtems-bsd-program.h>
|
||||||
|
|
||||||
|
static int main(int argc, char **argv);
|
||||||
|
|
||||||
static int rtems_shell_main_ping(int argc, char *argv[])
|
static int rtems_shell_main_ping(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
rtems_shell_globals_t ping_globals;
|
BBELL = '\a';
|
||||||
rtems_shell_globals = &ping_globals;
|
BSPACE = '\b';
|
||||||
memset (rtems_shell_globals, 0, sizeof (ping_globals));
|
DOT = '.';
|
||||||
BBELL = '\a';
|
icmp_type = ICMP_ECHO;
|
||||||
BSPACE = '\b';
|
icmp_type_rsp = ICMP_ECHOREPLY;
|
||||||
DOT = '.';
|
phdr_len = 0;
|
||||||
icmp_type = ICMP_ECHO;
|
sweepmin = 0;
|
||||||
icmp_type_rsp = ICMP_ECHOREPLY;
|
sweepincr = 1;
|
||||||
phdr_len = 0;
|
interval = 1000;
|
||||||
sweepmin = 0;
|
waittime = MAXWAIT;
|
||||||
sweepincr = 1;
|
nrcvtimeout = 0;
|
||||||
interval = 1000;
|
tmin = 999999999.0;
|
||||||
waittime = MAXWAIT;
|
tmax = 0.0;
|
||||||
nrcvtimeout = 0;
|
tsum = 0.0;
|
||||||
tmin = 999999999.0;
|
tsumsq = 0.0;
|
||||||
tmax = 0.0;
|
|
||||||
tsum = 0.0;
|
return rtems_bsd_program_call_main("ping", main, argc, argv);
|
||||||
tsumsq = 0.0;
|
|
||||||
ping_globals.exit_code = 1;
|
|
||||||
if (setjmp (ping_globals.exit_jmp) == 0)
|
|
||||||
return main_ping (argc, argv);
|
|
||||||
return ping_globals.exit_code;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
#ifdef __rtems__
|
|
||||||
main_ping(argc, argv)
|
|
||||||
#else
|
|
||||||
main(argc, argv)
|
main(argc, argv)
|
||||||
#endif
|
|
||||||
int argc;
|
int argc;
|
||||||
|
#ifndef __rtems__
|
||||||
char *const *argv;
|
char *const *argv;
|
||||||
|
#else /* __rtems__ */
|
||||||
|
char **argv;
|
||||||
|
#endif /* __rtems__ */
|
||||||
{
|
{
|
||||||
struct sockaddr_in from, sock_in;
|
struct sockaddr_in from, sock_in;
|
||||||
struct in_addr ifaddr;
|
struct in_addr ifaddr;
|
||||||
|
@ -116,24 +116,6 @@ extern char *iso_ntoa();
|
|||||||
|
|
||||||
void usage(const char *) __dead2;
|
void usage(const char *) __dead2;
|
||||||
|
|
||||||
#ifdef __rtems__
|
|
||||||
|
|
||||||
static int main_route(int argc, char **argv);
|
|
||||||
|
|
||||||
static int rtems_shell_main_route(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
rtems_shell_globals_t route_globals;
|
|
||||||
rtems_shell_globals = &route_globals;
|
|
||||||
memset (rtems_shell_globals, 0, sizeof (route_globals));
|
|
||||||
route_globals.exit_code = 1;
|
|
||||||
if (setjmp (route_globals.exit_jmp) == 0)
|
|
||||||
return main_route ( argc, argv);
|
|
||||||
return route_globals.exit_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(cp)
|
usage(cp)
|
||||||
const char *cp;
|
const char *cp;
|
||||||
@ -147,11 +129,17 @@ usage(cp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
|
#include <machine/rtems-bsd-program.h>
|
||||||
|
|
||||||
|
static int main(int argc, char **argv);
|
||||||
|
|
||||||
|
static int rtems_shell_main_route(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return rtems_bsd_program_call_main("route", main, argc, argv);
|
||||||
|
}
|
||||||
|
#endif /* __rtems__ */
|
||||||
int
|
int
|
||||||
main_route(argc, argv)
|
|
||||||
#else
|
|
||||||
main(argc, argv)
|
main(argc, argv)
|
||||||
#endif
|
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
|
@ -201,6 +201,7 @@ struct thread {
|
|||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
rtems_chain_node td_node;
|
rtems_chain_node td_node;
|
||||||
Thread_Control *td_thread;
|
Thread_Control *td_thread;
|
||||||
|
struct rtems_bsd_program_control *td_prog_ctrl;
|
||||||
char td_name [16];
|
char td_name [16];
|
||||||
#endif /* __rtems__ */
|
#endif /* __rtems__ */
|
||||||
#ifndef __rtems__
|
#ifndef __rtems__
|
||||||
|
@ -153,8 +153,10 @@ struct ucred;
|
|||||||
struct uio;
|
struct uio;
|
||||||
struct _jmp_buf;
|
struct _jmp_buf;
|
||||||
|
|
||||||
|
#ifndef __rtems__
|
||||||
int setjmp(struct _jmp_buf *);
|
int setjmp(struct _jmp_buf *);
|
||||||
void longjmp(struct _jmp_buf *, int) __dead2;
|
void longjmp(struct _jmp_buf *, int) __dead2;
|
||||||
|
#endif /* __rtems__ */
|
||||||
int dumpstatus(vm_offset_t addr, off_t count);
|
int dumpstatus(vm_offset_t addr, off_t count);
|
||||||
int nullop(void);
|
int nullop(void);
|
||||||
int eopnotsupp(void);
|
int eopnotsupp(void);
|
||||||
|
@ -361,15 +361,14 @@ int unit; /* unit number for above */
|
|||||||
int af; /* address family */
|
int af; /* address family */
|
||||||
int live; /* true if we are examining a live system */
|
int live; /* true if we are examining a live system */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __rtems__
|
#ifdef __rtems__
|
||||||
static int main_netstat(int argc, char *argv[]);
|
#include <machine/rtems-bsd-program.h>
|
||||||
|
|
||||||
|
static int main(int argc, char *argv[]);
|
||||||
|
|
||||||
static int rtems_shell_main_netstat(int argc, char *argv[])
|
static int rtems_shell_main_netstat(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
rtems_shell_globals_t netstat_globals;
|
|
||||||
rtems_shell_globals = &netstat_globals;
|
|
||||||
memset (rtems_shell_globals, 0, sizeof (netstat_globals));
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
protox[i].pr_index = N_TCBINFO;
|
protox[i].pr_index = N_TCBINFO;
|
||||||
@ -728,19 +727,11 @@ static int rtems_shell_main_netstat(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
noutputs = 0;
|
noutputs = 0;
|
||||||
|
|
||||||
netstat_globals.exit_code = 1;
|
return rtems_bsd_program_call_main("netstat", main, argc, argv);
|
||||||
if (setjmp (netstat_globals.exit_jmp) == 0)
|
|
||||||
return main_netstat (argc, argv);
|
|
||||||
return netstat_globals.exit_code;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
int
|
int
|
||||||
#ifdef __rtems__
|
|
||||||
main_netstat(int argc, char *argv[])
|
|
||||||
#else
|
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
struct protox *tp = NULL; /* for printing cblocks & stats */
|
struct protox *tp = NULL; /* for printing cblocks & stats */
|
||||||
int ch;
|
int ch;
|
||||||
|
85
rtemsbsd/include/machine/rtems-bsd-program.h
Normal file
85
rtemsbsd/include/machine/rtems-bsd-program.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup rtems_bsd_machine
|
||||||
|
*
|
||||||
|
* @brief TODO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_
|
||||||
|
#define _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context);
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
|
||||||
|
int argc, char **argv);
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_exit(int exit_code) __dead2;
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rtems_bsd_program_get_name(void);
|
||||||
|
|
||||||
|
void *
|
||||||
|
rtems_bsd_program_get_context(void) __pure2;
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_lock(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_unlock(void);
|
||||||
|
|
||||||
|
#ifndef RTEMS_BSD_PROGRAM_NO_EXIT_WRAP
|
||||||
|
#define exit(code) rtems_bsd_program_exit(code)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RTEMS_BSD_PROGRAM_NO_GETPROGNAME_WRAP
|
||||||
|
#define getprogname() rtems_bsd_program_get_name()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RTEMS_BSD_PROGRAM_NO_PRINTF_WRAP
|
||||||
|
#define printf(...) fprintf(stdout, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_ */
|
202
rtemsbsd/rtems/rtems-bsd-program.c
Normal file
202
rtemsbsd/rtems/rtems-bsd-program.c
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup rtems_bsd_rtems
|
||||||
|
*
|
||||||
|
* @brief TODO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <machine/rtems-bsd-config.h>
|
||||||
|
#include <machine/rtems-bsd-thread.h>
|
||||||
|
|
||||||
|
#include <rtems/bsd/sys/param.h>
|
||||||
|
#include <rtems/bsd/sys/types.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <rtems/bsd/sys/lock.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct rtems_bsd_program_control {
|
||||||
|
void *context;
|
||||||
|
int exit_code;
|
||||||
|
const char *name;
|
||||||
|
jmp_buf return_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
int exit_code = EXIT_FAILURE;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
|
||||||
|
|
||||||
|
if (prog_ctrl == NULL) {
|
||||||
|
prog_ctrl = malloc(sizeof(*prog_ctrl), M_TEMP, 0);
|
||||||
|
|
||||||
|
if (prog_ctrl != NULL) {
|
||||||
|
td->td_prog_ctrl = prog_ctrl;
|
||||||
|
|
||||||
|
prog_ctrl->context = context;
|
||||||
|
prog_ctrl->name = name;
|
||||||
|
prog_ctrl->exit_code = exit_code;
|
||||||
|
|
||||||
|
if (setjmp(prog_ctrl->return_context) == 0) {
|
||||||
|
exit_code = (*prog)(context);
|
||||||
|
} else {
|
||||||
|
exit_code = prog_ctrl->exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
td->td_prog_ctrl = NULL;
|
||||||
|
free(prog_ctrl, M_TEMP);
|
||||||
|
} else {
|
||||||
|
errno = ENOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic("unexpected BSD program state");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errno = ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_exit(int exit_code)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
|
||||||
|
|
||||||
|
if (prog_ctrl != NULL) {
|
||||||
|
prog_ctrl->exit_code = exit_code;
|
||||||
|
longjmp(prog_ctrl->return_context, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("unexpected BSD program exit");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
rtems_bsd_program_get_name(void)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
const char *name = "?";
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
|
||||||
|
|
||||||
|
if (prog_ctrl != NULL) {
|
||||||
|
name = prog_ctrl->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
rtems_bsd_program_get_context(void)
|
||||||
|
{
|
||||||
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
|
void *context = NULL;
|
||||||
|
|
||||||
|
if (td != NULL) {
|
||||||
|
struct rtems_bsd_program_control *prog_ctrl = td->td_prog_ctrl;
|
||||||
|
|
||||||
|
if (prog_ctrl != NULL) {
|
||||||
|
context = prog_ctrl->context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct main_context {
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
int (*main)(int, char **);
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_main(void *ctx)
|
||||||
|
{
|
||||||
|
const struct main_context *mc = ctx;
|
||||||
|
|
||||||
|
return (*mc->main)(mc->argc, mc->argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
|
||||||
|
int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct main_context mc = {
|
||||||
|
.argc = argc,
|
||||||
|
.argv = argv,
|
||||||
|
.main = main
|
||||||
|
};
|
||||||
|
int exit_code;
|
||||||
|
|
||||||
|
if (argv[argc] == NULL) {
|
||||||
|
exit_code = rtems_bsd_program_call(name, call_main, &mc);
|
||||||
|
} else {
|
||||||
|
errno = EFAULT;
|
||||||
|
exit_code = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mtx program_mtx;
|
||||||
|
|
||||||
|
MTX_SYSINIT(rtems_bsd_program, &program_mtx, "BSD program", MTX_DEF);
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_lock(void)
|
||||||
|
{
|
||||||
|
mtx_lock(&program_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rtems_bsd_program_unlock(void)
|
||||||
|
{
|
||||||
|
mtx_unlock(&program_mtx);
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS version of
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char *getprogname(void)
|
|
||||||
{
|
|
||||||
return "RTEMS";
|
|
||||||
}
|
|
@ -36,6 +36,7 @@
|
|||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -45,6 +46,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define RTEMS_BSD_PROGRAM_NO_EXIT_WRAP
|
||||||
|
#define RTEMS_BSD_PROGRAM_NO_PRINTF_WRAP
|
||||||
|
#include <machine/rtems-bsd-program.h>
|
||||||
|
|
||||||
#include <rtems/libcsupport.h>
|
#include <rtems/libcsupport.h>
|
||||||
|
|
||||||
#define TEST_NAME "LIBBSD SYSCALLS 1"
|
#define TEST_NAME "LIBBSD SYSCALLS 1"
|
||||||
@ -1201,6 +1206,193 @@ test_socket_recv_and_recvfrom_and_recvmsg(void)
|
|||||||
assert(rtems_resource_snapshot_check(&snapshot));
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char prog_name[] = "prog";
|
||||||
|
|
||||||
|
static int
|
||||||
|
invalid_prog(void *ctx)
|
||||||
|
{
|
||||||
|
(void) ctx;
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
invalid_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *const some_context = (void *) 0xcafe;
|
||||||
|
|
||||||
|
static int
|
||||||
|
some_prog(void *ctx)
|
||||||
|
{
|
||||||
|
assert(ctx == some_context);
|
||||||
|
assert(strcmp(rtems_bsd_program_get_name(), prog_name) == 0);
|
||||||
|
assert(rtems_bsd_program_get_context() == some_context);
|
||||||
|
errno = 0;
|
||||||
|
rtems_bsd_program_exit(456);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int some_argc = 1;
|
||||||
|
|
||||||
|
static char *some_argv[] = { "a", NULL };
|
||||||
|
|
||||||
|
static int
|
||||||
|
some_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
assert(argc == some_argc);
|
||||||
|
assert(argv == some_argv);
|
||||||
|
assert(strcmp(rtems_bsd_program_get_name(), prog_name) == 0);
|
||||||
|
errno = 0;
|
||||||
|
rtems_bsd_program_exit(789);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
no_mem_bsd_program(int fd)
|
||||||
|
{
|
||||||
|
(void) fd;
|
||||||
|
|
||||||
|
assert(rtems_bsd_program_call(prog_name, invalid_prog, NULL)
|
||||||
|
== EXIT_FAILURE);
|
||||||
|
assert(rtems_bsd_program_call_main(prog_name, invalid_main, some_argc,
|
||||||
|
some_argv) == EXIT_FAILURE);
|
||||||
|
assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
|
||||||
|
assert(rtems_bsd_program_get_context() == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_bsd_program(void)
|
||||||
|
{
|
||||||
|
rtems_resource_snapshot snapshot;
|
||||||
|
int exit_code;
|
||||||
|
void *greedy;
|
||||||
|
char *invalid_argv[2] = { "a", "b" };
|
||||||
|
|
||||||
|
assert(rtems_configuration_get_unified_work_area());
|
||||||
|
|
||||||
|
puts("test BSD program");
|
||||||
|
|
||||||
|
rtems_resource_snapshot_take(&snapshot);
|
||||||
|
|
||||||
|
do_no_mem_test(no_mem_bsd_program, -1);
|
||||||
|
|
||||||
|
greedy = rtems_workspace_greedy_allocate(NULL, 0);
|
||||||
|
no_mem_bsd_program(-1);
|
||||||
|
rtems_workspace_greedy_free(greedy);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
exit_code = rtems_bsd_program_call_main(prog_name, NULL, 1, invalid_argv);
|
||||||
|
assert(errno == EFAULT);
|
||||||
|
assert(exit_code == EXIT_FAILURE);
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
exit_code = rtems_bsd_program_call(prog_name, some_prog, some_context);
|
||||||
|
assert(errno == 0);
|
||||||
|
assert(exit_code == 456);
|
||||||
|
assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
|
||||||
|
assert(rtems_bsd_program_get_context() == NULL);
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
exit_code = rtems_bsd_program_call_main(prog_name, some_main,
|
||||||
|
some_argc, some_argv);
|
||||||
|
assert(errno == 0);
|
||||||
|
assert(exit_code == 789);
|
||||||
|
assert(strcmp(rtems_bsd_program_get_name(), "?") == 0);
|
||||||
|
assert(rtems_bsd_program_get_context() == NULL);
|
||||||
|
|
||||||
|
assert(rtems_resource_snapshot_check(&snapshot));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_warn(void)
|
||||||
|
{
|
||||||
|
puts("test warn");
|
||||||
|
|
||||||
|
errno = EAGAIN;
|
||||||
|
warn("%s", "warn");
|
||||||
|
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
warn(NULL);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
warnc(EDOM, "%s", "warnc");
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
warnc(ERANGE, NULL);
|
||||||
|
|
||||||
|
warnx("%s", "warnx");
|
||||||
|
|
||||||
|
warnx(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_err(void *ctx)
|
||||||
|
{
|
||||||
|
errno = EAGAIN;
|
||||||
|
err(10, "%s", "call_err");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_err_null(void *ctx)
|
||||||
|
{
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
err(11, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_errc(void *ctx)
|
||||||
|
{
|
||||||
|
errc(12, EDOM, "%s", "call_errc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_errc_null(void *ctx)
|
||||||
|
{
|
||||||
|
errc(13, ERANGE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_errx(void *ctx)
|
||||||
|
{
|
||||||
|
errx(14, "%s", "call_errx");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
call_errx_null(void *ctx)
|
||||||
|
{
|
||||||
|
errx(15, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_err(void)
|
||||||
|
{
|
||||||
|
int exit_code;
|
||||||
|
|
||||||
|
puts("test err");
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("err", call_err, NULL);
|
||||||
|
assert(exit_code == 10);
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("err", call_err_null, NULL);
|
||||||
|
assert(exit_code == 11);
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("errc", call_errc, NULL);
|
||||||
|
assert(exit_code == 12);
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("errc", call_errc_null, NULL);
|
||||||
|
assert(exit_code == 13);
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("errx", call_errx, NULL);
|
||||||
|
assert(exit_code == 14);
|
||||||
|
|
||||||
|
exit_code = rtems_bsd_program_call("errx", call_errx_null, NULL);
|
||||||
|
assert(exit_code == 15);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_main(void)
|
test_main(void)
|
||||||
{
|
{
|
||||||
@ -1221,6 +1413,10 @@ test_main(void)
|
|||||||
test_socket_send_and_sendto_and_sendmsg();
|
test_socket_send_and_sendto_and_sendmsg();
|
||||||
test_socket_recv_and_recvfrom_and_recvmsg();
|
test_socket_recv_and_recvfrom_and_recvmsg();
|
||||||
|
|
||||||
|
test_bsd_program();
|
||||||
|
test_warn();
|
||||||
|
test_err();
|
||||||
|
|
||||||
puts("*** END OF " TEST_NAME " TEST ***");
|
puts("*** END OF " TEST_NAME " TEST ***");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user