/*---------------------------------------------------------------------------*
* PFileSystemUNIXImpl.c *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#include "PANSIFileImpl.h"
#include "PANSIFileSystemImpl.h"
#include "PFileSystem.h"
#include "PFileSystemImpl.h"
#include "PANSIFileSystem.h"
#include "phashtable.h"
#include "plog.h"
#include "pmemory.h"
#ifdef USE_THREAD
/* Prototype of private function */
PORTABLE_API ESR_ReturnCode PtrdFlush();
#endif
/**
* Initializes STDIN, STDOUT, STDERR.
*/
ESR_ReturnCode PFileSystemInitializeStreamsImpl(void)
{
ESR_ReturnCode rc;
PANSIFileImpl* impl;
#ifdef USE_THREAD
ESR_BOOL threadingEnabled;
#endif
ESR_BOOL isLittleEndian;
PANSIFileSystemImpl* ANSIImpl = NULL;
#if __BYTE_ORDER==__LITTLE_ENDIAN
isLittleEndian = ESR_TRUE;
#else
isLittleEndian = ESR_FALSE;
#endif
CHKLOG(rc, PANSIFileSystemCreate());
ANSIImpl = (PANSIFileSystemImpl*) PANSIFileSystemSingleton;
CHKLOG(rc, PMemSetLogEnabled(ESR_FALSE));
CHKLOG(rc, PHashTablePutValue(PFileSystemPathMap, L("/"), PANSIFileSystemSingleton, NULL));
CHKLOG(rc, PHashTablePutValue(ANSIImpl->directoryMap, L("/"), L("/"), NULL));
CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stdin"), isLittleEndian, &PSTDIN));
impl = (PANSIFileImpl*) PSTDIN;
impl->value = stdin;
CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stdout"), isLittleEndian, &PSTDOUT));
impl = (PANSIFileImpl*) PSTDOUT;
setvbuf(stdout, NULL, _IONBF, 0);
impl->value = stdout;
CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stderr"), isLittleEndian, &PSTDERR));
impl = (PANSIFileImpl*) PSTDERR;
setvbuf(stderr, NULL, _IONBF, 0);
impl->value = stderr;
#ifdef USE_THREAD
/* Have STDERR and STDOUT share the same lock */
CHKLOG(rc, PtrdIsEnabled(&threadingEnabled));
if (threadingEnabled)
{
CHKLOG(rc, PtrdMonitorDestroy(impl->Interface.lock));
impl->Interface.lock = ((PANSIFileImpl*) PSTDOUT)->Interface.lock;
}
#endif
CHKLOG(rc, PHashTableRemoveValue(PFileSystemPathMap, L("/"), NULL));
CHKLOG(rc, PHashTableRemoveValue(ANSIImpl->directoryMap, L("/"), NULL));
CHKLOG(rc, PMemSetLogEnabled(ESR_TRUE));
return ESR_SUCCESS;
CLEANUP:
PHashTableRemoveValue(PFileSystemPathMap, L("/"), NULL);
if (ANSIImpl!=NULL)
PHashTableRemoveValue(ANSIImpl->directoryMap, L("/"), NULL);
PMemSetLogEnabled(ESR_TRUE);
return rc;
}
ESR_ReturnCode PFileSystemShutdownStreamsImpl(void)
{
ESR_ReturnCode rc;
PANSIFileImpl* impl;
/* It is illegal to log to file after the file system has shutdown so we do it now */
#ifdef USE_THREAD
PtrdFlush();
#endif
PMemDumpLogFile();
if (PSTDIN!=NULL)
{
CHKLOG(rc, PFileFlush(PSTDIN));
impl = (PANSIFileImpl*) PSTDIN;
impl->value = NULL;
CHKLOG(rc, PFileDestroy(PSTDIN));
PSTDIN = NULL;
}
if (PSTDOUT!=NULL)
{
#ifdef USE_THREAD
if (PSTDERR!=NULL)
{
/* stdout, stderr share the same lock, only one of them should destroy it */
PFileImpl* impl = (PFileImpl*) PSTDOUT;
impl->lock = NULL;
}
#endif
CHKLOG(rc, PFileFlush(PSTDOUT));
impl = (PANSIFileImpl*) PSTDOUT;
impl->value = NULL;
CHKLOG(rc, PFileDestroy(PSTDOUT));
PSTDOUT = NULL;
}
if (PSTDERR!=NULL)
{
CHKLOG(rc, PFileFlush(PSTDERR));
impl = (PANSIFileImpl*) PSTDERR;
impl->value = NULL;
CHKLOG(rc, PFileDestroy(PSTDERR));
PSTDERR = NULL;
}
CHKLOG(rc, PANSIFileSystemDestroy());
return ESR_SUCCESS;
CLEANUP:
return rc;
}