diff options
author | Anantha Kesari H Y <hyanantha@php.net> | 2002-10-25 11:52:34 +0000 |
---|---|---|
committer | Anantha Kesari H Y <hyanantha@php.net> | 2002-10-25 11:52:34 +0000 |
commit | 96c2056eaaf12d385f89bd1195d3898e80b3fed6 (patch) | |
tree | 9775f894db471cd5acbde8377c034ea6bfc2a356 | |
parent | 2410f761244edafd9dc4571794cafa928935c52f (diff) | |
download | php-git-96c2056eaaf12d385f89bd1195d3898e80b3fed6.tar.gz |
NetWare related changes/modifications.
-rw-r--r-- | TSRM/TSRM.c | 47 | ||||
-rw-r--r-- | TSRM/TSRM.h | 14 | ||||
-rw-r--r-- | TSRM/tsrm_config.nw.h | 7 | ||||
-rw-r--r-- | TSRM/tsrm_config_common.h | 8 | ||||
-rw-r--r-- | TSRM/tsrm_nw.c | 327 | ||||
-rw-r--r-- | TSRM/tsrm_nw.h | 5 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 159 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.h | 26 |
8 files changed, 373 insertions, 220 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 65447c6df0..c9c6ff31c2 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -286,6 +286,13 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) int hash_value; tsrm_tls_entry *thread_resources; + /* The below if loop is added for NetWare to fix an abend while unloading PHP + * when an Apache unload command is issued on the system console. + * While exiting from PHP, at the end for some reason, this function is called + * with tsrm_tls_table = NULL. When this happened, the server abends when + * tsrm_tls_table is accessed since it is NULL. + */ + if(tsrm_tls_table) { if (!th_id) { #if defined(PTHREADS) /* Fast path for looking up the resources for the current @@ -346,6 +353,7 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) * changes to the structure as we read it. */ TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count); + } /* if(tsrm_tls_table) */ } @@ -412,6 +420,13 @@ TSRM_API THREAD_T tsrm_thread_id(void) { #ifdef TSRM_WIN32 return GetCurrentThreadId(); +#elif defined(NETWARE) + /* There seems to be some problem with the LibC call, NXThreadGetId + * due to which the PHPMyAdmin application was abending in PHP calls. + * Used the MPK call kCurrentThread instead. Need to check this again. + */ +/* return NXThreadGetId(); */ + return kCurrentThread(); #elif defined(GNUPTH) return pth_self(); #elif defined(PTHREADS) @@ -430,10 +445,24 @@ TSRM_API THREAD_T tsrm_thread_id(void) TSRM_API MUTEX_T tsrm_mutex_alloc(void) { MUTEX_T mutexp; +#ifdef NETWARE +#ifndef USE_MPK + /* To use the Recursive Mutex Locking of LibC */ + long flags = NX_MUTEX_RECURSIVE; + NXHierarchy_t order = 0; + NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0); +#endif +#endif #ifdef TSRM_WIN32 mutexp = malloc(sizeof(CRITICAL_SECTION)); InitializeCriticalSection(mutexp); +#elif defined(NETWARE) +#ifdef USE_MPK + mutexp = kMutexAlloc((BYTE*)"PHP-TSRM"); +#else + mutexp = NXMutexAlloc(flags, order, &lockInfo); +#endif #elif defined(GNUPTH) mutexp = (MUTEX_T) malloc(sizeof(*mutexp)); pth_mutex_init(mutexp); @@ -460,6 +489,12 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp) if (mutexp) { #ifdef TSRM_WIN32 DeleteCriticalSection(mutexp); +#elif defined(NETWARE) +#ifdef USE_MPK + kMutexFree(mutexp); +#else + NXMutexFree(mutexp); +#endif #elif defined(GNUPTH) free(mutexp); #elif defined(PTHREADS) @@ -486,6 +521,12 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp) #ifdef TSRM_WIN32 EnterCriticalSection(mutexp); return 1; +#elif defined(NETWARE) +#ifdef USE_MPK + return kMutexLock(mutexp); +#else + return NXLock(mutexp); +#endif #elif defined(GNUPTH) return pth_mutex_acquire(mutexp, 0, NULL); #elif defined(PTHREADS) @@ -507,6 +548,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp) #ifdef TSRM_WIN32 LeaveCriticalSection(mutexp); return 1; +#elif defined(NETWARE) +#ifdef USE_MPK + return kMutexUnlock(mutexp); +#else + return NXUnlock(mutexp); +#endif #elif defined(GNUPTH) return pth_mutex_release(mutexp); #elif defined(PTHREADS) diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 374e8ff2fc..b6fd0f508c 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -36,6 +36,13 @@ #ifdef TSRM_WIN32 # include <windows.h> +#elif defined(NETWARE) +# include <nks/thread.h> +#ifdef USE_MPK +# include <mpklib4php.h> +#else +# include <nks/synch.h> +#endif #elif defined(GNUPTH) # include <pth.h> #elif defined(PTHREADS) @@ -50,6 +57,13 @@ typedef int ts_rsrc_id; #ifdef TSRM_WIN32 # define THREAD_T DWORD # define MUTEX_T CRITICAL_SECTION * +#elif defined(NETWARE) +# define THREAD_T NXThreadId_t +#ifdef USE_MPK +# define MUTEX_T MUTEX +#else +# define MUTEX_T NXMutex_t * +#endif #elif defined(GNUPTH) # define THREAD_T pth_t # define MUTEX_T pth_mutex_t * diff --git a/TSRM/tsrm_config.nw.h b/TSRM/tsrm_config.nw.h index 0681852c7d..147c328483 100644 --- a/TSRM/tsrm_config.nw.h +++ b/TSRM/tsrm_config.nw.h @@ -1,9 +1,12 @@ + #ifndef TSRM_CONFIG_NW_H #define TSRM_CONFIG_NW_H #define HAVE_UTIME 1 -/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */ -/* #define HAVE_ALLOCA 1 */ +/* Though we have alloca(), this seems to be causing some problem + * with the stack pointer. Hence not using it + */ +/*#define HAVE_ALLOCA 1*/ #endif diff --git a/TSRM/tsrm_config_common.h b/TSRM/tsrm_config_common.h index add5a50fa5..6c220fa008 100644 --- a/TSRM/tsrm_config_common.h +++ b/TSRM/tsrm_config_common.h @@ -5,11 +5,13 @@ # define TSRM_WIN32 #endif -#ifndef TSRM_WIN32 +#ifdef TSRM_WIN32 +# include "tsrm_config.w32.h" +#elif defined(NETWARE) +# include "tsrm_config.nw.h" +#else # include "tsrm_config.h" # include <sys/param.h> -#else -# include "tsrm_config.w32.h" #endif #ifdef TSRM_WIN32 diff --git a/TSRM/tsrm_nw.c b/TSRM/tsrm_nw.c index c0f69adb5d..4c09f82e54 100644 --- a/TSRM/tsrm_nw.c +++ b/TSRM/tsrm_nw.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ @@ -12,11 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Venkat Raghavan S <rvenkat@novell.com> | + | Authors: Andi Gutmans <andi@zend.com> | + | Rasmus Lerdorf <rasmus@lerdorf.on.ca> | + | Zeev Suraski <zeev@zend.com> | + | Modified for NetWare: Novell, Inc. | +----------------------------------------------------------------------+ */ -/* $Id$ */ #include <stdlib.h> #include <stdio.h> @@ -24,11 +26,12 @@ #include "TSRM.h" + #ifdef NETWARE #ifdef USE_MKFIFO #include <sys/stat.h> -#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */ +#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */ #include <nks/fsio.h> #endif @@ -39,8 +42,9 @@ #include "mktemp.h" -/* strtok() call in LibC is abending when used in a different address space -- hence using - PHP's version itself for now : Venkat (30/4/02) */ +/* strtok() call in LibC is abending when used in a different address space + * -- hence using PHP's version itself for now + */ #include "tsrm_strtok_r.h" #define tsrm_strtok_r(a,b,c) strtok((a),(b)) @@ -50,211 +54,188 @@ TSRM_API FILE* popen(const char *commandline, const char *type) { - char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL; + char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL; char *tempName = "sys:/php/temp/phpXXXXXX.tmp"; - char *filePath = NULL; - char *ptr = NULL; - int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0; + char *filePath = NULL; + char *ptr = NULL; + int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0; FILE *stream = NULL; #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO) - int pipe_handle; - int mode = O_RDONLY; + int pipe_handle; + int mode = O_RDONLY; #else - NXHandle_t pipe_handle; - NXMode_t mode = NX_O_RDONLY; + NXHandle_t pipe_handle; + NXMode_t mode = NX_O_RDONLY; #endif - NXExecEnvSpec_t envSpec; - NXNameSpec_t nameSpec; - NXVmId_t newVM = 0; + NXExecEnvSpec_t envSpec; + NXNameSpec_t nameSpec; + NXVmId_t newVM = 0; - /* Check for validity of input parameters */ - if (!commandline || !type) - return NULL; + /* Check for validity of input parameters */ + if (!commandline || !type) + return NULL; - /* Get temporary file name */ - filePath = mktemp(tempName); -/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/ + /* Get temporary file name */ + filePath = mktemp(tempName); if (!filePath) return NULL; - /* Set pipe mode according to type -- for now allow only "r" or "w" */ - if (strcmp(type, "r") == 0) + /* Set pipe mode according to type -- for now allow only "r" or "w" */ + if (strcmp(type, "r") == 0) #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO) - mode = O_RDONLY; + mode = O_RDONLY; #else - mode = NX_O_RDONLY; + mode = NX_O_RDONLY; #endif - else if (strcmp(type, "w") == 0) + else if (strcmp(type, "w") == 0) #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO) - mode = O_WRONLY; + mode = O_WRONLY; #else - mode = NX_O_WRONLY; + mode = NX_O_WRONLY; #endif - else - return NULL; + else + return NULL; #ifdef USE_PIPE_OPEN - pipe_handle = pipe_open(filePath, mode); -/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/ - if (pipe_handle == -1) - return NULL; + pipe_handle = pipe_open(filePath, mode); + if (pipe_handle == -1) + return NULL; #elif defined(USE_MKFIFO) - pipe_handle = mkfifo(filePath, mode); -consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle); - if (pipe_handle == -1) - return NULL; + pipe_handle = mkfifo(filePath, mode); + if (pipe_handle == -1) + return NULL; #else - /* - - NetWare doesn't require first parameter - - Allowing LibC to choose the buffer size for now - */ - err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle); -/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/ - if (err) - return NULL; + /* NetWare doesn't require first parameter. + * Allowing LibC to choose the buffer size for now + */ + err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle); + if (err) + return NULL; #endif - /* Copy the environment variables in preparation for the spawn call */ - - envCount = NXGetEnvCount() + 1; /* add one for NULL */ - env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0); - if (!env) - return NULL; - - err = NXCopyEnv(env, envCount); -consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err); - if (err) - { - NXMemFree (env); - return NULL; - } - - /* Separate commandline string into words */ -consoleprintf ("PHP | popen: commandline = %s\n", commandline); - ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL); - ptrLen = strlen(ptr); - - command = (char*)malloc(ptrLen + 1); - if (!command) - { - NXMemFree (env); - return NULL; - } - - strcpy (command, ptr); - - ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL); - while (ptr && (argc < MAX_ARGS)) - { - ptrLen = strlen(ptr); - - argv[argc] = (char*)malloc(ptrLen + 1); - if (!argv[argc]) - { - NXMemFree (env); - - if (command) - free (command); - - for (i = 0; i < argc; i++) - { - if (argv[i]) - free (argv[i]); - } - - return NULL; - } - - strcpy (argv[argc], ptr); - - argc++; - - ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL); - } -consoleprintf ("PHP | popen: commandline string parsed into tokens\n"); - /* Setup the execution environment and spawn new process */ - - envSpec.esFlags = 0; /* Not used */ - envSpec.esArgc = argc; - envSpec.esArgv = (void**)argv; - envSpec.esEnv = (void**)env; - - envSpec.esStdin.ssType = - envSpec.esStdout.ssType = NX_OBJ_FIFO; - envSpec.esStderr.ssType = NX_OBJ_FILE; + /* Copy the environment variables in preparation for the spawn call */ + envCount = NXGetEnvCount() + 1; /* add one for NULL */ + env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0); + if (!env) + return NULL; + + err = NXCopyEnv(env, envCount); + if (err) { + NXMemFree (env); + return NULL; + } + + /* Separate commandline string into words */ + ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL); + ptrLen = strlen(ptr); + + command = (char*)malloc(ptrLen + 1); + if (!command) { + NXMemFree (env); + return NULL; + } + + strcpy (command, ptr); + + ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL); + while (ptr && (argc < MAX_ARGS)) { + ptrLen = strlen(ptr); + + argv[argc] = (char*)malloc(ptrLen + 1); + if (!argv[argc]) { + NXMemFree (env); + + if (command) + free (command); + + for (i = 0; i < argc; i++) { + if (argv[i]) + free (argv[i]); + } + + return NULL; + } + + strcpy (argv[argc], ptr); + argc++; + + ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL); + } + + /* Setup the execution environment and spawn new process */ + envSpec.esFlags = 0; /* Not used */ + envSpec.esArgc = argc; + envSpec.esArgv = (void**)argv; + envSpec.esEnv = (void**)env; + + envSpec.esStdin.ssType = + envSpec.esStdout.ssType = NX_OBJ_FIFO; + envSpec.esStderr.ssType = NX_OBJ_FILE; /* - envSpec.esStdin.ssHandle = - envSpec.esStdout.ssHandle = - envSpec.esStderr.ssHandle = -1; + envSpec.esStdin.ssHandle = + envSpec.esStdout.ssHandle = + envSpec.esStderr.ssHandle = -1; */ - envSpec.esStdin.ssPathCtx = - envSpec.esStdout.ssPathCtx = - envSpec.esStderr.ssPathCtx = NULL; + envSpec.esStdin.ssPathCtx = + envSpec.esStdout.ssPathCtx = + envSpec.esStderr.ssPathCtx = NULL; #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO) - if (mode == O_RDONLY) + if (mode == O_RDONLY) { #else - if (mode == NX_O_RDONLY) + if (mode == NX_O_RDONLY) { #endif - { - envSpec.esStdin.ssPath = filePath; - envSpec.esStdout.ssPath = stdout; - } - else /* Write Only */ - { - envSpec.esStdin.ssPath = stdin; - envSpec.esStdout.ssPath = filePath; - } - - envSpec.esStderr.ssPath = stdout; - - nameSpec.ssType = NX_OBJ_FIFO; -/* nameSpec.ssHandle = 0; */ /* Not used */ - nameSpec.ssPathCtx = NULL; /* Not used */ - nameSpec.ssPath = argv[0]; -consoleprintf ("PHP | popen: environment setup\n"); - err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM); -consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err); - if (!err) - /* Get file pointer corresponding to the pipe (file) opened */ - stream = fdopen(pipe_handle, type); - - /* Clean-up */ - - if (env) - NXMemFree (env); - - if (pipe_handle) + envSpec.esStdin.ssPath = filePath; + envSpec.esStdout.ssPath = stdout; + } else { /* Write Only */ + envSpec.esStdin.ssPath = stdin; + envSpec.esStdout.ssPath = filePath; + } + + envSpec.esStderr.ssPath = stdout; + + nameSpec.ssType = NX_OBJ_FIFO; +/* nameSpec.ssHandle = 0; */ /* Not used */ + nameSpec.ssPathCtx = NULL; /* Not used */ + nameSpec.ssPath = argv[0]; + err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM); + if (!err) + /* Get file pointer corresponding to the pipe (file) opened */ + stream = fdopen(pipe_handle, type); + + /* Clean-up */ + if (env) + NXMemFree (env); + + if (pipe_handle) #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO) - close(pipe_handle); + close(pipe_handle); #else - NXClose(pipe_handle); + NXClose(pipe_handle); #endif - if (command) - free (command); + if (command) + free (command); - for (i = 0; i < argc; i++) - { - if (argv[i]) - free (argv[i]); - } -consoleprintf ("PHP | popen: all clean-up done, returning...\n"); - return stream; + for (i = 0; i < argc; i++) { + if (argv[i]) + free (argv[i]); + } + return stream; } + TSRM_API int pclose(FILE* stream) { - int err = 0; - NXHandle_t fd = 0; - - /* Get the process associated with this pipe (file) handle and terminate it */ - fd = fileno(stream); - NXClose (fd); + int err = 0; + NXHandle_t fd = 0; - err = fclose(stream); + /* Get the process associated with this pipe (file) handle and terminate it */ + fd = fileno(stream); + NXClose (fd); - return err; + err = fclose(stream); + return err; } -#endif +#endif /* NETWARE */ diff --git a/TSRM/tsrm_nw.h b/TSRM/tsrm_nw.h index 3ced3f299b..9cfb692f47 100644 --- a/TSRM/tsrm_nw.h +++ b/TSRM/tsrm_nw.h @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ @@ -12,7 +12,8 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Venkat Raghavan S <rvenkat@novell.com> | + | Authors: Daniel Beulshausen <daniel@php4win.de> | + | Modified for NetWare: Novell, Inc. | +----------------------------------------------------------------------+ */ diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 1712a9c2d8..b6b4052203 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -36,12 +36,18 @@ #include "tsrm_win32.h" #endif +#ifdef NETWARE +/*#include "pipe.h"*/ +#include "tsrm_nw.h" +#endif + #define VIRTUAL_CWD_DEBUG 0 #include "TSRM.h" -/* Only need mutex for popen() in Windows because it doesn't chdir() on UNIX */ -#if defined(TSRM_WIN32) && defined(ZTS) +/* Only need mutex for popen() in Windows and NetWare because it doesn't chdir() on UNIX */ +#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS) +#define TSRM_CWD_MUTEX 1 MUTEX_T cwd_mutex; #endif @@ -86,6 +92,16 @@ static int php_check_dots(const char *element, int n) (len == 1 && ptr[0] == '.') +/* NetWare has strtok() (in LibC) and allows both slashes in paths, + * like Windows. But rest of the stuff is like Unix + */ +#elif defined(NETWARE) +/* strtok() call in LibC is abending when used in a different address space. + * Hence using PHP's version itself for now + */ +/*#define tsrm_strtok_r(a,b,c) strtok((a),(b))*/ +#define TOKENIZER_STRING "/\\" + #else #define TOKENIZER_STRING "/" #endif @@ -121,9 +137,15 @@ static int php_check_dots(const char *element, int n) static int php_is_dir_ok(const cwd_state *state) { +#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH)) struct stat buf; if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode)) +#else + struct stat_libc buf; + + if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode)) +#endif return (0); return (1); @@ -131,9 +153,15 @@ static int php_is_dir_ok(const cwd_state *state) static int php_is_file_ok(const cwd_state *state) { +#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH)) struct stat buf; if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode)) +#else + struct stat_libc buf; + + if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode)) +#endif return (0); return (1); @@ -182,7 +210,7 @@ CWD_API void virtual_cwd_startup(void) cwd_globals_ctor(&cwd_globals TSRMLS_CC); #endif -#if defined(TSRM_WIN32) && defined(ZTS) +#ifdef TSRM_CWD_MUTEX cwd_mutex = tsrm_mutex_alloc(); #endif } @@ -192,7 +220,7 @@ CWD_API void virtual_cwd_shutdown(void) #ifndef ZTS cwd_globals_dtor(&cwd_globals TSRMLS_CC); #endif -#if defined(TSRM_WIN32) && defined(ZTS) +#ifdef TSRM_CWD_MUTEX tsrm_mutex_free(cwd_mutex); #endif @@ -274,7 +302,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func if (path_length == 0) return (0); -#if !defined(TSRM_WIN32) && !defined(__BEOS__) +#if !defined(TSRM_WIN32) && !defined(__BEOS__) && !defined(NETWARE) if (IS_ABSOLUTE_PATH(path, path_length)) { if (realpath(path, resolved_path)) { path = resolved_path; @@ -309,7 +337,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path); #endif if (IS_ABSOLUTE_PATH(path_copy, path_length)) { +/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */ +#ifndef NETWARE copy_amount = COPY_WHEN_ABSOLUTE; +#else + copy_amount = COPY_WHEN_ABSOLUTE(path_copy); +#endif is_absolute = 1; #ifdef TSRM_WIN32 } else if (IS_UNC_PATH(path_copy, path_length)) { @@ -368,6 +401,11 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func IsDBCSLeadByte(state->cwd[state->cwd_length-2])) { state->cwd[state->cwd_length++] = DEFAULT_SLASH; } +#elif defined(NETWARE) + /* If the token is a volume name, it will have colon at the end -- so, no slash before it */ + if (ptr[ptr_length-1] != ':') { + state->cwd[state->cwd_length++] = DEFAULT_SLASH; + } #else state->cwd[state->cwd_length++] = DEFAULT_SLASH; #endif @@ -377,7 +415,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok); } +/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */ +#ifndef NETWARE if (state->cwd_length == COPY_WHEN_ABSOLUTE) { +#else + if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) { +#endif state->cwd = (char *) realloc(state->cwd, state->cwd_length+1+1); state->cwd[state->cwd_length] = DEFAULT_SLASH; state->cwd[state->cwd_length+1] = '\0'; @@ -427,7 +470,12 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path return -1; } +/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */ +#ifndef NETWARE if (length == COPY_WHEN_ABSOLUTE && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */ +#else + if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */ +#endif length++; } temp = (char *) tsrm_do_alloca(length+1); @@ -526,7 +574,7 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC) return ret; } -#ifndef TSRM_WIN32 +#if !defined(TSRM_WIN32) && !defined(NETWARE) CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC) { cwd_state new_state; @@ -602,7 +650,11 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) return retval; } +#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH)) CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) +#else +CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC) +#endif { cwd_state new_state; int retval; @@ -610,13 +662,17 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) CWD_STATE_COPY(&new_state, &CWDG(cwd)); virtual_file_ex(&new_state, path, NULL); +#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH)) retval = stat(new_state.cwd, buf); +#else + retval = stat(new_state.cwd, (struct stat*)buf); +#endif CWD_STATE_FREE(&new_state); return retval; } -#ifndef TSRM_WIN32 +#if !defined(TSRM_WIN32) && !defined(NETWARE) CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) { @@ -697,46 +753,41 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) return retval; } -#ifndef TSRM_WIN32 +#ifdef TSRM_WIN32 +/* On Windows the trick of prepending "cd cwd; " doesn't work so we need to perform + a real chdir() and mutex it + */ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) { - int command_length; - char *command_line; - char *ptr; + char prev_cwd[MAXPATHLEN]; + char *getcwd_result; FILE *retval; - command_length = strlen(command); - - ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1); - if (!command_line) { + getcwd_result = getcwd(prev_cwd, MAXPATHLEN); + if (!getcwd_result) { return NULL; } - memcpy(ptr, "cd ", sizeof("cd ")-1); - ptr += sizeof("cd ")-1; - if (CWDG(cwd).cwd_length == 0) { - *ptr++ = DEFAULT_SLASH; - } else { - memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length); - ptr += CWDG(cwd).cwd_length; - } - - *ptr++ = ' '; - *ptr++ = ';'; - *ptr++ = ' '; +#ifdef ZTS + tsrm_mutex_lock(cwd_mutex); +#endif - memcpy(ptr, command, command_length+1); - retval = popen(command_line, type); + chdir(CWDG(cwd).cwd); + retval = popen(command, type); + chdir(prev_cwd); + +#ifdef ZTS + tsrm_mutex_unlock(cwd_mutex); +#endif - free(command_line); return retval; } -#else +#elif defined(NETWARE) -/* On Windows the trick of prepending "cd cwd; " doesn't work so we need to perform - a real chdir() and mutex it +/* On NetWare, the trick of prepending "cd cwd; " doesn't work so we need to perform + * a VCWD_CHDIR() and mutex it. */ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) { @@ -744,7 +795,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) char *getcwd_result; FILE *retval; - getcwd_result = getcwd(prev_cwd, MAXPATHLEN); + getcwd_result = VCWD_GETCWD(prev_cwd, MAXPATHLEN); if (!getcwd_result) { return NULL; } @@ -753,9 +804,9 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) tsrm_mutex_lock(cwd_mutex); #endif - chdir(CWDG(cwd).cwd); + VCWD_CHDIR(CWDG(cwd).cwd); retval = popen(command, type); - chdir(prev_cwd); + VCWD_CHDIR(prev_cwd); #ifdef ZTS tsrm_mutex_unlock(cwd_mutex); @@ -764,6 +815,42 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) return retval; } +#else + +CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) +{ + int command_length; + char *command_line; + char *ptr; + FILE *retval; + + command_length = strlen(command); + + ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1); + if (!command_line) { + return NULL; + } + memcpy(ptr, "cd ", sizeof("cd ")-1); + ptr += sizeof("cd ")-1; + + if (CWDG(cwd).cwd_length == 0) { + *ptr++ = DEFAULT_SLASH; + } else { + memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length); + ptr += CWDG(cwd).cwd_length; + } + + *ptr++ = ' '; + *ptr++ = ';'; + *ptr++ = ' '; + + memcpy(ptr, command, command_length+1); + retval = popen(command_line, type); + + free(command_line); + return retval; +} + #endif diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index 98efaa1432..8dde5f523f 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -58,6 +58,20 @@ typedef unsigned short mode_t; #define IS_UNC_PATH(path, len) \ (len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1])) +#elif defined(NETWARE) +#ifdef HAVE_DIRENT_H +#include <dirent.h> +#endif + +#define DEFAULT_SLASH '/' +#define DEFAULT_DIR_SEPARATOR ';' +#define IS_SLASH(c) ((c) == '/' || (c) == '\\') +#define IS_SLASH_P(c) IS_SLASH(*(c)) +#define COPY_WHEN_ABSOLUTE(path) \ + (strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */ +#define IS_ABSOLUTE_PATH(path, len) \ + (strchr(path, ':') != NULL) /* Colon indicates volume name */ + #else #ifdef HAVE_DIRENT_H #include <dirent.h> @@ -120,8 +134,12 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC); CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...); CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC); CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC); +#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH)) CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC); -#ifndef TSRM_WIN32 +#else +CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC); +#endif +#if !defined(TSRM_WIN32) && !defined(NETWARE) CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC); #endif CWD_API int virtual_unlink(const char *path TSRMLS_DC); @@ -168,7 +186,7 @@ typedef struct _virtual_cwd_globals { #define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC) #define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC) #define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC) -#ifdef TSRM_WIN32 +#if defined(TSRM_WIN32) || defined(NETWARE) #define VCWD_LSTAT(path, buff) virtual_stat(path, buff TSRMLS_CC) #else #define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC) @@ -205,7 +223,7 @@ typedef struct _virtual_cwd_globals { #define VCWD_OPENDIR(pathname) opendir(pathname) #define VCWD_POPEN(command, type) popen(command, type) -#ifndef TSRM_WIN32 +#if !defined(TSRM_WIN32) && !defined(NETWARE) #define VCWD_REALPATH(path, real_path) realpath(path, real_path) #else #define VCWD_REALPATH(path, real_path) strcpy(real_path, path) @@ -215,7 +233,7 @@ typedef struct _virtual_cwd_globals { #define VCWD_UTIME(path, time) utime(path, time) #endif #define VCWD_CHMOD(path, mode) chmod(path, mode) -#ifndef TSRM_WIN32 +#if !defined(TSRM_WIN32) && !defined(NETWARE) #define VCWD_CHOWN(path, owner, group) chown(path, owner, group) #endif |