summaryrefslogtreecommitdiff
path: root/portable/src/UNIX
diff options
context:
space:
mode:
Diffstat (limited to 'portable/src/UNIX')
-rw-r--r--portable/src/UNIX/PANSIFileSystemUNIXImpl.c166
-rw-r--r--portable/src/UNIX/PFileSystemUNIXImpl.c142
-rw-r--r--portable/src/UNIX/PFileWrapUNIX_OS_Specific.c116
3 files changed, 424 insertions, 0 deletions
diff --git a/portable/src/UNIX/PANSIFileSystemUNIXImpl.c b/portable/src/UNIX/PANSIFileSystemUNIXImpl.c
new file mode 100644
index 0000000..2c561b1
--- /dev/null
+++ b/portable/src/UNIX/PANSIFileSystemUNIXImpl.c
@@ -0,0 +1,166 @@
+/*---------------------------------------------------------------------------*
+ * PANSIFileSystemUNIXImpl.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 <sys/types.h>
+#include <sys/stat.h>
+
+#include "errno.h"
+#include "PFileSystemImpl.h"
+#include "PANSIFileSystem.h"
+#include "PANSIFileSystemImpl.h"
+#include "phashtable.h"
+#include "LCHAR.h"
+#include "plog.h"
+
+ESR_ReturnCode PANSIFileSystemGetVirtualPathImpl(PFileSystem* self, LCHAR* path, size_t* len)
+{
+ PANSIFileSystemImpl* impl = (PANSIFileSystemImpl*) self;
+ PHashTableEntry* entry;
+ LCHAR driveLetter = 0;
+ LCHAR* key;
+ LCHAR* value;
+ LCHAR* bestKey = NULL;
+ LCHAR* bestValue = NULL;
+ ESR_BOOL isAbsolute;
+ ESR_ReturnCode rc;
+
+ CHKLOG(rc, lstrtrim(path));
+ CHKLOG(rc, PFileSystemCanonicalSlashes(path));
+ CHKLOG(rc, PFileSystemIsAbsolutePath(path, &isAbsolute));
+ if (isAbsolute && path[0] != L('/'))
+ {
+ /* Skip drive letters in absolute paths */
+ driveLetter = path[0];
+ LSTRCPY(path, path + 2);
+ }
+ CHKLOG(rc, PHashTableEntryGetFirst(impl->directoryMap, &entry));
+ while (entry!=NULL)
+ {
+ CHKLOG(rc, PHashTableEntryGetKeyValue(entry, (void **)&key, (void **)&value));
+ if (LSTRSTR(path, value)==path)
+ {
+ /* File-system handles file path */
+
+ if (bestValue==NULL || LSTRLEN(value) > LSTRLEN(bestValue))
+ {
+ /* Found a better match -- the new key is a subdirectory of the previous bestKey */
+ bestKey = key;
+ bestValue = value;
+ }
+ }
+ CHKLOG(rc, PHashTableEntryAdvance(&entry));
+ }
+ if (bestKey == NULL)
+ {
+ rc = ESR_INVALID_STATE;
+ PLogError(L("PANSIFileSystem does not handle the specified path: %s"), path);
+ goto CLEANUP;
+ }
+
+ /* Delete the real-path */
+ LSTRCPY(path, path + LSTRLEN(bestValue));
+ /* Insert the virtual-path */
+ CHKLOG(rc, lstrinsert(bestKey, path, 0, len));
+
+ /* Bring back the drive letter */
+ if (driveLetter!=0)
+ {
+ CHKLOG(rc, lstrinsert(L("X:/"), path, LSTRLEN(bestKey), len));
+ path[LSTRLEN(bestKey)] = driveLetter;
+ }
+ return ESR_SUCCESS;
+ CLEANUP:
+ return rc;
+}
+ESR_ReturnCode PANSIFileSystemMkdirImpl(PFileSystem* self, const LCHAR* path)
+{
+ LCHAR realPath[P_PATH_MAX];
+ size_t len;
+ ESR_ReturnCode rc;
+
+ passert(path!=NULL);
+ LSTRCPY(realPath, path);
+ len = P_PATH_MAX;
+ CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len));
+
+ if (mkdir(realPath, S_IRWXU|S_IRWXG|S_IRWXO ) != 0)
+ {
+ switch (errno)
+ {
+ case EEXIST:
+ return ESR_IDENTIFIER_COLLISION;
+ case ENOENT:
+ return ESR_NO_MATCH_ERROR;
+ default:
+ PLogError(L("ESR_INVALID_STATE"));
+ return ESR_INVALID_STATE;
+ }
+ }
+ return ESR_SUCCESS;
+CLEANUP:
+ return rc;
+}
+
+ESR_ReturnCode PANSIFileSystemGetcwdImpl(PFileSystem* self, LCHAR* path, size_t* len)
+{
+ ESR_ReturnCode rc;
+
+ if (path==NULL)
+ {
+ rc = ESR_INVALID_ARGUMENT;
+ PLogError(ESR_rc2str(rc));
+ goto CLEANUP;
+ }
+ if (getcwd(path, *len) == NULL)
+ {
+ switch (errno)
+ {
+ case ERANGE:
+ *len = P_PATH_MAX;
+ return ESR_BUFFER_OVERFLOW;
+ case ENOMEM:
+ default:
+ PLogError(L("ESR_INVALID_STATE"));
+ return ESR_INVALID_STATE;
+ }
+ }
+
+ CHKLOG(rc, PANSIFileSystemGetVirtualPathImpl(self, path, len));
+ return ESR_SUCCESS;
+CLEANUP:
+ return rc;
+}
+
+ESR_ReturnCode PANSIFileSystemChdirImpl(PFileSystem* self, const LCHAR* path)
+{
+ LCHAR realPath[P_PATH_MAX];
+ size_t len;
+ ESR_ReturnCode rc;
+
+ passert(path!=NULL);
+ LSTRCPY(realPath, path);
+ len = P_PATH_MAX;
+ CHKLOG(rc, PANSIFileSystemGetRealPathImpl(self, realPath, &len));
+
+ if ((*path != '\0') && (chdir(realPath) != 0))
+ return ESR_NO_MATCH_ERROR;
+ return ESR_SUCCESS;
+CLEANUP:
+ return rc;
+}
diff --git a/portable/src/UNIX/PFileSystemUNIXImpl.c b/portable/src/UNIX/PFileSystemUNIXImpl.c
new file mode 100644
index 0000000..06655f3
--- /dev/null
+++ b/portable/src/UNIX/PFileSystemUNIXImpl.c
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------*
+ * 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;
+}
diff --git a/portable/src/UNIX/PFileWrapUNIX_OS_Specific.c b/portable/src/UNIX/PFileWrapUNIX_OS_Specific.c
new file mode 100644
index 0000000..dfe2efe
--- /dev/null
+++ b/portable/src/UNIX/PFileWrapUNIX_OS_Specific.c
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*
+ * PFileWrapUNIX_OS_Specific.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 <sys/types.h>
+#include <sys/stat.h>
+
+#include "errno.h"
+#include "PFileSystemImpl.h"
+#include "PANSIFileSystem.h"
+#include "PANSIFileSystemImpl.h"
+#include "phashtable.h"
+#include "LCHAR.h"
+#include "plog.h"
+
+ESR_ReturnCode pf_make_dir ( const LCHAR* path )
+ {
+ ESR_ReturnCode rc;
+
+ passert(path!=NULL);
+
+ if ( mkdir ( path, S_IRWXU|S_IRWXG|S_IRWXO ) == 0)
+ {
+ rc = ESR_SUCCESS;
+ }
+ else
+ {
+ switch (errno)
+ {
+ case EEXIST:
+ rc = ESR_IDENTIFIER_COLLISION;
+ break;
+
+ case ENOENT:
+ rc = ESR_NO_MATCH_ERROR;
+ break;
+
+ default:
+ PLogError ( L("ESR_INVALID_STATE") );
+ rc = ESR_INVALID_STATE;
+ break;
+ }
+ }
+ return ( rc );
+ }
+
+
+
+ESR_ReturnCode pf_get_cwd ( LCHAR* path, size_t *len )
+ {
+ ESR_ReturnCode rc;
+
+ if ( path != NULL )
+ {
+ if ( getcwd ( path, *len ) != NULL)
+ {
+ rc = ESR_SUCCESS;
+ }
+ else
+ {
+ switch ( errno )
+ {
+ case ERANGE:
+ rc = ESR_BUFFER_OVERFLOW;
+ break;
+
+ case ENOMEM:
+ rc = ESR_OUT_OF_MEMORY;
+ break;
+
+ default:
+ PLogError(L("ESR_INVALID_STATE"));
+ rc = ESR_INVALID_STATE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ rc = ESR_INVALID_ARGUMENT;
+ PLogError(ESR_rc2str(rc));
+ }
+
+ return ( rc );
+ }
+
+
+
+ESR_ReturnCode pf_change_dir ( const LCHAR* path )
+ {
+ ESR_ReturnCode rc;
+
+ passert ( path != NULL );
+ passert ( *path != '\0' );
+
+ if ( chdir ( path ) == 0 )
+ rc = ESR_SUCCESS;
+ else
+ rc = ESR_NO_MATCH_ERROR;
+ return ( rc );
+ }