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 */
PFileSystemInitializeStreamsImpl(void)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
PFileSystemShutdownStreamsImpl(void)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