1 /*---------------------------------------------------------------------------* 2 * PFileSystemUNIXImpl.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #include "PANSIFileImpl.h" 21 #include "PANSIFileSystemImpl.h" 22 #include "PFileSystem.h" 23 #include "PFileSystemImpl.h" 24 #include "PANSIFileSystem.h" 25 #include "phashtable.h" 26 #include "plog.h" 27 #include "pmemory.h" 28 29 30 #ifdef USE_THREAD 31 /* Prototype of private function */ 32 PORTABLE_API ESR_ReturnCode PtrdFlush(); 33 #endif 34 35 36 /** 37 * Initializes STDIN, STDOUT, STDERR. 38 */ 39 ESR_ReturnCode PFileSystemInitializeStreamsImpl(void) 40 { 41 ESR_ReturnCode rc; 42 PANSIFileImpl* impl; 43 #ifdef USE_THREAD 44 ESR_BOOL threadingEnabled; 45 #endif 46 ESR_BOOL isLittleEndian; 47 PANSIFileSystemImpl* ANSIImpl = NULL; 48 49 #if __BYTE_ORDER==__LITTLE_ENDIAN 50 isLittleEndian = ESR_TRUE; 51 #else 52 isLittleEndian = ESR_FALSE; 53 #endif 54 CHKLOG(rc, PANSIFileSystemCreate()); 55 ANSIImpl = (PANSIFileSystemImpl*) PANSIFileSystemSingleton; 56 CHKLOG(rc, PMemSetLogEnabled(ESR_FALSE)); 57 CHKLOG(rc, PHashTablePutValue(PFileSystemPathMap, L("/"), PANSIFileSystemSingleton, NULL)); 58 CHKLOG(rc, PHashTablePutValue(ANSIImpl->directoryMap, L("/"), L("/"), NULL)); 59 CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stdin"), isLittleEndian, &PSTDIN)); 60 impl = (PANSIFileImpl*) PSTDIN; 61 impl->value = stdin; 62 63 CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stdout"), isLittleEndian, &PSTDOUT)); 64 impl = (PANSIFileImpl*) PSTDOUT; 65 setvbuf(stdout, NULL, _IONBF, 0); 66 impl->value = stdout; 67 68 CHKLOG(rc, PANSIFileSystemSingleton->createPFile(PANSIFileSystemSingleton, L("/dev/stderr"), isLittleEndian, &PSTDERR)); 69 impl = (PANSIFileImpl*) PSTDERR; 70 setvbuf(stderr, NULL, _IONBF, 0); 71 impl->value = stderr; 72 73 #ifdef USE_THREAD 74 /* Have STDERR and STDOUT share the same lock */ 75 CHKLOG(rc, PtrdIsEnabled(&threadingEnabled)); 76 if (threadingEnabled) 77 { 78 CHKLOG(rc, PtrdMonitorDestroy(impl->Interface.lock)); 79 impl->Interface.lock = ((PANSIFileImpl*) PSTDOUT)->Interface.lock; 80 } 81 #endif 82 CHKLOG(rc, PHashTableRemoveValue(PFileSystemPathMap, L("/"), NULL)); 83 CHKLOG(rc, PHashTableRemoveValue(ANSIImpl->directoryMap, L("/"), NULL)); 84 CHKLOG(rc, PMemSetLogEnabled(ESR_TRUE)); 85 return ESR_SUCCESS; 86 CLEANUP: 87 PHashTableRemoveValue(PFileSystemPathMap, L("/"), NULL); 88 if (ANSIImpl!=NULL) 89 PHashTableRemoveValue(ANSIImpl->directoryMap, L("/"), NULL); 90 PMemSetLogEnabled(ESR_TRUE); 91 return rc; 92 } 93 94 ESR_ReturnCode PFileSystemShutdownStreamsImpl(void) 95 { 96 ESR_ReturnCode rc; 97 PANSIFileImpl* impl; 98 99 /* It is illegal to log to file after the file system has shutdown so we do it now */ 100 #ifdef USE_THREAD 101 PtrdFlush(); 102 #endif 103 PMemDumpLogFile(); 104 105 if (PSTDIN!=NULL) 106 { 107 CHKLOG(rc, PFileFlush(PSTDIN)); 108 impl = (PANSIFileImpl*) PSTDIN; 109 impl->value = NULL; 110 CHKLOG(rc, PFileDestroy(PSTDIN)); 111 PSTDIN = NULL; 112 } 113 if (PSTDOUT!=NULL) 114 { 115 #ifdef USE_THREAD 116 if (PSTDERR!=NULL) 117 { 118 /* stdout, stderr share the same lock, only one of them should destroy it */ 119 PFileImpl* impl = (PFileImpl*) PSTDOUT; 120 121 impl->lock = NULL; 122 } 123 #endif 124 CHKLOG(rc, PFileFlush(PSTDOUT)); 125 impl = (PANSIFileImpl*) PSTDOUT; 126 impl->value = NULL; 127 CHKLOG(rc, PFileDestroy(PSTDOUT)); 128 PSTDOUT = NULL; 129 } 130 if (PSTDERR!=NULL) 131 { 132 CHKLOG(rc, PFileFlush(PSTDERR)); 133 impl = (PANSIFileImpl*) PSTDERR; 134 impl->value = NULL; 135 CHKLOG(rc, PFileDestroy(PSTDERR)); 136 PSTDERR = NULL; 137 } 138 CHKLOG(rc, PANSIFileSystemDestroy()); 139 return ESR_SUCCESS; 140 CLEANUP: 141 return rc; 142 } 143