diff options
Diffstat (limited to 'portable/src/UNIX')
-rw-r--r-- | portable/src/UNIX/PANSIFileSystemUNIXImpl.c | 166 | ||||
-rw-r--r-- | portable/src/UNIX/PFileSystemUNIXImpl.c | 142 | ||||
-rw-r--r-- | portable/src/UNIX/PFileWrapUNIX_OS_Specific.c | 116 |
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 ); + } |