/* * tlib.cxx * * Miscelaneous class implementation * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: tlib.cxx,v $ * Revision 1.76 2005/11/30 12:47:42 csoutheren * Removed tabs, reformatted some code, and changed tags for Doxygen * * Revision 1.75 2005/11/08 10:35:53 csoutheren * Added missing pragma * * Revision 1.74 2005/08/04 18:54:10 csoutheren * Applied fix for bug Bugs item #1244310 * Fix problem wioth --disable-openh323 option * Thanks to Michael Manousos * * Revision 1.73 2005/02/22 03:25:43 dereksmithies * Add fix from huangzb@a-star.com.cn to correct a typo. Many thanks. * * Revision 1.72 2005/01/26 05:38:05 csoutheren * Added ability to remove config file support * * Revision 1.71 2005/01/04 08:09:43 csoutheren * Fixed Linux configure problems * * Revision 1.70 2004/07/11 07:56:36 csoutheren * Applied jumbo VxWorks patch, thanks to Eize Slange * * Revision 1.69 2003/09/18 23:52:08 dereksmithies * Fix checks on NULL pointers. Many thanks to Chris Rankin. * * Revision 1.68 2003/09/17 01:18:04 csoutheren * Removed recursive include file system and removed all references * to deprecated coooperative threading support * * Revision 1.67 2003/01/24 10:21:06 robertj * Fixed issues in RTEMS support, thanks Vladimir Nesic * * Revision 1.66 2002/12/11 23:02:39 robertj * Added ability to set user identity temporarily and permanently. * Added ability to have username exclusively digits which corresponds to a uid. * Added get and set users group functions. * * Revision 1.65 2002/12/02 03:57:18 robertj * More RTEMS support patches, thank you Vladimir Nesic. * * Revision 1.64 2002/11/22 10:14:07 robertj * QNX port, thanks Xiaodan Tang * * Revision 1.63 2002/11/02 00:32:21 robertj * Further fixes to VxWorks (Tornado) port, thanks Andreas Sikkema. * * Revision 1.62 2002/10/17 13:44:27 robertj * Port to RTEMS, thanks Vladimir Nesic. * * Revision 1.61 2002/10/10 04:43:44 robertj * VxWorks port, thanks Martijn Roest * * Revision 1.60 2002/06/27 08:09:06 robertj * GNU GCC 3.1 compatibility under Solaris * * Revision 1.59 2001/11/25 23:30:31 robertj * Added PProcess::SetUserName() function to set euid * * Revision 1.58 2001/10/11 02:20:54 robertj * Added IRIX support (no audio/video), thanks Andre Schulze. * * Revision 1.57 2001/09/18 05:56:03 robertj * Fixed numerous problems with thread suspend/resume and signals handling. * * Revision 1.56 2001/08/11 15:38:43 rogerh * Add Mac OS Carbon changes from John Woods * * Revision 1.55 2001/06/30 06:59:07 yurik * Jac Goudsmit from Be submit these changes 6/28. Implemented by Yuri Kiryanov * * Revision 1.54 2001/03/29 03:24:31 robertj * Removed capture of SIGQUIT so can still dro a core on demand. * * Revision 1.53 2001/03/14 01:16:11 robertj * Fixed signals processing, now uses housekeeping thread to handle signals * synchronously. This also fixes issues with stopping PServiceProcess. * * Revision 1.52 2001/03/07 07:31:25 yurik * refined BeOS constants * * Revision 1.51 2000/06/21 01:01:22 robertj * AIX port, thanks Wolfgang Platzer (wolfgang.platzer@infonova.at). * * Revision 1.50 2000/04/09 18:19:23 rogerh * Add my changes for NetBSD support. * * Revision 1.49 2000/04/06 12:19:49 rogerh * Add Mac OS X support submitted by Kevin Packard * * Revision 1.48 2000/03/08 12:17:09 rogerh * Add OpenBSD support * * Revision 1.47 1999/09/03 02:26:25 robertj * Changes to aid in breaking I/O locks on thread termination. Still needs more work esp in BSD! * * Revision 1.46 1999/07/19 01:32:24 craigs * Changed signals used in pthreads code, is used by linux version. * * Revision 1.45 1999/07/11 13:42:13 craigs * pthreads support for Linux * * Revision 1.44 1999/06/28 09:28:02 robertj * Portability issues, especially n BeOS (thanks Yuri!) * * Revision 1.43 1999/05/13 04:44:18 robertj * Added SIGHUP and SIGWINCH handlers to increase and decrease the log levels. * * Revision 1.42 1999/03/02 05:41:59 robertj * More BeOS changes * * Revision 1.41 1999/02/26 04:10:39 robertj * More BeOS port changes * * Revision 1.40 1999/02/19 11:34:15 robertj * Added platform dependent function for "system configuration" directory. * * Revision 1.39 1999/02/06 05:49:44 robertj * BeOS port effort by Yuri Kiryanov * * Revision 1.38 1999/01/11 12:10:39 robertj * Improved operating system version display. * * Revision 1.37 1999/01/08 01:31:01 robertj * Support for pthreads under FreeBSD * * Revision 1.36 1998/11/24 11:24:40 robertj * Added FreeBSD OSName * * Revision 1.35 1998/11/24 09:39:16 robertj * FreeBSD port. * * Revision 1.34 1998/10/31 14:14:21 robertj * Changed syncptack.h to syncthrd.h for more thread synchronisation objects. * * Revision 1.33 1998/10/19 00:29:57 robertj * Moved error stream to common. * * Revision 1.32 1998/09/24 04:12:22 robertj * Added open software license. * * Revision 1.31 1998/05/30 14:58:56 robertj * Fixed shutdown deadlock (and other failure modes) in cooperative threads. * * Revision 1.30 1998/04/17 15:13:08 craigs * Added lazy writes to Config cache * * Revision 1.29 1998/03/29 10:42:16 craigs * Changed for new initialisation scheme * * Revision 1.28 1998/03/26 05:01:12 robertj * Added PMutex and PSyncPoint classes. * * Revision 1.27 1998/01/04 08:09:23 craigs * Added support for PThreads through use of reentrant system calls * * Revision 1.26 1998/01/03 22:46:44 craigs * Added PThread support * * Revision 1.25 1997/05/10 08:04:15 craigs * Added new routines for access to PErrorStream * * Revision 1.24 1997/04/22 10:57:53 craigs * Removed DLL functions and added call the FreeStack * * Revision 1.23 1997/02/23 03:06:00 craigs * Changed for PProcess::Current reference * * Revision 1.22 1997/02/14 09:18:36 craigs * Changed for PProcess::Current being a reference rather that a ptr * * Revision 1.21 1996/12/30 03:21:46 robertj * Added timer to block on wait for child process. * * Revision 1.20 1996/12/29 13:25:02 robertj * Fixed GCC warnings. * * Revision 1.19 1996/11/16 11:11:46 craigs * Fixed problem with timeout on blocked IO channels * * Revision 1.18 1996/11/03 04:35:58 craigs * Added hack to avoid log timeouts, which shouldn't happen! * * Revision 1.17 1996/09/21 05:40:10 craigs * Changed signal hcnalding * * Revision 1.16 1996/09/03 11:55:19 craigs * Removed some potential problems with return values from system calls * * Revision 1.15 1996/06/29 01:43:11 craigs * Moved AllocateStack to switch.cxx to keep platform dependent routines in one place * * Revision 1.14 1996/06/10 12:46:53 craigs * Changed process.h include * * Revision 1.13 1996/05/25 06:06:33 craigs * Sun4 fixes and updated for gcc 2.7.2 * * Revision 1.12 1996/05/09 10:55:59 craigs * More SunOS fixes * * Revision 1.11 1996/05/03 13:15:27 craigs * More Sun4 & Solaris fixes * * Revision 1.10 1996/05/03 13:11:35 craigs * More Sun4 fixes * * Revision 1.9 1996/05/02 12:11:54 craigs * Sun4 fixes * * Revision 1.8 1996/04/18 11:43:38 craigs * Changed GetHomeDir to use effective UID for uid, and changed to * look at passwd file info *before* $HOME variable * * Revision 1.7 1996/04/15 10:49:11 craigs * Last build prior to release of MibMaster v1.0 * * Revision 1.6 1996/01/26 11:09:42 craigs * Added signal handlers * */ #define _OSUTIL_CXX //#define SIGNALS_DEBUG #pragma implementation "args.h" #pragma implementation "pprocess.h" #pragma implementation "thread.h" #pragma implementation "semaphor.h" #pragma implementation "mutex.h" #pragma implementation "psync.h" #pragma implementation "syncpoint.h" #pragma implementation "syncthrd.h" #include "ptlib.h" #ifdef P_VXWORKS #include #include #include #include #include #include #else #include #include #include #endif // P_VXWORKS #include #include #include #if defined(P_LINUX) #include #include #include #endif #if defined(P_LINUX) || defined(P_SUN4) || defined(P_SOLARIS) || defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS) || defined (P_AIX) || defined(__BEOS__) || defined(P_IRIX) || defined(P_QNX) #include #define HAS_UNAME #elif defined(P_RTEMS) extern "C" { #include } #define HAS_UNAME #endif #include "uerror.h" #if defined(P_HPUX9) #define SELECT(p1,p2,p3,p4,p5) select(p1,(int *)(p2),(int *)(p3),(int *)(p4),p5) #else #define SELECT(p1,p2,p3,p4,p5) select(p1,p2,p3,p4,p5) #endif #if defined(P_SUN4) extern "C" void bzero(void *, int); extern "C" int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); #endif #ifdef __BEOS__ #include "OS.h" #endif #include "../common/pglobalstatic.cxx" PString PProcess::GetOSClass() { #ifndef __BEOS__ return PString("Unix"); #elif defined P_VXWORKS return PString("VxWorks"); #else return PString("Be Inc."); #endif } PString PProcess::GetOSName() { #if defined(HAS_UNAME) struct utsname info; uname(&info); #ifdef P_SOLARIS return PString(info.sysname) & info.release; #else return PString(info.sysname); #endif #elif defined(P_VXWORKS) return PString::Empty(); #else #warning No GetOSName specified return PString("Unknown"); #endif } PString PProcess::GetOSHardware() { #if defined(HAS_UNAME) struct utsname info; uname(&info); return PString(info.machine); #elif defined(P_VXWORKS) return PString(sysModel()); #else #warning No GetOSHardware specified return PString("unknown"); #endif } PString PProcess::GetOSVersion() { #if defined(HAS_UNAME) struct utsname info; uname(&info); #ifdef P_SOLARIS return PString(info.version); #else return PString(info.release); #endif #elif defined(P_VXWORKS) return PString(sysBspRev()); #else #warning No GetOSVersion specified return PString("?.?"); #endif } PDirectory PProcess::GetOSConfigDir() { #ifdef P_VXWORKS return "./"; #else return "/etc"; #endif // P_VXWORKS } PDirectory PProcess::PXGetHomeDir () { #ifdef P_VXWORKS return "./"; #else PString dest; char *ptr; struct passwd *pw = NULL; #if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) struct passwd pwd; char buffer[1024]; #if defined (P_LINUX) || defined(P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) ::getpwuid_r(geteuid(), &pwd, buffer, 1024, &pw); #else pw = ::getpwuid_r(geteuid(), &pwd, buffer, 1024); #endif #else pw = ::getpwuid(geteuid()); #endif if (pw != NULL && pw->pw_dir != NULL) dest = pw->pw_dir; else if ((ptr = getenv ("HOME")) != NULL) dest = ptr; else dest = "."; if (dest.GetLength() > 0 && dest[dest.GetLength()-1] != '/') dest += "/"; return dest; #endif } /////////////////////////////////////////////////////////////////////////////// // // PProcess // // Return the effective user name of the process, eg "root" etc. PString PProcess::GetUserName() const { #ifdef P_VXWORKS char pnamebuf[1024]; int len = 1024; STATUS gethostresult; gethostresult =::gethostname(pnamebuf,len); if (gethostresult == OK) return PString(pnamebuf,len); else return PString("VxWorks"); #else #if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) struct passwd pwd; char buffer[1024]; struct passwd * pw = NULL; #if defined (P_LINUX) || defined (P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) ::getpwuid_r(geteuid(), &pwd, buffer, 1024, &pw); #else pw = ::getpwuid_r(geteuid(), &pwd, buffer, 1024); #endif #else struct passwd * pw = ::getpwuid(geteuid()); #endif char * ptr; if (pw != NULL && pw->pw_name != NULL) return PString(pw->pw_name); else if ((ptr = getenv("USER")) != NULL) return PString(ptr); else return PString("user"); #endif // P_VXWORKS } BOOL PProcess::SetUserName(const PString & username, BOOL permanent) { #ifdef P_VXWORKS PAssertAlways("PProcess::SetUserName - not implemented for VxWorks"); return FALSE; #else if (username.IsEmpty()) return seteuid(getuid()) != -1; int uid = -1; if (username[0] == '#') { PString s = username.Mid(1); if (strspn(s, "1234567890") == strlen(s)) uid = s.AsInteger(); } else { #if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) struct passwd pwd; char buffer[1024]; struct passwd * pw = NULL; #if defined (P_LINUX) || defined (P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) ::getpwnam_r(username, &pwd, buffer, 1024, &pw); #else pw = ::getpwnam_r(username, &pwd, buffer, 1024); #endif #else struct passwd * pw = ::getpwnam(username); #endif if (pw != NULL && pw->pw_name != NULL) uid = pw->pw_uid; else { if (strspn(username, "1234567890") == strlen(username)) uid = username.AsInteger(); } } if (uid < 0) return FALSE; if (permanent) return setuid(uid) != -1; return seteuid(uid) != -1; #endif // P_VXWORKS } /////////////////////////////////////////////////////////////////////////////// // // PProcess // // Return the effective group name of the process, eg "wheel" etc. PString PProcess::GetGroupName() const { #ifdef P_VXWORKS return PString("VxWorks"); #else #if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) struct group grp; char buffer[1024]; struct group * gr = NULL; #if defined (P_LINUX) || defined (P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) ::getgrgid_r(getegid(), &grp, buffer, 1024, &gr); #else gr = ::getgrgid_r(getegid(), &grp, buffer, 1024); #endif #else struct group * gr = ::getgrgid(getegid()); #endif char * ptr; if (gr != NULL && gr->gr_name != NULL) return PString(gr->gr_name); else if ((ptr = getenv("GROUP")) != NULL) return PString(ptr); else return PString("group"); #endif // P_VXWORKS } BOOL PProcess::SetGroupName(const PString & groupname, BOOL permanent) { #ifdef P_VXWORKS PAssertAlways("PProcess::SetGroupName - not implemented for VxWorks"); return FALSE; #else if (groupname.IsEmpty()) return setegid(getgid()) != -1; int gid = -1; if (groupname[0] == '#') { PString s = groupname.Mid(1); if (strspn(s, "1234567890") == strlen(s)) gid = s.AsInteger(); } else { #if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) struct group grp; char buffer[1024]; struct group * gr = NULL; #if defined (P_LINUX) || defined (P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) ::getgrnam_r(groupname, &grp, buffer, 1024, &gr); #else gr = ::getgrnam_r(groupname, &grp, buffer, 1024); #endif #else struct group * gr = ::getgrnam(groupname); #endif if (gr != NULL && gr->gr_name != NULL) gid = gr->gr_gid; else { if (strspn(groupname, "1234567890") == strlen(groupname)) gid = groupname.AsInteger(); } } if (gid < 0) return FALSE; if (permanent) return setgid(gid) != -1; return setegid(gid) != -1; #endif // P_VXWORKS } void PProcess::PXShowSystemWarning(PINDEX num) { PXShowSystemWarning(num, ""); } void PProcess::PXShowSystemWarning(PINDEX num, const PString & str) { PProcess::Current()._PXShowSystemWarning(num, str); } void PProcess::_PXShowSystemWarning(PINDEX code, const PString & str) { PError << "PWLib " << GetOSClass() << " error #" << code << '-' << str << endl; } void PXSignalHandler(int sig) { #ifdef SIGNALS_DEBUG fprintf(stderr,"\nSIGNAL<%u>\n",sig); #endif PProcess & process = PProcess::Current(); process.pxSignals |= 1 << sig; process.PXOnAsyncSignal(sig); #if defined(P_MAC_MPTHREADS) process.SignalTimerChange(); #elif defined(P_PTHREADS) // Inform house keeping thread we have a signal to be processed BYTE ch; write(process.timerChangePipe[1], &ch, 1); #endif signal(sig, PXSignalHandler); } void PProcess::PXCheckSignals() { if (pxSignals == 0) return; #ifdef SIGNALS_DEBUG fprintf(stderr,"\nCHKSIG<%x>\n",pxSignals); #endif for (int sig = 0; sig < 32; sig++) { int bit = 1 << sig; if ((pxSignals&bit) != 0) { pxSignals &= ~bit; PXOnSignal(sig); } } } void SetSignals(void (*handler)(int)) { #ifdef SIGNALS_DEBUG fprintf(stderr,"\nSETSIG<%x>\n",(INT)handler); #endif if (handler == NULL) handler = SIG_DFL; #ifdef SIGHUP signal(SIGHUP, handler); #endif #ifdef SIGINT signal(SIGINT, handler); #endif #ifdef SIGUSR1 signal(SIGUSR1, handler); #endif #ifdef SIGUSR2 signal(SIGUSR2, handler); #endif #ifdef SIGPIPE signal(SIGPIPE, handler); #endif #ifdef SIGTERM signal(SIGTERM, handler); #endif #ifdef SIGWINCH signal(SIGWINCH, handler); #endif #ifdef SIGPROF signal(SIGPROF, handler); #endif } void PProcess::PXOnAsyncSignal(int sig) { #ifdef SIGNALS_DEBUG fprintf(stderr,"\nASYNCSIG<%u>\n",sig); #endif switch (sig) { case SIGINT: case SIGTERM: case SIGHUP: raise(SIGKILL); break; default: return; } } void PProcess::PXOnSignal(int sig) { #ifdef SIGNALS_DEBUG fprintf(stderr,"\nSYNCSIG<%u>\n",sig); #endif } void PProcess::CommonConstruct() { // Setup signal handlers pxSignals = 0; SetSignals(&PXSignalHandler); #if !defined(P_VXWORKS) && !defined(P_RTEMS) // initialise the timezone information tzset(); #endif #ifdef P_CONFIG_FILE CreateConfigFilesDictionary(); #endif } void PProcess::CommonDestruct() { #ifdef P_CONFIG_FILE delete configFiles; #endif configFiles = NULL; SetSignals(NULL); } // rtems fixes #ifdef P_RTEMS extern "C" { #include #include int socketpair(int d, int type, int protocol, int sv[2]) { static int port_count = IPPORT_USERRESERVED; int s; int addrlen; struct sockaddr_in addr1, addr2; static int network_status = 1; if (network_status>0) { printf("\"Network\" initializing!\n"); network_status = rtems_bsdnet_initialize_network(); if (network_status == 0) printf("\"Network\" initialized!\n"); else { printf("Error: %s\n", strerror(errno)); return -1; } } /* prepare sv */ sv[0]=sv[1]=-1; /* make socket */ s = socket( d, type, protocol); if (s<0) return -1; memset(&addr1, 0, sizeof addr1); addr1.sin_family = d; addr1.sin_port = htons(++port_count); addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(s, (struct sockaddr *)&addr1, sizeof addr1) < 0) { close(s); return -1; } if (listen(s, 2) < 0 ) { close(s); return -1; } sv[0] = socket(d, type, protocol); if (sv[0] < 0) { close(s); return -1; } memset(&addr2, 0, sizeof addr2); addr2.sin_family = d; addr2.sin_port = htons(++port_count); addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(sv[0], (struct sockaddr *)&addr2, sizeof addr2) < 0) { close(s); close(sv[0]); sv[0]=-1; return -1; } if (connect(sv[0], (struct sockaddr *)&addr1, sizeof addr1) < 0) { close(s); close(sv[0]); sv[0]=-1; return -1; } sv[1] = accept(s, (struct sockaddr *)&addr2, &addrlen); if (sv[1] < 0) { close(s); close(sv[0]); sv[0]=-1; return -1; } close(s); return 0; } /* * Loopback interface */ extern int rtems_bsdnet_loopattach(rtems_bsdnet_ifconfig *); static struct rtems_bsdnet_ifconfig loopback_config = { "lo0", /* name */ rtems_bsdnet_loopattach, /* attach function */ NULL, /* link to next interface */ "127.0.0.1", /* IP address */ "255.0.0.0", /* IP net mask */ }; #include #warning Change lines below to match Your system settings /* * Default network interface */ static struct rtems_bsdnet_ifconfig netdriver_config = { RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ &loopback_config, /* link to next interface */ "10.0.0.2", /* IP address */ "255.255.255.0", /* IP net mask */ NULL, /* Driver supplies hardware address */ 0 /* Use default driver parameters */ }; /* * Network configuration */ struct rtems_bsdnet_config rtems_bsdnet_config = { &netdriver_config, NULL, /* no bootp function */ 1, /* Default network task priority */ 0, /* Default mbuf capacity */ 0, /* Default mbuf cluster capacity */ "computer.name", /* Host name */ "domain.name", /* Domain name */ "10.0.0.1", /* Gateway */ "10.0.0.1", /* Log host */ {"10.0.0.1" }, /* Name server(s) */ {"10.0.0.1" }, /* NTP server(s) */ }; #define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER #define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER #define CONFIGURE_TEST_NEEDS_TIMER_DRIVER #define CONFIGURE_MICROSECONDS_PER_TICK 1000 #define CONFIGURE_TICKS_PER_TIMESLICE 50 #define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(50) #define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(50) #define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(50) #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(50) #define CONFIGURE_MAXIMUM_MUTEXES rtems_resource_unlimited(50) #define CONFIGURE_MAXIMUM_POSIX_THREADS 500 #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 500 #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 500 #define CONFIGURE_MAXIMUM_POSIX_KEYS 500 #define CONFIGURE_MAXIMUM_POSIX_TIMERS 500 #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 500 #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 500 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 500 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 500 #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | RTEMS_TIMESLICE) #ifdef DEBUG #define STACK_CHECKER_ON #endif void* POSIX_Init(void*); #define CONFIGURE_INIT #include } #endif // P_RTEMS ////////////////////////////////////////////////////////////////// // // Non-PTHREAD based routines // #if defined(P_MAC_MPTHREADS) #include "tlibmpthrd.cxx" #elif defined(P_PTHREADS) #include "tlibthrd.cxx" #elif defined(BE_THREADS) #include "tlibbe.cxx" #elif defined(VX_TASKS) #include "tlibvx.cxx" #endif