sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "POSIXIF.H" sl@0: sl@0: // Category for the panic. sl@0: _LIT(KEstlibInit, "ESTLIB-INIT"); sl@0: sl@0: // Access for the outside world sl@0: extern "C" { sl@0: sl@0: EXPORT_C void CloseSTDLIB() sl@0: { sl@0: struct _reent* p=(struct _reent*)Dll::Tls(); sl@0: if (p==0) sl@0: return; sl@0: _reclaim_reent(p); // Reclaiming calls the atexit processing and generally tries to tidy up sl@0: User::Free(p); // then we give back the struct _reent itself sl@0: Dll::SetTls(0); // ... so we don't free it again when the DLL exits sl@0: } sl@0: sl@0: /** sl@0: Allocates memory for the library globals struct and returns a pointer to it. If the sl@0: memory has been allocated previously then it simply returns a pointer to the memory. sl@0: Panics if any error/failure occurs. sl@0: sl@0: @return On Success, a pointer to the memory containing the library globals. sl@0: */ sl@0: EXPORT_C struct _reent *ImpurePtr(void) sl@0: { sl@0: struct _reent* p=(struct _reent*)Dll::Tls(); sl@0: if (p) sl@0: return p; // Memory is already allocated for the library globals. sl@0: sl@0: // First use, so construct the default struct _reent and the associated SystemInterface sl@0: p=(struct _reent*)User::Alloc(sizeof(struct _reent)); sl@0: if(p ==0) sl@0: { sl@0: User::Panic(KEstlibInit,KErrNoMemory); sl@0: } sl@0: sl@0: TInt err= Dll::SetTls(p); sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: delete p; sl@0: p = 0; sl@0: Dll::FreeTls(); sl@0: User::Panic(KEstlibInit, err); sl@0: } sl@0: sl@0: void* sysIf=0; sl@0: sl@0: CProcessSystemInterface* pSysIf=new CProcessSystemInterface; sl@0: if (pSysIf && pSysIf->Connect()==KErrNone) sl@0: { sl@0: sysIf=pSysIf; sl@0: } sl@0: else sl@0: { sl@0: delete pSysIf; sl@0: pSysIf = 0; sl@0: sl@0: CTrapCleanup *cleanup = NULL; sl@0: if(User::TrapHandler() == NULL) sl@0: { sl@0: cleanup = CTrapCleanup::New(); sl@0: if(cleanup != NULL) sl@0: { sl@0: //use static_cast to perform the valid conversion from CLocalSystemInterface to base class MSystemInterface sl@0: TRAP(err, sysIf = static_cast (CLocalSystemInterface::NewL())); sl@0: } sl@0: else sl@0: { sl@0: err = KErrNoMemory; sl@0: } sl@0: delete cleanup; sl@0: } sl@0: else sl@0: { sl@0: //use static_cast to perform the valid conversion from CLocalSystemInterface to base class MSystemInterface sl@0: TRAP(err, sysIf = static_cast (CLocalSystemInterface::NewL())); sl@0: } sl@0: } sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: delete p; sl@0: p = 0; sl@0: Dll::FreeTls(); sl@0: User::Panic(KEstlibInit, err); sl@0: } sl@0: sl@0: Mem::FillZ(p,sizeof(struct _reent)); sl@0: _init_reent(p,sysIf); sl@0: sl@0: return p; sl@0: } sl@0: sl@0: /** sl@0: This is a panic free version of ImpurePtr. It allocates memory for the library globals sl@0: struct and returns a pointer to it. If the memory has been allocated previously then it sl@0: simply returns a pointer to the memory. sl@0: If there is not enough memory available to set up the library globals or other error occurs, sl@0: a NULL pointer will be returned. sl@0: sl@0: @return On Success, a pointer to the memory containing the library globals. sl@0: On Failure, a NULL pointer. sl@0: */ sl@0: EXPORT_C struct _reent * ImpurePtr2(void) sl@0: { sl@0: struct _reent* p = (struct _reent*)Dll::Tls(); sl@0: if (p) sl@0: return p; // Memory is already allocated for the library globals. sl@0: sl@0: // First use, so construct the default struct _reent and the associated SystemInterface sl@0: p =(struct _reent*)User::Alloc(sizeof(struct _reent)); sl@0: if (p== 0) sl@0: return p ; // NULL sl@0: sl@0: if (Dll::SetTls(p)) sl@0: { sl@0: delete p; sl@0: p = 0; sl@0: Dll::FreeTls(); sl@0: return p; // NULL sl@0: } sl@0: sl@0: void* sysIf=0; sl@0: CProcessSystemInterface* pSysIf=new CProcessSystemInterface; sl@0: if (pSysIf && pSysIf->Connect()==KErrNone) sl@0: { sl@0: sysIf=pSysIf; sl@0: } sl@0: else sl@0: { sl@0: TInt err=KErrNone; sl@0: delete pSysIf; sl@0: pSysIf = 0; sl@0: sl@0: CTrapCleanup *cleanup = NULL; sl@0: if(User::TrapHandler() == NULL) sl@0: { sl@0: cleanup = CTrapCleanup::New(); sl@0: if(cleanup != NULL) sl@0: { sl@0: //use static_cast to perform the valid conversion from CLocalSystemInterface to base class MSystemInterface sl@0: TRAP(err, sysIf = static_cast (CLocalSystemInterface::NewL())); sl@0: } sl@0: delete cleanup; sl@0: } sl@0: else sl@0: { sl@0: //use static_cast to perform the valid conversion from CLocalSystemInterface to base class MSystemInterface sl@0: TRAP(err, sysIf = static_cast (CLocalSystemInterface::NewL())); sl@0: } sl@0: } sl@0: sl@0: if (!sysIf) sl@0: { sl@0: delete p; sl@0: p = 0; sl@0: Dll::FreeTls(); sl@0: return p; // NULL sl@0: } sl@0: sl@0: Mem::FillZ(p,sizeof(struct _reent)); sl@0: _init_reent(p,sysIf); sl@0: sl@0: return p; // Library globals have been set up correctly. sl@0: } sl@0: sl@0: sl@0: EXPORT_C int *__errno(void) sl@0: { sl@0: return &(ImpurePtr()->_errno); sl@0: } sl@0: sl@0: EXPORT_C void _exit (int status) _ATTRIBUTE((noreturn)) sl@0: { sl@0: struct _reent* p=(struct _reent*)Dll::Tls(); sl@0: if (p) sl@0: { sl@0: MSystemInterface& sysIf=Interface(p); sl@0: sysIf.TerminateProcess(status); sl@0: } sl@0: RProcess().Terminate(status); // just in case sl@0: } sl@0: sl@0: } // extern "C" sl@0: sl@0: #ifndef EKA2 sl@0: GLDEF_C TInt E32Dll(TDllReason) sl@0: // sl@0: // DLL entry point sl@0: // sl@0: { sl@0: sl@0: return KErrNone; sl@0: } sl@0: #endif sl@0: