summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libc')
-rw-r--r--c/src/lib/libc/Makefile.in4
-rw-r--r--c/src/lib/libc/__getpid.c14
-rw-r--r--c/src/lib/libc/newlibc.c430
-rw-r--r--c/src/lib/libc/no_posix.c101
4 files changed, 262 insertions, 287 deletions
diff --git a/c/src/lib/libc/Makefile.in b/c/src/lib/libc/Makefile.in
index e91e2dd478..8b88d51c8e 100644
--- a/c/src/lib/libc/Makefile.in
+++ b/c/src/lib/libc/Makefile.in
@@ -46,8 +46,8 @@ MALLOC_C_PIECES = malloc __brk __sbrk
PASSWORD_GROUP_C_PIECES = getpwent getgrent
-LIBC_GLUE_C_PIECES = __gettod __times truncate access stat lstat pathconf \
- newlibc no_libc
+LIBC_GLUE_C_PIECES = __getpid __gettod __times truncate access stat \
+ lstat pathconf newlibc no_posix no_libc
UNIX_LIBC_C_PIECES = unixlibc hosterr
diff --git a/c/src/lib/libc/__getpid.c b/c/src/lib/libc/__getpid.c
new file mode 100644
index 0000000000..32353b717d
--- /dev/null
+++ b/c/src/lib/libc/__getpid.c
@@ -0,0 +1,14 @@
+/*
+ * Some C Libraries reference this routine since they think getpid is
+ * a real system call.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+
+pid_t __getpid(void)
+{
+ return getpid();
+}
+
diff --git a/c/src/lib/libc/newlibc.c b/c/src/lib/libc/newlibc.c
index 3a3812e1ae..cfa9100e96 100644
--- a/c/src/lib/libc/newlibc.c
+++ b/c/src/lib/libc/newlibc.c
@@ -40,24 +40,17 @@
#include <stdio.h>
#endif
+static int extension_index;
+
/*
* Private routines
*/
-void MY_task_set_note(
- rtems_tcb *tcb,
- rtems_unsigned32 notepad,
- rtems_unsigned32 note
-);
-
-rtems_unsigned32 MY_task_get_note(
- rtems_tcb *tcb,
- rtems_unsigned32 notepad
-);
-
-
-#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST
+#define set_newlib_extension( _the_thread, _value ) \
+ (_the_thread)->extensions[ extension_index ] = (_value);
+#define get_newlib_extension( _the_thread ) \
+ (_the_thread)->extensions[ extension_index ]
int libc_reentrant; /* do we think we are reentrant? */
struct _reent libc_global_reent;
@@ -73,90 +66,93 @@ extern void _reclaim_reent(struct _reent *);
#include <stdio.h>
-void
-libc_wrapup(void)
+void libc_wrapup(void)
{
- /*
- * In case RTEMS is already down, don't do this. It could be
- * dangerous.
- */
-
- if (!_System_state_Is_up(_System_state_Get()))
- return;
-
- /*
- * This was already done if the user called exit() directly .
-
- _wrapup_reent(0);
- */
- if (_REENT != &libc_global_reent)
- {
- _wrapup_reent(&libc_global_reent);
+ /*
+ * In case RTEMS is already down, don't do this. It could be
+ * dangerous.
+ */
+
+ if (!_System_state_Is_up(_System_state_Get()))
+ return;
+
+ /*
+ * This was already done if the user called exit() directly .
+ _wrapup_reent(0);
+ */
+
+ if (_REENT != &libc_global_reent) {
+ _wrapup_reent(&libc_global_reent);
#if 0
- /* don't reclaim this one, just in case we do printfs */
- /* on our way out to ROM */
- _reclaim_reent(&libc_global_reent);
+ /* Don't reclaim this one, just in case we do printfs
+ * on the way out to ROM.
+ */
+ _reclaim_reent(&libc_global_reent);
#endif
- _REENT = &libc_global_reent;
- }
-
- /*
- * Try to drain output buffers.
- *
- * Should this be changed to do *all* file streams?
- * _fwalk (_REENT, fclose);
- */
- fclose (stdin);
- fclose (stdout);
- fclose (stderr);
+ _REENT = &libc_global_reent;
+ }
+
+ /*
+ * Try to drain output buffers.
+ *
+ * Should this be changed to do *all* file streams?
+ * _fwalk (_REENT, fclose);
+ */
+
+ fclose (stdin);
+ fclose (stdout);
+ fclose (stderr);
}
-rtems_boolean
-libc_create_hook(rtems_tcb *current_task,
- rtems_tcb *creating_task)
+rtems_boolean libc_create_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *creating_task
+)
{
- MY_task_set_note(creating_task, LIBC_NOTEPAD, 0);
- return TRUE;
+ set_newlib_extension( creating_task, NULL );
+ return TRUE;
}
/*
* Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
*/
-rtems_extension
-libc_start_hook(rtems_tcb *current_task,
- rtems_tcb *starting_task)
+rtems_extension libc_start_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *starting_task
+)
{
- struct _reent *ptr;
+ struct _reent *ptr;
- /* NOTE: our malloc is reentrant without a reent ptr since
- * it is based on region manager
- */
+ /* NOTE: The RTEMS malloc is reentrant without a reent ptr since
+ * it is based on the Classic API Region Manager.
+ */
- ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
+ ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
- if (!ptr)
- rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
+ if (!ptr)
+ rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
#ifdef __GNUC__
- /* GCC extension: structure constants */
- *ptr = (struct _reent) _REENT_INIT((*ptr));
+ /* GCC extension: structure constants */
+ *ptr = (struct _reent) _REENT_INIT((*ptr));
#else
- /*
- * Warning: THIS IS VERY DEPENDENT ON NEWLIB!!! WRITTEN FOR 1.7.0
- */
- ptr->_errno=0;
- ptr->_stdin=&ptr->__sf[0];
- ptr->_stdout=&ptr->__sf[1];
- ptr->_stderr=&ptr->__sf[2];
- ptr->_scanpoint=0;
- ptr->_asctime[0]=0;
- ptr->_next=1;
- ptr->__sdidinit=0;
+ /*
+ * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!!
+ * Last visual check was against newlib 1.8.2 but last known
+ * use was against 1.7.0. This is basically an exansion of
+ * REENT_INIT() in <sys/reent.h>.
+ * NOTE: calloc() takes care of zeroing fields.
+ */
+ ptr->_stdin = &ptr->__sf[0];
+ ptr->_stdout = &ptr->__sf[1];
+ ptr->_stderr = &ptr->__sf[2];
+ ptr->_current_locale = "C";
+ ptr->_new._reent._rand_next = 1;
#endif
- MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr);
+ set_newlib_extension( starting_task, ptr );
}
/*
@@ -164,38 +160,26 @@ libc_start_hook(rtems_tcb *current_task,
*/
#ifdef NEED_SETVBUF
-rtems_extension
-libc_begin_hook(rtems_tcb *current_task)
+rtems_extension libc_begin_hook(rtems_tcb *current_task)
{
setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
}
#endif
-rtems_extension
-libc_switch_hook(rtems_tcb *current_task,
- rtems_tcb *heir_task)
+rtems_extension libc_switch_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *heir_task
+)
{
- rtems_unsigned32 impure_value;
-
- /* XXX We can't use rtems_task_set_note() here since SYSI task has a
- * tid of 0, which is treated specially (optimized, actually)
- * by rtems_task_set_note
- *
- * NOTE: The above comment is no longer true and we need to use
- * the extension data areas added about the same time.
- */
-
- /*
- * Don't touch the outgoing task if it has been deleted.
- */
-
- if ( !_States_Is_transient( current_task->current_state ) ) {
- impure_value = (rtems_unsigned32) _REENT;
- MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value);
- }
+ /*
+ * Don't touch the outgoing task if it has been deleted.
+ */
- _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD);
+ if ( !_States_Is_transient( current_task->current_state ) ) {
+ set_newlib_extension( current_task, _REENT );
+ }
+ _REENT = (struct _reent *) get_newlib_extension( heir_task );
}
/*
@@ -222,43 +206,40 @@ libc_switch_hook(rtems_tcb *current_task,
*
*
*/
-rtems_extension
-libc_delete_hook(rtems_tcb *current_task,
- rtems_tcb *deleted_task)
+
+rtems_extension libc_delete_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *deleted_task
+)
{
- struct _reent *ptr;
-
- /*
- * The reentrancy structure was allocated by newlib using malloc()
- */
-
- if (current_task == deleted_task)
- {
- ptr = _REENT;
- }
- else
- {
- ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD);
- }
-
- /* if (ptr) */
- if (ptr && ptr != &libc_global_reent)
- {
- _wrapup_reent(ptr);
- _reclaim_reent(ptr);
- free(ptr);
- }
-
- MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0);
-
- /*
- * Require the switch back to another task to install its own
- */
-
- if (current_task == deleted_task)
- {
- _REENT = 0;
- }
+ struct _reent *ptr;
+
+ /*
+ * The reentrancy structure was allocated by newlib using malloc()
+ */
+
+ if (current_task == deleted_task) {
+ ptr = _REENT;
+ } else {
+ ptr = (struct _reent *) get_newlib_extension( deleted_task );
+ }
+
+ /* if (ptr) */
+ if (ptr && ptr != &libc_global_reent) {
+ _wrapup_reent(ptr);
+ _reclaim_reent(ptr);
+ free(ptr);
+ }
+
+ set_newlib_extension( deleted_task, NULL );
+
+ /*
+ * Require the switch back to another task to install its own
+ */
+
+ if ( current_task == deleted_task ) {
+ _REENT = 0;
+ }
}
/*
@@ -294,44 +275,33 @@ libc_delete_hook(rtems_tcb *current_task,
void
libc_init(int reentrant)
{
- rtems_extensions_table libc_extension;
- rtems_id extension_id;
- rtems_status_code rc;
+ rtems_extensions_table libc_extension;
+ rtems_status_code rc;
+ rtems_id extension_id;
- libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent));
- _REENT = &libc_global_reent;
+ libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent));
+ _REENT = &libc_global_reent;
- if (reentrant)
- {
- memset(&libc_extension, 0, sizeof(libc_extension));
+ if (reentrant) {
+ memset(&libc_extension, 0, sizeof(libc_extension));
- libc_extension.thread_create = libc_create_hook;
- libc_extension.thread_start = libc_start_hook;
+ libc_extension.thread_create = libc_create_hook;
+ libc_extension.thread_start = libc_start_hook;
#ifdef NEED_SETVBUF
- libc_extension.thread_begin = libc_begin_hook;
+ libc_extension.thread_begin = libc_begin_hook;
#endif
- libc_extension.thread_switch = libc_switch_hook;
- libc_extension.thread_delete = libc_delete_hook;
-
- rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
- &libc_extension, &extension_id);
- if (rc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred( rc );
-
- libc_reentrant = reentrant;
- }
-}
+ libc_extension.thread_switch = libc_switch_hook;
+ libc_extension.thread_delete = libc_delete_hook;
-#if 0
-/*
- * Routines required by the gnat runtime.
- */
+ rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
+ &libc_extension, &extension_id);
+ if (rc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred( rc );
-int get_errno()
-{
- return errno;
+ libc_reentrant = reentrant;
+ extension_index = rtems_get_index( extension_id );
+ }
}
-#endif
/*
* Function: _exit
@@ -366,134 +336,24 @@ int get_errno()
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
void _exit(int status)
{
- /*
- * We need to do the exit processing on the global reentrancy structure.
- * This has already been done on the per task reentrancy structure
- * associated with this task.
- */
-
- libc_wrapup();
- rtems_shutdown_executive(status);
+ /*
+ * We need to do the exit processing on the global reentrancy structure.
+ * This has already been done on the per task reentrancy structure
+ * associated with this task.
+ */
+
+ libc_wrapup();
+ rtems_shutdown_executive(status);
}
#else
void exit(int status)
{
- libc_wrapup();
- rtems_shutdown_executive(status);
-}
-#endif
-
-
-/*
- * These are directly supported (and completely correct) in the posix api.
- */
-
-pid_t __getpid(void)
-{
- return getpid();
-}
-
-#if !defined(RTEMS_POSIX_API)
-pid_t getpid(void)
-{
- return 0;
-}
-
-pid_t _getpid_r(
- struct _reent *ptr
-)
-{
- return getpid();
+ libc_wrapup();
+ rtems_shutdown_executive(status);
}
#endif
-#if !defined(RTEMS_POSIX_API)
-int kill( pid_t pid, int sig )
-{
- return 0;
-}
-int _kill_r( pid_t pid, int sig )
-{
- return 0;
-}
-#endif
-
-int __kill( pid_t pid, int sig )
-{
- return 0;
-}
-
-#if !defined(RTEMS_POSIX_API)
-unsigned int sleep(
- unsigned int seconds
-)
-{
- rtems_status_code status;
- rtems_interval ticks_per_second;
- rtems_interval ticks;
-
- status = rtems_clock_get(
- RTEMS_CLOCK_GET_TICKS_PER_SECOND,
- &ticks_per_second
- );
-
- ticks = seconds * ticks_per_second;
-
- status = rtems_task_wake_after( ticks );
-
- /*
- * Returns the "unslept" amount of time. In RTEMS signals are not
- * interruptable, so tasks really sleep all of the requested time.
- */
-
- return 0;
-}
-#endif
-
-
-/*
- * Newlib Interface Support
- *
- * Routines to Access Internal RTEMS Resources without violating
- * kernel visibility.
- *
- */
-
-void MY_task_set_note(
- Thread_Control *the_thread,
- unsigned32 notepad,
- unsigned32 note
-)
-{
- RTEMS_API_Control *api;
-
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
-
- if ( api )
- api->Notepads[ notepad ] = note;
-}
-
-
-unsigned32 MY_task_get_note(
- Thread_Control *the_thread,
- unsigned32 notepad
-)
-{
- RTEMS_API_Control *api;
-
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
-
- return api->Notepads[ notepad ];
-}
-
-void *MY_CPU_Context_FP_start(
- void *base,
- unsigned32 offset
-)
-{
- return _CPU_Context_Fp_start( base, offset );
-}
#endif
diff --git a/c/src/lib/libc/no_posix.c b/c/src/lib/libc/no_posix.c
new file mode 100644
index 0000000000..9973230e44
--- /dev/null
+++ b/c/src/lib/libc/no_posix.c
@@ -0,0 +1,101 @@
+/*
+ * Marginal implementations of some POSIX API routines
+ * to be used when POSIX is disabled.
+ *
+ * + getpid
+ * + _getpid_r
+ * + kill
+ * + _kill_r
+ * + __kill
+ * + sleep
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#include <unistd.h>
+
+/*
+ * These are directly supported (and completely correct) in the posix api.
+ */
+
+#if !defined(RTEMS_POSIX_API)
+pid_t getpid(void)
+{
+ return 0;
+}
+
+#if defined(RTEMS_NEWLIB)
+#include <sys/reent.h>
+
+pid_t _getpid_r(
+ struct _reent *ptr
+)
+{
+ return getpid();
+}
+#endif
+
+#endif
+
+#if !defined(RTEMS_POSIX_API)
+int kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+int _kill_r( pid_t pid, int sig )
+{
+ return 0;
+}
+#endif
+
+int __kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+
+/*
+ * 3.4.3 Delay Process Execution, P1003.1b-1993, p. 81
+ *
+ * $Id$
+ */
+
+#include <time.h>
+#include <unistd.h>
+
+#include <rtems.h>
+
+#if !defined(RTEMS_POSIX_API)
+unsigned int sleep(
+ unsigned int seconds
+)
+{
+ rtems_status_code status;
+ rtems_interval ticks_per_second;
+ rtems_interval ticks;
+
+ status = rtems_clock_get(
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ &ticks_per_second
+ );
+
+ ticks = seconds * ticks_per_second;
+
+ status = rtems_task_wake_after( ticks );
+
+ /*
+ * Returns the "unslept" amount of time. In RTEMS signals are not
+ * interruptable, so tasks really sleep all of the requested time.
+ */
+
+ return 0;
+}
+#endif
+