mirror of
https://github.com/php/php-src.git
synced 2024-11-29 04:46:07 +08:00
261 lines
6.9 KiB
C
261 lines
6.9 KiB
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 |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
#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
|