Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2000-12-12 04:24:09 +0300
committerJeff Johnston <jjohnstn@redhat.com>2000-12-12 04:24:09 +0300
commit8fb3796385eb2416d05567a5996cc60f251d0021 (patch)
treebbb95a383e2485dcc0fdf9948770e2edfad0aee1 /newlib/libc/include
parent947411367d78a0fcbecb21f47711bce31c5a0d08 (diff)
2000-12-11 Joel Sherrill <joel@OARcorp.com>
* Merge RTEMS specific .h files into main libc/include. * libc/sys/rtems/include/signal.h: Removed. * libc/sys/rtems/include/time.h: Removed. * libc/sys/rtems/sys/features.h: Removed. * libc/sys/rtems/sys/sched.h: Removed. * libc/sys/rtems/sys/siginfo.h: Removed. * libc/sys/rtems/sys/signal.h: Removed. * libc/sys/rtems/sys/time.h: Removed. * libc/sys/rtems/sys/times.h: Removed. definitions for time_t and clock_t since these are no longer in time.h. * libc/include/pthread.h: New file. * libc/include/sys/sched.h: New file. * libc/include/sys/features.h: New file. * libc/include/time.h: Removed duplicate definition of clock_t and time_t, get them from <sys/types.h> instead. Add prototypes for POSIX clock and timer functionality. * libc/sys/linux/sys/types.h: Changed to include * libc/include/machine/types.h: Add _CLOCKID_T_ and _TIMER_T_. * libc/include/sys/signal.h: Add more complete set of POSIX signal functionality including real-time and threaded signals. * libc/include/sys/types.h: Add clock_t, time_t, struct timespec, and struct itimerspec. Centralizing these makes things cleaner. RTEMS uses 64-bit dev_t. Added numerous primitive definitions for pthreads including macros, pthread_attr_t, pthread_mutexattr_t, pthread_condattr_t, pthread_key_t, pthread_once_t, and pthread_t. * libc/include/sys/unistd.h: Added getlogin_r() prototype. If RTEMS follow POSIX on read(), write() and sbrk() prototype. Feature flags removed and moved to new file <sys/features.h>. Full set of POSIX sysconf() constants
Diffstat (limited to 'newlib/libc/include')
-rw-r--r--newlib/libc/include/machine/types.h3
-rw-r--r--newlib/libc/include/pthread.h298
-rw-r--r--newlib/libc/include/sys/features.h89
-rw-r--r--newlib/libc/include/sys/sched.h65
-rw-r--r--newlib/libc/include/sys/signal.h157
-rw-r--r--newlib/libc/include/sys/types.h138
-rw-r--r--newlib/libc/include/sys/unistd.h130
-rw-r--r--newlib/libc/include/time.h113
8 files changed, 931 insertions, 62 deletions
diff --git a/newlib/libc/include/machine/types.h b/newlib/libc/include/machine/types.h
index b71a67f56..ad8cc28c3 100644
--- a/newlib/libc/include/machine/types.h
+++ b/newlib/libc/include/machine/types.h
@@ -3,6 +3,9 @@
#define _CLOCK_T_ unsigned long /* clock() */
#define _TIME_T_ long /* time() */
+#define _CLOCKID_T_ unsigned long
+#define _TIMER_T_ unsigned long
+
#endif /* _MACHTYPES_H_ */
diff --git a/newlib/libc/include/pthread.h b/newlib/libc/include/pthread.h
new file mode 100644
index 000000000..af5d32c40
--- /dev/null
+++ b/newlib/libc/include/pthread.h
@@ -0,0 +1,298 @@
+/* pthread.h
+ *
+ * Written by Joel Sherrill <joel@OARcorp.com>.
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
+ * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
+ * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * $Id$
+ */
+
+#ifndef __PTHREAD_h
+#define __PTHREAD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+
+#if defined(_POSIX_THREADS)
+
+#include <sys/types.h>
+#include <time.h>
+#include <sys/sched.h>
+
+/* Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
+
+ If an OS does not support processes, then it falls under this provision
+ and may not provide pthread_atfork():
+
+ "Either the implementation shall support the pthread_atfork() function
+ as described above or the pthread_atfork() funciton shall not be
+ provided."
+
+ NOTE: RTEMS does not provide pthread_atfork(). */
+
+#if !defined(__rtems__)
+#warning "Add pthread_atfork() prototype"
+#endif
+
+/* Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 */
+
+int _EXFUN(pthread_mutexattr_init, (pthread_mutexattr_t *attr));
+int _EXFUN(pthread_mutexattr_destroy, (pthread_mutexattr_t *attr));
+int _EXFUN(pthread_mutexattr_getpshared,
+ (const pthread_mutexattr_t *attr, int *pshared));
+int _EXFUN(pthread_mutexattr_setpshared,
+ (pthread_mutexattr_t *attr, int pshared));
+
+/* Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 */
+
+int _EXFUN(pthread_mutex_init,
+ (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr));
+int _EXFUN(pthread_mutex_destroy, (pthread_mutex_t *mutex));
+
+/* This is used to statically initialize a pthread_mutex_t. Example:
+
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ */
+
+#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFF)
+
+/* Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
+ NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 */
+
+int _EXFUN(pthread_mutex_lock, (pthread_mutex_t *mutex));
+int _EXFUN(pthread_mutex_trylock, (pthread_mutex_t *mutex));
+int _EXFUN(pthread_mutex_unlock, (pthread_mutex_t *mutex));
+
+#if defined(_POSIX_TIMEOUTS)
+
+int _EXFUN(pthread_mutex_timedlock,
+ (pthread_mutex_t *mutex, const struct timespec *timeout));
+
+#endif /* _POSIX_TIMEOUTS */
+
+/* Condition Variable Initialization Attributes, P1003.1c/Draft 10, p. 96 */
+
+int _EXFUN(pthread_condattr_init, (pthread_condattr_t *attr));
+int _EXFUN(pthread_condattr_destroy, (pthread_condattr_t *attr));
+int _EXFUN(pthread_condattr_getpshared,
+ (const pthread_condattr_t *attr, int *pshared));
+int _EXFUN(pthread_condattr_setpshared,
+ (pthread_condattr_t *attr, int pshared));
+
+/* Initializing and Destroying a Condition Variable, P1003.1c/Draft 10, p. 87 */
+
+int _EXFUN(pthread_cond_init,
+ (pthread_cond_t *cond, const pthread_condattr_t *attr));
+int _EXFUN(pthread_cond_destroy, (pthread_cond_t *mutex));
+
+/* This is used to statically initialize a pthread_cond_t. Example:
+
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+ */
+
+#define PTHREAD_COND_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFF)
+
+/* Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101 */
+
+int _EXFUN(pthread_cond_signal, (pthread_cond_t *cond));
+int _EXFUN(pthread_cond_broadcast, (pthread_cond_t *cond));
+
+/* Waiting on a Condition, P1003.1c/Draft 10, p. 105 */
+
+int _EXFUN(pthread_cond_wait,
+ (pthread_cond_t *cond, pthread_mutex_t *mutex));
+
+int _EXFUN(pthread_cond_timedwait,
+ (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime));
+
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+
+/* Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 */
+
+int _EXFUN(pthread_attr_setscope,
+ (pthread_attr_t *attr, int contentionscope));
+int _EXFUN(pthread_attr_getscope,
+ (const pthread_attr_t *attr, int *contentionscope));
+int _EXFUN(pthread_attr_setinheritsched,
+ (pthread_attr_t *attr, int inheritsched));
+int _EXFUN(pthread_attr_getinheritsched,
+ (const pthread_attr_t *attr, int *inheritsched));
+int _EXFUN(pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy));
+int _EXFUN(pthread_attr_getschedpolicy,
+ (const pthread_attr_t *attr, int *policy));
+
+#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */
+
+int _EXFUN(pthread_attr_setschedparam,
+ (pthread_attr_t *attr, const struct sched_param *param));
+int _EXFUN(pthread_attr_getschedparam,
+ (const pthread_attr_t *attr, struct sched_param *param));
+
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+
+/* Dynamic Thread Scheduling Parameters Access, P1003.1c/Draft 10, p. 124 */
+
+int _EXFUN(pthread_getschedparam,
+ (pthread_t thread, int *policy, struct sched_param *param));
+int _EXFUN(pthread_setschedparam,
+ (pthread_t thread, int policy, struct sched_param *param));
+
+#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */
+
+#if defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT)
+
+/* Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 */
+
+int _EXFUN(pthread_mutexattr_setprotocol,
+ (pthread_mutexattr_t *attr, int protocol));
+int _EXFUN(pthread_mutexattr_getprotocol,
+ (const pthread_mutexattr_t *attr, int *protocol));
+int _EXFUN(pthread_mutexattr_setprioceiling,
+ (pthread_mutexattr_t *attr, int prioceiling));
+int _EXFUN(pthread_mutexattr_getprioceiling,
+ (const pthread_mutexattr_t *attr, int *prioceiling));
+
+#endif /* _POSIX_THREAD_PRIO_INHERIT || _POSIX_THREAD_PRIO_PROTECT */
+
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+
+/* Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131 */
+
+int _EXFUN(pthread_mutex_setprioceiling,
+ (pthread_mutex_t *mutex, int prioceiling, int *old_ceiling));
+int _EXFUN(pthread_mutex_getprioceiling,
+ (pthread_mutex_t *mutex, int *prioceiling));
+
+#endif /* _POSIX_THREAD_PRIO_PROTECT */
+
+/* Thread Creation Attributes, P1003.1c/Draft 10, p, 140 */
+
+int _EXFUN(pthread_attr_init, (pthread_attr_t *attr));
+int _EXFUN(pthread_attr_destroy, (pthread_attr_t *attr));
+int _EXFUN(pthread_attr_getstacksize,
+ (const pthread_attr_t *attr, size_t *stacksize));
+int _EXFUN(pthread_attr_setstacksize,
+ (pthread_attr_t *attr, size_t stacksize));
+int _EXFUN(pthread_attr_getstackaddr,
+ (const pthread_attr_t *attr, void **stackaddr));
+int _EXFUN(pthread_attr_setstackaddr,
+ (pthread_attr_t *attr, void *stackaddr));
+int _EXFUN(pthread_attr_getdetachstate,
+ (const pthread_attr_t *attr, int *detachstate));
+int _EXFUN(pthread_attr_setdetachstate,
+ (pthread_attr_t *attr, int detachstate));
+
+/* Thread Creation, P1003.1c/Draft 10, p. 144 */
+
+int _EXFUN(pthread_create,
+ (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)( void * ), void *arg));
+
+/* Wait for Thread Termination, P1003.1c/Draft 10, p. 147 */
+
+int _EXFUN(pthread_join, (pthread_t thread, void **value_ptr));
+
+/* Detaching a Thread, P1003.1c/Draft 10, p. 149 */
+
+int _EXFUN(pthread_detach, (pthread_t thread));
+
+/* Thread Termination, p1003.1c/Draft 10, p. 150 */
+
+void _EXFUN(pthread_exit, (void *value_ptr));
+
+/* Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX */
+
+pthread_t _EXFUN(pthread_self, (void));
+
+/* Compare Thread IDs, p1003.1c/Draft 10, p. 153 */
+
+int _EXFUN(pthread_equal, (pthread_t t1, pthread_t t2));
+
+/* Dynamic Package Initialization */
+
+/* This is used to statically initialize a pthread_once_t. Example:
+
+ pthread_once_t once = PTHREAD_ONCE_INIT;
+
+ NOTE: This is named inconsistently -- it should be INITIALIZER. */
+
+#define PTHREAD_ONCE_INIT { 1, 0 } /* is initialized and not run */
+
+int _EXFUN(pthread_once,
+ (pthread_once_t *once_control, void (*init_routine)(void)));
+
+/* Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 */
+
+int _EXFUN(pthread_key_create,
+ (pthread_key_t *key, void (*destructor)( void * )));
+
+/* Thread-Specific Data Management, P1003.1c/Draft 10, p. 165 */
+
+int _EXFUN(pthread_setspecific, (pthread_key_t key, const void *value));
+void * _EXFUN(pthread_getspecific, (pthread_key_t key));
+
+/* Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */
+
+int _EXFUN(pthread_key_delete, (pthread_key_t key));
+
+/* Execution of a Thread, P1003.1c/Draft 10, p. 181 */
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+int _EXFUN(pthread_cancel, (pthread_t thread));
+
+/* Setting Cancelability State, P1003.1c/Draft 10, p. 183 */
+
+int _EXFUN(pthread_setcancelstate, (int state, int *oldstate));
+int _EXFUN(pthread_setcanceltype, (int type, int *oldtype));
+void _EXFUN(pthread_testcancel, (void));
+
+/* Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 */
+
+void _EXFUN(pthread_cleanup_push, (void (*routine)( void * ), void *arg));
+void _EXFUN(pthread_cleanup_pop, (int execute));
+
+#if defined(_POSIX_THREAD_CPUTIME)
+
+/* Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58 */
+
+int _EXFUN(pthread_getcpuclockid,
+ (pthread_t thread_id, clockid_t *clock_id));
+
+/* CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59 */
+
+int _EXFUN(pthread_attr_setcputime,
+ (pthread_attr_t *attr, int clock_allowed));
+
+int _EXFUN(pthread_attr_getcputime,
+ (pthread_attr_t *attr, int *clock_allowed));
+
+#endif /* defined(_POSIX_THREAD_CPUTIME) */
+
+#endif /* defined(_POSIX_THREADS) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/newlib/libc/include/sys/features.h b/newlib/libc/include/sys/features.h
new file mode 100644
index 000000000..c73d439e9
--- /dev/null
+++ b/newlib/libc/include/sys/features.h
@@ -0,0 +1,89 @@
+/*
+ * Written by Joel Sherrill <joel@OARcorp.com>.
+ *
+ * COPYRIGHT (c) 1989-2000.
+ *
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
+ * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
+ * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * $Id$
+ */
+
+#ifndef _SYS_FEATURES_H
+#define _SYS_FEATURES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* RTEMS adheres to POSIX -- 1003.1b with some features from annexes. */
+
+#ifdef __rtems__
+#define _POSIX_JOB_CONTROL 1
+#define _POSIX_SAVED_IDS 1
+#define _POSIX_VERSION 199309L
+#define _POSIX_ASYNCHRONOUS_IO 1
+#define _POSIX_FSYNC 1
+#define _POSIX_MAPPED_FILES 1
+#define _POSIX_MEMLOCK 1
+#define _POSIX_MEMLOCK_RANGE 1
+#define _POSIX_MEMORY_PROTECTION 1
+#define _POSIX_MESSAGE_PASSING 1
+#define _POSIX_PRIORITIZED_IO 1
+#define _POSIX_PRIORITY_SCHEDULING 1
+#define _POSIX_REALTIME_SIGNALS 1
+#define _POSIX_SEMAPHORES 1
+#define _POSIX_SHARED_MEMORY_OBJECTS 1
+#define _POSIX_SYNCHRONIZED_IO 1
+#define _POSIX_TIMERS 1
+
+
+/* In P1003.1b but defined by drafts at least as early as P1003.1c/D10 */
+#define _POSIX_THREADS 1
+#define _POSIX_THREAD_ATTR_STACKADDR 1
+#define _POSIX_THREAD_ATTR_STACKSIZE 1
+#define _POSIX_THREAD_PRIORITY_SCHEDULING 1
+#define _POSIX_THREAD_PRIO_INHERIT 1
+#define _POSIX_THREAD_PRIO_PROTECT 1
+#define _POSIX_THREAD_PROCESS_SHARED 1
+#define _POSIX_THREAD_SAFE_FUNCTIONS 1
+
+/* P1003.4b/D8 defines the constants below this comment. */
+#define _POSIX_SPAWN 1
+#define _POSIX_TIMEOUTS 1
+#define _POSIX_CPUTIME 1
+#define _POSIX_THREAD_CPUTIME 1
+#define _POSIX_SPORADIC_SERVER 1
+#define _POSIX_THREAD_SPORADIC_SERVER 1
+#define _POSIX_DEVICE_CONTROL 1
+#define _POSIX_DEVCTL_DIRECTION 1
+#define _POSIX_INTERRUPT_CONTROL 1
+#define _POSIX_ADVISORY_INFO 1
+
+#endif
+
+#ifdef __svr4__
+# define _POSIX_JOB_CONTROL 1
+# define _POSIX_SAVED_IDS 1
+# define _POSIX_VERSION 199009L
+#endif
+
+#ifdef __CYGWIN32__
+# define _POSIX_JOB_CONTROL 1
+# define _POSIX_SAVED_IDS 0
+# define _POSIX_VERSION 199009L
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _SYS_FEATURES_H */
diff --git a/newlib/libc/include/sys/sched.h b/newlib/libc/include/sys/sched.h
new file mode 100644
index 000000000..540552199
--- /dev/null
+++ b/newlib/libc/include/sys/sched.h
@@ -0,0 +1,65 @@
+/*
+ * Written by Joel Sherrill <joel@OARcorp.com>.
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION
+ * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
+ * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * $Id$
+ */
+
+
+#ifndef __POSIX_SYS_SCHEDULING_h
+#define __POSIX_SYS_SCHEDULING_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/unistd.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+/* Scheduling Policies, P1003.1b-1993, p. 250
+ NOTE: SCHED_SPORADIC added by P1003.4b/D8, p. 34. */
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+
+#if defined(_POSIX_SPORADIC_SERVER)
+#define SCHED_SPORADIC 3
+#endif
+
+/* Scheduling Parameters, P1003.1b-1993, p. 249
+ NOTE: Fields whose name begins with "ss_" added by P1003.4b/D8, p. 33. */
+
+struct sched_param {
+ int sched_priority; /* Process execution scheduling priority */
+
+#if defined(_POSIX_SPORADIC_SERVER)
+ int ss_low_priority; /* Low scheduling priority for sporadic */
+ /* server */
+ struct timespec ss_replenish_period;
+ /* Replenishment period for sporadic server */
+ struct timespec ss_initial_budget; /* Initial budget for sporadic server */
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/newlib/libc/include/sys/signal.h b/newlib/libc/include/sys/signal.h
index 478531023..58d84de11 100644
--- a/newlib/libc/include/sys/signal.h
+++ b/newlib/libc/include/sys/signal.h
@@ -8,16 +8,113 @@ extern "C" {
#endif
#include "_ansi.h"
+#include <sys/features.h>
+
+/* #ifndef __STRICT_ANSI__*/
+
+#if defined(_POSIX_THREADS)
+#include <sys/types.h> /* for pthread data types */
+#endif
-#ifndef __STRICT_ANSI__
typedef unsigned long sigset_t;
+
+#if defined(__rtems__)
+
+#if defined(_POSIX_REALTIME_SIGNALS)
+
+/* sigev_notify values
+ NOTE: P1003.1c/D10, p. 34 adds SIGEV_THREAD. */
+
+#define SIGEV_NONE 1 /* No asynchronous notification shall be delivered */
+ /* when the event of interest occurs. */
+#define SIGEV_SIGNAL 2 /* A queued signal, with an application defined */
+ /* value, shall be delivered when the event of */
+ /* interest occurs. */
+#define SIGEV_THREAD 3 /* A notification function shall be called to */
+ /* perform notification. */
+
+/* Signal Generation and Delivery, P1003.1b-1993, p. 63
+ NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
+ sigev_notify_attributes to the sigevent structure. */
+
+union sigval {
+ int sival_int; /* Integer signal value */
+ void *sival_ptr; /* Pointer signal value */
+};
+
+struct sigevent {
+ int sigev_notify; /* Notification type */
+ int sigev_signo; /* Signal number */
+ union sigval sigev_value; /* Signal value */
+
+#if defined(_POSIX_THREADS)
+ void (*sigev_notify_function)( union sigval );
+ /* Notification function */
+ pthread_attr_t *sigev_notify_attributes; /* Notification Attributes */
+#endif
+};
+
+/* Signal Actions, P1003.1b-1993, p. 64 */
+/* si_code values, p. 66 */
+
+#define SI_USER 1 /* Sent by a user. kill(), abort(), etc */
+#define SI_QUEUE 2 /* Sent by sigqueue() */
+#define SI_TIMER 3 /* Sent by expiration of a timer_settime() timer */
+#define SI_ASYNCIO 4 /* Indicates completion of asycnhronous IO */
+#define SI_MESGQ 5 /* Indicates arrival of a message at an empty queue */
+
+typedef struct {
+ int si_signo; /* Signal number */
+ int si_code; /* Cause of the signal */
+ union sigval si_value; /* Signal value */
+} siginfo_t;
+#endif
+
+/* 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 */
+
+#define SA_NOCLDSTOP 1 /* Do not generate SIGCHLD when children stop */
+#define SA_SIGINFO 2 /* Invoke the signal catching function with */
+ /* three arguments instead of one. */
+
+/* struct sigaction notes from POSIX:
+ *
+ * (1) Routines stored in sa_handler should take a single int as
+ * there argument although the POSIX standard does not require this.
+ * (2) The fields sa_handler and sa_sigaction may overlap, and a conforming
+ * application should not use both simultaneously.
+ */
+
+struct sigaction {
+ int sa_flags; /* Special flags to affect behavior of signal */
+ sigset_t sa_mask; /* Additional set of signals to be blocked */
+ /* during execution of signal-catching */
+ /* function. */
+ union {
+ void (*_handler)(); /* SIG_DFL, SIG_IGN, or pointer to a function */
+#if defined(_POSIX_REALTIME_SIGNALS)
+ void (*_sigaction)( int, siginfo_t *, void * );
+#endif
+ } _signal_handlers;
+};
+
+#define sa_handler _signal_handlers._handler
+#if defined(_POSIX_REALTIME_SIGNALS)
+#define sa_sigaction _signal_handlers._sigaction
+#endif
+
+#else
+
struct sigaction
{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
};
-#define SA_NOCLDSTOP 1 /* only value supported now for sa_flags */
+
+#define SA_NOCLDSTOP 1 /* only value supported now for sa_flags */
+
+#endif /* defined(__rtems__) */
+
#define SIG_SETMASK 0 /* set mask with sigprocmask() */
#define SIG_BLOCK 1 /* set of signals to block */
#define SIG_UNBLOCK 2 /* set of signals to, well, unblock */
@@ -28,10 +125,14 @@ struct sigaction
#define sigaddset(what,sig) (*(what) |= (1<<(sig)))
#define sigemptyset(what) (*(what) = 0)
-int sigprocmask (int __how, const sigset_t *__a, sigset_t *__b);
+int _EXFUN(sigprocmask, (int how, const sigset_t *set, sigset_t *oset));
+
+#if defined(_POSIX_THREADS)
+int _EXFUN(pthread_sigmask, (int how, const sigset_t *set, sigset_t *oset));
+#endif
-/* protos for functions found in winsup sources */
-#if defined(__CYGWIN__)
+/* protos for functions found in winsup sources for CYGWIN */
+#if defined(__CYGWIN__) || defined(__rtems__)
#undef sigaddset
#undef sigemptyset
/* The first argument to kill should be pid_t. Right now
@@ -48,9 +149,30 @@ int _EXFUN(sigemptyset, (sigset_t *));
int _EXFUN(sigpending, (sigset_t *));
int _EXFUN(sigsuspend, (const sigset_t *));
int _EXFUN(sigpause, (int));
+
+#if defined(_POSIX_THREADS)
+int _EXFUN(pthread_kill, (pthread_t thread, int sig));
#endif
-#endif /* __STRICT_ANSI__ */
+#if defined(_POSIX_REALTIME_SIGNALS)
+
+/* 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ NOTE: P1003.1c/D10, p. 39 adds sigwait(). */
+
+int _EXFUN(sigwaitinfo, (const sigset_t *set, siginfo_t *info));
+int _EXFUN(sigtimedwait,
+ (const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
+);
+int _EXFUN(sigwait, (const sigset_t *set, int *sig));
+
+/* 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 */
+int _EXFUN(sigqueue, (pid_t pid, int signo, const union sigval value));
+
+#endif /* defined(_POSIX_REALTIME_SIGNALS) */
+
+#endif /* defined(__CYGWIN32__) || defined(__rtems__) */
+
+/* #endif __STRICT_ANSI__ */
#if defined(___AM29K__)
/* These all need to be defined for ANSI C, but I don't think they are
@@ -139,7 +261,28 @@ int _EXFUN(sigpause, (int));
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
-#if defined(__svr4__)
+#if defined(__rtems__)
+#define SIGUSR1 16 /* reserved as application defined signal 1 */
+#define SIGUSR2 17 /* reserved as application defined signal 2 */
+
+#define __SIGFIRSTNOTRT SIGHUP
+#define __SIGLASTNOTRT SIGUSR2
+
+/* RTEMS does not support job control, hence no Job Control Signals are
+ defined per P1003.1b-1993, p. 60-61.
+
+ RTEMS does not support memory protection, hence no Memory Protection
+ Signals are defined per P1003.1b-1993, p. 60-61. */
+
+/* Real-Time Signals Range, P1003.1b-1993, p. 61
+ NOTE: By P1003.1b-1993, this should be at least RTSIG_MAX
+ (which is a minimum of 8) signals.
+ */
+
+#define SIGRTMIN 18
+#define SIGRTMAX 32
+
+#elif defined(__svr4__)
/* svr4 specifics. different signals above 15, and sigaction. */
#define SIGUSR1 16
#define SIGUSR2 17
diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h
index 1f147c6a8..d37a5f9ae 100644
--- a/newlib/libc/include/sys/types.h
+++ b/newlib/libc/include/sys/types.h
@@ -60,9 +60,26 @@ typedef unsigned short ushort; /* System V compatibility */
typedef unsigned int uint; /* System V compatibility */
# endif /*!_POSIX_SOURCE */
+#ifndef __clock_t_defined
+typedef _CLOCK_T_ clock_t;
+#define __clock_t_defined
+#endif
+
#ifndef __time_t_defined
typedef _TIME_T_ time_t;
#define __time_t_defined
+
+/* Time Value Specification Structures, P1003.1b-1993, p. 261 */
+
+struct timespec {
+ time_t tv_sec; /* Seconds */
+ long tv_nsec; /* Nanoseconds */
+};
+
+struct itimerspec {
+ struct timespec it_interval; /* Timer period */
+ struct timespec it_value; /* Timer expiration */
+};
#endif
typedef long daddr_t;
@@ -102,7 +119,12 @@ typedef int32_t register_t;
* how the file was compiled (e.g. -mint16 vs -mint32, etc.).
*/
+#if defined(__rtems__)
+/* device numbers are 32-bit major and and 32-bit minor */
+typedef unsigned long long dev_t;
+#else
typedef short dev_t;
+#endif
typedef long off_t;
@@ -176,4 +198,120 @@ typedef struct _types_fd_set {
#undef __MS_types__
#undef _ST_INT32
+/* The following are actually standard POSIX 1003.1b-1993 threads, mutexes,
+ condition variables, and keys. But since RTEMS is currently the only
+ newlib user of these, the ifdef is just on RTEMS. */
+
+#if defined(__rtems__)
+
+#ifndef __clockid_t_defined
+typedef _CLOCKID_T_ clockid_t;
+#define __clockid_t_defined
+#endif
+
+#ifndef __timer_t_defined
+typedef _TIMER_T_ timer_t;
+#define __timer_t_defined
+#endif
+
+#include <sys/features.h>
+
+#if defined(_POSIX_THREADS)
+
+#include <sys/sched.h>
+
+/*
+ * 2.5 Primitive System Data Types, P1003.1c/D10, p. 19.
+ */
+
+typedef __uint32_t pthread_t; /* identify a thread */
+
+/* P1003.1c/D10, p. 118-119 */
+#define PTHREAD_SCOPE_PROCESS 0
+#define PTHREAD_SCOPE_SYSTEM 1
+
+/* P1003.1c/D10, p. 111 */
+#define PTHREAD_INHERIT_SCHED 1 /* scheduling policy and associated */
+ /* attributes are inherited from */
+ /* the calling thread. */
+#define PTHREAD_EXPLICIT_SCHED 2 /* set from provided attribute object */
+
+/* P1003.1c/D10, p. 141 */
+#define PTHREAD_CREATE_DETACHED 0
+#define PTHREAD_CREATE_JOINABLE 1
+
+typedef struct {
+ int is_initialized;
+ void *stackaddr;
+ int stacksize;
+ int contentionscope;
+ int inheritsched;
+ int schedpolicy;
+ struct sched_param schedparam;
+
+ /* P1003.4b/D8, p. 54 adds cputime_clock_allowed attribute. */
+#if defined(_POSIX_THREAD_CPUTIME)
+ int cputime_clock_allowed; /* see time.h */
+#endif
+ int detachstate;
+
+} pthread_attr_t;
+
+#if defined(_POSIX_THREAD_PROCESS_SHARED)
+/* NOTE: P1003.1c/D10, p. 81 defines following values for process_shared. */
+
+#define PTHREAD_PROCESS_PRIVATE 0 /* visible within only the creating process */
+#define PTHREAD_PROCESS_SHARED 1 /* visible too all processes with access to */
+ /* the memory where the resource is */
+ /* located */
+#endif
+
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+/* Mutexes */
+
+/* Values for blocking protocol. */
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+#endif
+
+typedef __uint32_t pthread_mutex_t; /* identify a mutex */
+
+typedef struct {
+ int is_initialized;
+#if defined(_POSIX_THREAD_PROCESS_SHARED)
+ int process_shared; /* allow mutex to be shared amongst processes */
+#endif
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+ int prio_ceiling;
+ int protocol;
+#endif
+ int recursive;
+} pthread_mutexattr_t;
+
+/* Condition Variables */
+
+typedef __uint32_t pthread_cond_t; /* identify a condition variable */
+
+typedef struct {
+ int is_initialized;
+#if defined(_POSIX_THREAD_PROCESS_SHARED)
+ int process_shared; /* allow this to be shared amongst processes */
+#endif
+} pthread_condattr_t; /* a condition attribute object */
+
+/* Keys */
+
+typedef __uint32_t pthread_key_t; /* thread-specific data keys */
+
+typedef struct {
+ int is_initialized; /* is this structure initialized? */
+ int init_executed; /* has the initialization routine been run? */
+} pthread_once_t; /* dynamic package initialization */
+
+#endif /* defined(_POSIX_THREADS) */
+
+#endif /* defined(__rtems__) */
+
#endif /* _SYS_TYPES_H */
diff --git a/newlib/libc/include/sys/unistd.h b/newlib/libc/include/sys/unistd.h
index fa103a91f..9d87365b4 100644
--- a/newlib/libc/include/sys/unistd.h
+++ b/newlib/libc/include/sys/unistd.h
@@ -8,6 +8,7 @@ extern "C" {
#include <_ansi.h>
#include <sys/types.h>
#define __need_size_t
+#define __need_ptrdiff_t
#include <stddef.h>
extern char **environ;
@@ -41,6 +42,9 @@ uid_t _EXFUN(geteuid, (void ));
gid_t _EXFUN(getgid, (void ));
int _EXFUN(getgroups, (int __gidsetsize, gid_t __grouplist[] ));
char _EXFUN(*getlogin, (void ));
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+int _EXFUN(getlogin_r, (char *name, size_t namesize) );
+#endif
char _EXFUN(*getpass, (__const char *__prompt));
size_t _EXFUN(getpagesize, (void));
pid_t _EXFUN(getpgrp, (void ));
@@ -55,9 +59,18 @@ off_t _EXFUN(lseek, (int __fildes, off_t __offset, int __whence ));
long _EXFUN(pathconf, (const char *__path, int __name ));
int _EXFUN(pause, (void ));
int _EXFUN(pipe, (int __fildes[2] ));
-int _EXFUN(read, (int __fildes, void *__buf, size_t __nbyte ));
+/* POSIX 1003.1b-1993 says read() returns ssize_t */
+#if defined(__rtems__)
+ssize_t _EXFUN(read, (int __fildes, void *__buf, size_t __nbyte ));
+#else
+int _EXFUN(read, (int __fildes, void *__buf, size_t __nbyte ));
+#endif
int _EXFUN(rmdir, (const char *__path ));
-void * _EXFUN(sbrk, (size_t __incr));
+#if defined(__rtems__)
+void * _EXFUN(sbrk, (ptrdiff_t __incr));
+#else
+void * _EXFUN(sbrk, (size_t __incr));
+#endif
#if defined(__CYGWIN__)
int _EXFUN(setegid, (gid_t __gid ));
int _EXFUN(seteuid, (uid_t __uid ));
@@ -73,7 +86,12 @@ pid_t _EXFUN(tcgetpgrp, (int __fildes ));
int _EXFUN(tcsetpgrp, (int __fildes, pid_t __pgrp_id ));
char _EXFUN(*ttyname, (int __fildes ));
int _EXFUN(unlink, (const char *__path ));
+/* POSIX 1003.1b-1993 says write() returns ssize_t */
+#if defined(__rtems__)
+ssize_t _EXFUN(write, (int __fildes, const void *__buf, size_t __nbyte ));
+#else
int _EXFUN(write, (int __fildes, const void *__buf, size_t __nbyte ));
+#endif
#ifndef _POSIX_SOURCE
pid_t _EXFUN(vfork, (void ));
@@ -114,33 +132,7 @@ int _EXFUN(symlink, (const char *__name1, const char *__name2));
# define SEEK_CUR 1
# define SEEK_END 2
-/*
- * RTEMS adheres to a later version of POSIX -- 1003.1b.
- *
- * XXX this version string should change.
- */
-
-#ifdef __rtems__
-#ifndef _POSIX_JOB_CONTROL
-# define _POSIX_JOB_CONTROL 1
-#endif
-#ifndef _POSIX_SAVED_IDS
-# define _POSIX_SAVED_IDS 1
-#endif
-# define _POSIX_VERSION 199009L
-#else
-#ifdef __svr4__
-# define _POSIX_JOB_CONTROL 1
-# define _POSIX_SAVED_IDS 1
-# define _POSIX_VERSION 199009L
-#endif
-#endif
-
-#ifdef __CYGWIN__
-# define _POSIX_JOB_CONTROL 1
-# define _POSIX_SAVED_IDS 0
-# define _POSIX_VERSION 199009L
-#endif
+#include <sys/features.h>
#define STDIN_FILENO 0 /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
@@ -148,21 +140,73 @@ int _EXFUN(symlink, (const char *__name1, const char *__name2));
long _EXFUN(sysconf, (int __name));
-# define _SC_ARG_MAX 0
-# define _SC_CHILD_MAX 1
-# define _SC_CLK_TCK 2
-# define _SC_NGROUPS_MAX 3
-# define _SC_OPEN_MAX 4
-/* no _SC_STREAM_MAX */
-# define _SC_JOB_CONTROL 5
-# define _SC_SAVED_IDS 6
-# define _SC_VERSION 7
-# define _SC_PAGESIZE 8
-# define _SC_NPROCESSORS_CONF 9
-# define _SC_NPROCESSORS_ONLN 10
-# define _SC_PHYS_PAGES 11
-# define _SC_AVPHYS_PAGES 12
+/*
+ * 4.8.1 Get Configurable System Variables, P1003.1b-1993, p. 96
+ *
+ * NOTE: Table 4-2, Configurable System Variables, p. 96
+ */
+
+#define _SC_ARG_MAX 0
+#define _SC_CHILD_MAX 1
+#define _SC_CLK_TCK 2
+#define _SC_NGROUPS_MAX 3
+#define _SC_OPEN_MAX 4
+ /* no _SC_STREAM_MAX */
+#define _SC_JOB_CONTROL 5
+#define _SC_SAVED_IDS 6
+#define _SC_VERSION 7
+#define _SC_PAGESIZE 8
+#define _SC_AIO_LISTIO_MAX 9
+#define _SC_AIO_MAX 10
+#define _SC_AIO_PRIO_DELTA_MAX 11
+#define _SC_DELAYTIMER_MAX 12
+#define _SC_MQ_OPEN_MAX 13
+#define _SC_MQ_PRIO_MAX 14
+#define _SC_RTSIG_MAX 15
+#define _SC_SEM_NSEMS_MAX 16
+#define _SC_SEM_VALUE_MAX 17
+#define _SC_SIGQUEUE_MAX 18
+#define _SC_TIMER_MAX 19
+#define _SC_TZNAME_MAX 20
+
+#define _SC_ASYNCHRONOUS_IO 21
+#define _SC_FSYNC 22
+#define _SC_MAPPED_FILES 23
+#define _SC_MEMLOCK 24
+#define _SC_MEMLOCK_RANGE 25
+#define _SC_MEMORY_PROTECTION 26
+#define _SC_MESSAGE_PASSING 27
+#define _SC_PRIORITIZED_IO 28
+#define _SC_REALTIME_SIGNALS 29
+#define _SC_SEMAPHORES 30
+#define _SC_SHARED_MEMORY_OBJECTS 31
+#define _SC_SYNCHRONIZED_IO 32
+#define _SC_TIMERS 33
+
+/*
+ * P1003.1c/D10, p. 52 adds the following.
+ */
+#define _SC_GETGR_R_SIZE_MAX 34
+#define _SC_GETPW_R_SIZE_MAX 35
+#define _SC_LOGIN_NAME_MAX 36
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS 37
+#define _SC_THREAD_KEYS_MAX 38
+#define _SC_THREAD_STACK_MIN 39
+#define _SC_THREAD_THREADS_MAX 40
+#define _SC_TTY_NAME_MAX 41
+
+#define _SC_THREADS 42
+#define _SC_THREAD_ATTR_STACKADDR 43
+#define _SC_THREAD_ATTR_STACKSIZE 44
+#define _SC_THREAD_PRIORITY_SCHEDULING 45
+#define _SC_THREAD_PRIO_INHERIT 46
+/* _SC_THREAD_PRIO_PROTECT was _SC_THREAD_PRIO_CEILING in early drafts */
+#define _SC_THREAD_PRIO_PROTECT 47
+#define _SC_THREAD_PRIO_CEILING _SC_THREAD_PRIO_PROTECT
+#define _SC_THREAD_PROCESS_SHARED 48
+#define _SC_THREAD_SAFE_FUNCTIONS 49
+
# define _PC_LINK_MAX 0
# define _PC_MAX_CANON 1
# define _PC_MAX_INPUT 2
diff --git a/newlib/libc/include/time.h b/newlib/libc/include/time.h
index d3ced3854..261a5c6e0 100644
--- a/newlib/libc/include/time.h
+++ b/newlib/libc/include/time.h
@@ -29,18 +29,7 @@ extern "C" {
#define __need_size_t
#include <stddef.h>
-/* Get _CLOCK_T_ and _TIME_T_. */
-#include <machine/types.h>
-
-#ifndef __clock_t_defined
-typedef _CLOCK_T_ clock_t;
-#define __clock_t_defined
-#endif
-
-#ifndef __time_t_defined
-typedef _TIME_T_ time_t;
-#define __time_t_defined
-#endif
+#include <sys/types.h>
struct tm
{
@@ -83,6 +72,106 @@ void _EXFUN(tzset, (void));
#endif
#endif /* __CYGWIN__ */
+#include <sys/features.h>
+
+
+#if defined(_POSIX_TIMERS)
+
+#include <signal.h>
+
+/* Clocks, P1003.1b-1993, p. 263 */
+
+int _EXFUN(clock_settime, (clockid_t clock_id, const struct timespec *tp));
+int _EXFUN(clock_gettime, (clockid_t clock_id, struct timespec *tp));
+int _EXFUN(clock_getres, (clockid_t clock_id, struct timespec *res));
+
+/* Create a Per-Process Timer, P1003.1b-1993, p. 264 */
+
+int _EXFUN(timer_create,
+ (clockid_t clock_id, struct sigevent *evp, timer_t *timerid));
+
+/* Delete a Per_process Timer, P1003.1b-1993, p. 266 */
+
+int _EXFUN(timer_delete, (timer_t timerid));
+
+/* Per-Process Timers, P1003.1b-1993, p. 267 */
+
+int _EXFUN(timer_settime,
+ (timer_t timerid, int flags, const struct itimerspec *value,
+ struct itimerspec *ovalue));
+int _EXFUN(timer_gettime, (timer_t timerid, struct itimerspec *value));
+int _EXFUN(timer_getoverrun, (timer_t timerid));
+
+/* High Resolution Sleep, P1003.1b-1993, p. 269 */
+
+int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp));
+
+#endif /* _POSIX_TIMERS */
+
+/* CPU-time Clock Attributes, P1003.4b/D8, p. 54 */
+
+/* values for the clock enable attribute */
+
+#define CLOCK_ENABLED 1 /* clock is enabled, i.e. counting execution time */
+#define CLOCK_DISABLED 0 /* clock is disabled */
+
+/* values for the pthread cputime_clock_allowed attribute */
+
+#define CLOCK_ALLOWED 1 /* If a thread is created with this value a */
+ /* CPU-time clock attached to that thread */
+ /* shall be accessible. */
+#define CLOCK_DISALLOWED 0 /* If a thread is created with this value, the */
+ /* thread shall not have a CPU-time clock */
+ /* accessible. */
+
+/* Manifest Constants, P1003.1b-1993, p. 262 */
+
+#define CLOCK_REALTIME (clockid_t)1
+
+/* Flag indicating time is "absolute" with respect to the clock
+ associated with a time. */
+
+#define TIMER_ABSTIME 4
+
+/* Manifest Constants, P1003.4b/D8, p. 55 */
+
+#if defined(_POSIX_CPUTIME)
+
+/* When used in a clock or timer function call, this is interpreted as
+ the identifier of the CPU_time clock associated with the PROCESS
+ making the function call. */
+
+#define CLOCK_PROCESS_CPUTIME (clockid_t)2
+
+#endif
+
+#if defined(_POSIX_THREAD_CPUTIME)
+
+/* When used in a clock or timer function call, this is interpreted as
+ the identifier of the CPU_time clock associated with the THREAD
+ making the function call. */
+
+#define CLOCK_THREAD_CPUTIME (clockid_t)3
+
+#endif
+
+#if defined(_POSIX_CPUTIME)
+
+/* Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55 */
+
+int _EXFUN(clock_getcpuclockid, (pid_t pid, clockid_t *clock_id));
+
+#endif /* _POSIX_CPUTIME */
+
+#if defined(_POSIX_CPUTIME) || defined(_POSIX_THREAD_CPUTIME)
+
+/* CPU-time Clock Attribute Access, P1003.4b/D8, p. 56 */
+
+int _EXFUN(clock_setenable_attr, (clockid_t clock_id, int attr));
+int _EXFUN(clock_getenable_attr, (clockid_t clock_id, int *attr));
+
+#endif /* _POSIX_CPUTIME or _POSIX_THREAD_CPUTIME */
+
#ifdef __cplusplus
}
#endif