root/TSRM/tsrm_nw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. popen
  2. pclose

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Venkat Raghavan S <rvenkat@novell.com>                      |
  16    |          Anantha Kesari H Y <hyanantha@novell.com>                   |
  17    +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #include <stdlib.h>
  23 #include <stdio.h>
  24 #include <fcntl.h>
  25 
  26 #include "TSRM.h"
  27 
  28 #ifdef NETWARE
  29 
  30 #ifdef USE_MKFIFO
  31 #include <sys/stat.h>
  32 #elif !defined(USE_PIPE_OPEN)   /* NXFifoOpen */
  33 #include <nks/fsio.h>
  34 #endif
  35 
  36 #include <nks/vm.h>
  37 #include <nks/memory.h>
  38 
  39 #include <string.h>
  40 
  41 #include "mktemp.h"
  42 
  43 /* strtok() call in LibC is abending when used in a different address space
  44  * -- hence using PHP's version itself for now
  45  */
  46 #include "tsrm_strtok_r.h"
  47 #define tsrm_strtok_r(a,b,c) strtok((a),(b))
  48 
  49 #define WHITESPACE  " \t"
  50 #define MAX_ARGS    10
  51 
  52 
  53 TSRM_API FILE* popen(const char *commandline, const char *type)
  54 {
  55         char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
  56         char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
  57         char *filePath = NULL;
  58         char *ptr = NULL;
  59         int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
  60         FILE *stream = NULL;
  61 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
  62         int pipe_handle;
  63         int mode = O_RDONLY;
  64 #else
  65         NXHandle_t pipe_handle;
  66         NXMode_t mode = NX_O_RDONLY;
  67 #endif
  68         NXExecEnvSpec_t envSpec;
  69         NXNameSpec_t nameSpec;
  70         NXVmId_t newVM = 0;
  71 
  72         /* Check for validity of input parameters */
  73         if (!commandline || !type)
  74                 return NULL;
  75 
  76         /* Get temporary file name */
  77         filePath = mktemp(tempName);
  78         if (!filePath)
  79                 return NULL;
  80 
  81         /* Set pipe mode according to type -- for now allow only "r" or "w" */
  82         if (strcmp(type, "r") == 0)
  83 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
  84                 mode = O_RDONLY;
  85 #else
  86                 mode = NX_O_RDONLY;
  87 #endif
  88         else if (strcmp(type, "w") == 0)
  89 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
  90                 mode = O_WRONLY;
  91 #else
  92                 mode = NX_O_WRONLY;
  93 #endif
  94         else
  95                 return NULL;
  96 
  97 #ifdef USE_PIPE_OPEN
  98         pipe_handle = pipe_open(filePath, mode);
  99         if (pipe_handle == -1)
 100                 return NULL;
 101 #elif defined(USE_MKFIFO)
 102         pipe_handle = mkfifo(filePath, mode);
 103         if (pipe_handle == -1)
 104                 return NULL;
 105 #else
 106         /* - NetWare doesn't require first parameter
 107          * - Allowing LibC to choose the buffer size for now
 108          */
 109         err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
 110         if (err)
 111                 return NULL;
 112 #endif
 113 
 114         /* Copy the environment variables in preparation for the spawn call */
 115         envCount = NXGetEnvCount() + 1;  /* add one for NULL */
 116         env = (char **) NXMemAlloc(sizeof(char *) * envCount, 0);
 117         if (!env)
 118                 return NULL;
 119 
 120         err = NXCopyEnv(env, envCount);
 121         if (err) {
 122                 NXMemFree (env);
 123                 return NULL;
 124         }
 125 
 126         /* Separate commandline string into words */
 127         ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
 128         ptrLen = strlen(ptr);
 129 
 130         command = (char*)malloc(ptrLen + 1);
 131         if (!command) {
 132                 NXMemFree (env);
 133                 return NULL;
 134         }
 135 
 136         strcpy (command, ptr);
 137 
 138         ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
 139         while (ptr && (argc < MAX_ARGS)) {
 140                 ptrLen = strlen(ptr);
 141 
 142                 argv[argc] = (char*)malloc(ptrLen + 1);
 143                 if (!argv[argc]) {
 144                         NXMemFree (env);
 145                         if (command)
 146                                 free (command);
 147 
 148                         for (i = 0; i < argc; i++) {
 149                                 if (argv[i])
 150                                         free (argv[i]);
 151                         }
 152 
 153                         return NULL;
 154                 }
 155 
 156                 strcpy (argv[argc], ptr);
 157                 argc++;
 158                 ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
 159         }
 160 
 161         /* Setup the execution environment and spawn new process */
 162         envSpec.esFlags = 0;    /* Not used */
 163         envSpec.esArgc = argc;
 164         envSpec.esArgv = (void **) argv;
 165         envSpec.esEnv = (void **) env;
 166 
 167 /*      envSpec.esStdin.ssType = */
 168         envSpec.esStdout.ssType = NX_OBJ_FIFO;
 169         envSpec.esStderr.ssType = NX_OBJ_FILE;
 170 
 171         /* 'ssHandle' is not a struct/union/class member */
 172 /*
 173         envSpec.esStdin.ssHandle =
 174         envSpec.esStdout.ssHandle =
 175         envSpec.esStderr.ssHandle = -1;
 176 */
 177         envSpec.esStdin.ssPathCtx = NULL;
 178         envSpec.esStdout.ssPathCtx = NULL;
 179         envSpec.esStderr.ssPathCtx = NULL;
 180 
 181 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
 182         if (mode == O_RDONLY) {
 183 #else
 184         if (mode == NX_O_RDONLY) {
 185 #endif
 186                 envSpec.esStdin.ssPath = filePath;
 187                 envSpec.esStdout.ssPath = stdout;
 188         } else { /* Write Only */
 189                 envSpec.esStdin.ssPath = stdin;
 190                 envSpec.esStdout.ssPath = filePath;
 191         }
 192 
 193         envSpec.esStderr.ssPath = stdout;
 194 
 195         nameSpec.ssType = NX_OBJ_FIFO;
 196 /*      nameSpec.ssHandle = 0; */       /* 'ssHandle' is not a struct/union/class member */
 197         nameSpec.ssPathCtx = NULL;  /* Not used */
 198         nameSpec.ssPath = argv[0];
 199         err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
 200         if (!err)
 201                 /* Get file pointer corresponding to the pipe (file) opened */
 202                 stream = fdopen(pipe_handle, type);
 203 
 204         /* Clean-up */
 205         if (env)
 206                 NXMemFree (env);
 207 
 208         if (pipe_handle)
 209 #if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
 210                 close(pipe_handle);
 211 #else
 212                 NXClose(pipe_handle);
 213 #endif
 214 
 215         if (command)
 216                 free (command);
 217 
 218         for (i = 0; i < argc; i++) {
 219                 if (argv[i])
 220                         free (argv[i]);
 221         }
 222 
 223         return stream;
 224 }
 225 
 226 TSRM_API int pclose(FILE* stream)
 227 {
 228         int err = 0;
 229         NXHandle_t fd = 0;
 230 
 231         /* Get the process associated with this pipe (file) handle and terminate it */
 232         fd = fileno(stream);
 233         NXClose (fd);
 234 
 235         err = fclose(stream);
 236 
 237         return err;
 238 }
 239 
 240 #endif  /* NETWARE */

/* [<][>][^][v][top][bottom][index][help] */