hyanantha               Fri Oct 25 07:52:34 2002 EDT

  Added files:                 (Branch: PHP_4_2_0)
    /TSRM       tsrm_config.nw.h tsrm_nw.c tsrm_nw.h 

  Modified files:              
    /TSRM       TSRM.c TSRM.h tsrm_config_common.h tsrm_virtual_cwd.c 
                tsrm_virtual_cwd.h 
  Log:
  NetWare related changes/modifications.
  
  
Index: TSRM/TSRM.c
diff -u TSRM/TSRM.c:1.42 TSRM/TSRM.c:1.42.4.1
--- TSRM/TSRM.c:1.42    Mon Jul 30 01:46:31 2001
+++ TSRM/TSRM.c Fri Oct 25 07:52:34 2002
@@ -286,6 +286,13 @@
        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 @@
         * 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 @@
 {
 #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 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 @@
     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 @@
 #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 @@
 #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)
Index: TSRM/TSRM.h
diff -u TSRM/TSRM.h:1.31 TSRM/TSRM.h:1.31.4.1
--- TSRM/TSRM.h:1.31    Thu Aug  2 12:03:17 2001
+++ TSRM/TSRM.h Fri Oct 25 07:52:34 2002
@@ -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 @@
 #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 *
Index: TSRM/tsrm_config_common.h
diff -u TSRM/tsrm_config_common.h:1.6 TSRM/tsrm_config_common.h:1.6.2.1
--- TSRM/tsrm_config_common.h:1.6       Sun Dec  9 18:43:20 2001
+++ TSRM/tsrm_config_common.h   Fri Oct 25 07:52:34 2002
@@ -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
Index: TSRM/tsrm_virtual_cwd.c
diff -u TSRM/tsrm_virtual_cwd.c:1.27.2.2 TSRM/tsrm_virtual_cwd.c:1.27.2.3
--- TSRM/tsrm_virtual_cwd.c:1.27.2.2    Thu Apr 25 10:52:46 2002
+++ TSRM/tsrm_virtual_cwd.c     Fri Oct 25 07:52:34 2002
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: tsrm_virtual_cwd.c,v 1.27.2.2 2002/04/25 14:52:46 hirokawa Exp $ */
+/* $Id: tsrm_virtual_cwd.c,v 1.27.2.3 2002/10/25 11:52:34 hyanantha Exp $ */
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -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 @@
        (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_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_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_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 @@
 #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 @@
        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 @@
        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 @@
                                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 @@
                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 @@
                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 @@
        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 @@
        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_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 @@
        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 @@
        char *getcwd_result;
        FILE *retval;
 
-       getcwd_result = getcwd(prev_cwd, MAXPATHLEN);
+       getcwd_result = VCWD_GETCWD(prev_cwd, MAXPATHLEN);
        if (!getcwd_result) {
                return NULL;
        }
@@ -753,14 +804,50 @@
        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);
 #endif
 
+       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;
 }
 
Index: TSRM/tsrm_virtual_cwd.h
diff -u TSRM/tsrm_virtual_cwd.h:1.17.2.1 TSRM/tsrm_virtual_cwd.h:1.17.2.2
--- TSRM/tsrm_virtual_cwd.h:1.17.2.1    Thu Apr 25 10:52:46 2002
+++ TSRM/tsrm_virtual_cwd.h     Fri Oct 25 07:52:34 2002
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: tsrm_virtual_cwd.h,v 1.17.2.1 2002/04/25 14:52:46 hirokawa Exp $ */
+/* $Id: tsrm_virtual_cwd.h,v 1.17.2.2 2002/10/25 11:52:34 hyanantha Exp $ */
 
 #ifndef VIRTUAL_CWD_H
 #define VIRTUAL_CWD_H
@@ -58,6 +58,20 @@
 #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 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 @@
 #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 @@
 #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 @@
 #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
 

Index: TSRM/tsrm_config.nw.h
+++ TSRM/tsrm_config.nw.h
#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 */

#endif

Index: TSRM/tsrm_nw.c
+++ TSRM/tsrm_nw.c
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2002 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available at through the world-wide-web at                           |
   | http://www.php.net/license/2_02.txt.                                 |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Venkat Raghavan S <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
*/

/* $Id: tsrm_nw.c,v 1.1 2002/05/29 08:41:21 rvenkat Exp $ */

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#include "TSRM.h"

#ifdef NETWARE

#ifdef USE_MKFIFO
#include <sys/stat.h>
#elif !defined(USE_PIPE_OPEN)   /* NXFifoOpen */
#include <nks/fsio.h>
#endif

#include <nks/vm.h>
#include <nks/memory.h>

#include <string.h>

#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) */
#include "tsrm_strtok_r.h"
#define tsrm_strtok_r(a,b,c) strtok((a),(b))

#define WHITESPACE  " \t"
#define MAX_ARGS    10


TSRM_API FILE* popen(const char *commandline, const char *type)
{
    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;
        FILE *stream = NULL;
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
    int pipe_handle;
    int mode = O_RDONLY;
#else
    NXHandle_t pipe_handle;
    NXMode_t mode = NX_O_RDONLY;
#endif
    NXExecEnvSpec_t envSpec;
    NXNameSpec_t nameSpec;
    NXVmId_t newVM = 0;

    /* 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);*/
        if (!filePath)
                return NULL;

    /* 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;
#else
        mode = NX_O_RDONLY;
#endif
    else if (strcmp(type, "w") == 0)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
        mode = O_WRONLY;
#else
        mode = NX_O_WRONLY;
#endif
    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;
#elif defined(USE_MKFIFO)
    pipe_handle = mkfifo(filePath, mode);
consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
    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;
#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;
/*
    envSpec.esStdin.ssHandle =
    envSpec.esStdout.ssHandle =
    envSpec.esStderr.ssHandle = -1;
*/
    envSpec.esStdin.ssPathCtx =
    envSpec.esStdout.ssPathCtx =
    envSpec.esStderr.ssPathCtx = NULL;

#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
    if (mode == O_RDONLY)
#else
    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)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
        close(pipe_handle);
#else
        NXClose(pipe_handle);
#endif

    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;
}

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);

    err = fclose(stream);

    return err;
}

#endif

Index: TSRM/tsrm_nw.h
+++ TSRM/tsrm_nw.h
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2002 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available at through the world-wide-web at                           |
   | http://www.php.net/license/2_02.txt.                                 |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Venkat Raghavan S <[EMAIL PROTECTED]>                      |
   +----------------------------------------------------------------------+
*/


#ifndef TSRM_NW_H
#define TSRM_NW_H

#include "TSRM.h"

TSRM_API FILE* popen(const char *command, const char *type);
TSRM_API int pclose(FILE* stream);

#endif

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to