Annotation of embedaddon/php/TSRM/tsrm_nw.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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:
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 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 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>