Back to index

php5  5.3.10
tsrm_nw.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Venkat Raghavan S <rvenkat@novell.com>                      |
00016    |          Anantha Kesari H Y <hyanantha@novell.com>                   |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: tsrm_nw.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <fcntl.h>
00025 
00026 #include "TSRM.h"
00027 
00028 #ifdef NETWARE
00029 
00030 #ifdef USE_MKFIFO
00031 #include <sys/stat.h>
00032 #elif !defined(USE_PIPE_OPEN)   /* NXFifoOpen */
00033 #include <nks/fsio.h>
00034 #endif
00035 
00036 #include <nks/vm.h>
00037 #include <nks/memory.h>
00038 
00039 #include <string.h>
00040 
00041 #include "mktemp.h"
00042 
00043 /* strtok() call in LibC is abending when used in a different address space
00044  * -- hence using PHP's version itself for now
00045  */
00046 #include "tsrm_strtok_r.h"
00047 #define tsrm_strtok_r(a,b,c) strtok((a),(b))
00048 
00049 #define WHITESPACE  " \t"
00050 #define MAX_ARGS    10
00051 
00052 
00053 TSRM_API FILE* popen(const char *commandline, const char *type)
00054 {
00055        char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
00056        char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
00057        char *filePath = NULL;
00058        char *ptr = NULL;
00059        int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
00060        FILE *stream = NULL;
00061 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
00062        int pipe_handle;
00063        int mode = O_RDONLY;
00064 #else
00065        NXHandle_t pipe_handle;
00066        NXMode_t mode = NX_O_RDONLY;
00067 #endif
00068        NXExecEnvSpec_t envSpec;
00069        NXNameSpec_t nameSpec;
00070        NXVmId_t newVM = 0;
00071 
00072        /* Check for validity of input parameters */
00073        if (!commandline || !type)
00074               return NULL;
00075 
00076        /* Get temporary file name */
00077        filePath = mktemp(tempName);
00078        if (!filePath)
00079               return NULL;
00080 
00081        /* Set pipe mode according to type -- for now allow only "r" or "w" */
00082        if (strcmp(type, "r") == 0)
00083 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
00084               mode = O_RDONLY;
00085 #else
00086               mode = NX_O_RDONLY;
00087 #endif
00088        else if (strcmp(type, "w") == 0)
00089 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
00090               mode = O_WRONLY;
00091 #else
00092               mode = NX_O_WRONLY;
00093 #endif
00094        else
00095               return NULL;
00096 
00097 #ifdef USE_PIPE_OPEN
00098        pipe_handle = pipe_open(filePath, mode);
00099        if (pipe_handle == -1)
00100               return NULL;
00101 #elif defined(USE_MKFIFO)
00102        pipe_handle = mkfifo(filePath, mode);
00103        if (pipe_handle == -1)
00104               return NULL;
00105 #else
00106        /* - NetWare doesn't require first parameter
00107         * - Allowing LibC to choose the buffer size for now
00108         */
00109        err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
00110        if (err)
00111               return NULL;
00112 #endif
00113 
00114        /* Copy the environment variables in preparation for the spawn call */
00115        envCount = NXGetEnvCount() + 1;  /* add one for NULL */
00116        env = (char **) NXMemAlloc(sizeof(char *) * envCount, 0);
00117        if (!env)
00118               return NULL;
00119 
00120        err = NXCopyEnv(env, envCount);
00121        if (err) {
00122               NXMemFree (env);
00123               return NULL;
00124        }
00125 
00126        /* Separate commandline string into words */
00127        ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
00128        ptrLen = strlen(ptr);
00129 
00130        command = (char*)malloc(ptrLen + 1);
00131        if (!command) {
00132               NXMemFree (env);
00133               return NULL;
00134        }
00135 
00136        strcpy (command, ptr);
00137 
00138        ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
00139        while (ptr && (argc < MAX_ARGS)) {
00140               ptrLen = strlen(ptr);
00141 
00142               argv[argc] = (char*)malloc(ptrLen + 1);
00143               if (!argv[argc]) {
00144                      NXMemFree (env);
00145                      if (command)
00146                             free (command);
00147 
00148                      for (i = 0; i < argc; i++) {
00149                             if (argv[i])
00150                                    free (argv[i]);
00151                      }
00152 
00153                      return NULL;
00154               }
00155 
00156               strcpy (argv[argc], ptr);
00157               argc++;
00158               ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
00159        }
00160 
00161        /* Setup the execution environment and spawn new process */
00162        envSpec.esFlags = 0;    /* Not used */
00163        envSpec.esArgc = argc;
00164        envSpec.esArgv = (void **) argv;
00165        envSpec.esEnv = (void **) env;
00166 
00167 /*     envSpec.esStdin.ssType = */
00168        envSpec.esStdout.ssType = NX_OBJ_FIFO;
00169        envSpec.esStderr.ssType = NX_OBJ_FILE;
00170 
00171        /* 'ssHandle' is not a struct/union/class member */
00172 /*
00173        envSpec.esStdin.ssHandle =
00174        envSpec.esStdout.ssHandle =
00175        envSpec.esStderr.ssHandle = -1;
00176 */
00177        envSpec.esStdin.ssPathCtx = NULL;
00178        envSpec.esStdout.ssPathCtx = NULL;
00179        envSpec.esStderr.ssPathCtx = NULL;
00180 
00181 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
00182        if (mode == O_RDONLY) {
00183 #else
00184        if (mode == NX_O_RDONLY) {
00185 #endif
00186               envSpec.esStdin.ssPath = filePath;
00187               envSpec.esStdout.ssPath = stdout;
00188        } else { /* Write Only */
00189               envSpec.esStdin.ssPath = stdin;
00190               envSpec.esStdout.ssPath = filePath;
00191        }
00192 
00193        envSpec.esStderr.ssPath = stdout;
00194 
00195        nameSpec.ssType = NX_OBJ_FIFO;
00196 /*     nameSpec.ssHandle = 0; */   /* 'ssHandle' is not a struct/union/class member */
00197        nameSpec.ssPathCtx = NULL;  /* Not used */
00198        nameSpec.ssPath = argv[0];
00199        err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
00200        if (!err)
00201               /* Get file pointer corresponding to the pipe (file) opened */
00202               stream = fdopen(pipe_handle, type);
00203 
00204        /* Clean-up */
00205        if (env)
00206               NXMemFree (env);
00207 
00208        if (pipe_handle)
00209 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
00210               close(pipe_handle);
00211 #else
00212               NXClose(pipe_handle);
00213 #endif
00214 
00215        if (command)
00216               free (command);
00217 
00218        for (i = 0; i < argc; i++) {
00219               if (argv[i])
00220                      free (argv[i]);
00221        }
00222 
00223        return stream;
00224 }
00225 
00226 TSRM_API int pclose(FILE* stream)
00227 {
00228        int err = 0;
00229        NXHandle_t fd = 0;
00230 
00231        /* Get the process associated with this pipe (file) handle and terminate it */
00232        fd = fileno(stream);
00233        NXClose (fd);
00234 
00235        err = fclose(stream);
00236 
00237        return err;
00238 }
00239 
00240 #endif /* NETWARE */