| /*---------------------------------------------------------------------------* |
| * 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; |
| } |