Merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module
- process-2
- Merge into process-module
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~zorba-coders/zorba/process-2 | ||||
Merge into: | lp:zorba/process-module | ||||
Diff against target: |
582 lines (+274/-57) 17 files modified
src/com/zorba-xquery/www/modules/CMakeLists.txt (+1/-1) src/com/zorba-xquery/www/modules/process.xq (+107/-11) src/com/zorba-xquery/www/modules/process.xq.src/process.cpp (+115/-33) src/com/zorba-xquery/www/modules/process.xq.src/process.h (+7/-4) test/ExpQueryResults/process2-01.xml.res (+1/-0) test/ExpQueryResults/process2-02.xml.res (+1/-0) test/ExpQueryResults/process2-03.xml.res (+1/-0) test/ExpQueryResults/process2-04.xml.res (+1/-0) test/ExpQueryResults/process2-05.xml.res (+1/-0) test/ExpQueryResults/process2-06.xml.res (+1/-0) test/Queries/process.xq (+8/-8) test/Queries/process2-01.xq (+5/-0) test/Queries/process2-02.xq (+5/-0) test/Queries/process2-03.xq (+5/-0) test/Queries/process2-04.xq (+6/-0) test/Queries/process2-05.xq (+5/-0) test/Queries/process2-06.xq (+4/-0) |
||||
To merge this branch: | bzr merge lp:~zorba-coders/zorba/process-2 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nicolae Brinza | Approve | ||
Matthias Brantner | Pending | ||
Review via email: mp+164354@code.launchpad.net |
Commit message
Version 2.0 of the process module, allows running executables directly, without invoking bash/cmd.exe
Description of the change
Version 2.0 of the process module, allows running executables directly, without invoking bash/cmd.exe
Nicolae Brinza (nbrinza) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.
Nicolae Brinza (nbrinza) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/process-2 into lp:zorba/process-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job process-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
- 40. By Nicolae Brinza
-
Fixed the build
- 41. By Nicolae Brinza
-
Updated documentation
- 42. By Nicolae Brinza
-
Addressed review comments: documentation fixes; brought back version 1.0 of the module, both 1.0 and 2.0 are avialable now
- 43. By Nicolae Brinza
-
Removed unused function
- 44. By Nicolae Brinza
-
The child fork()'ed process will now call abort() instead of exit() in order to avoid static object deallocation
- 45. By Nicolae Brinza
-
Improved comments; changed process module version from XQuery to JSONiq; removed xs: prefixes
- 46. By Nicolae Brinza
-
Moved the ver2.0 process module to the zorba.io ver1.0 namespace
- 47. By Matthias Brantner
-
moved files
- 48. By Matthias Brantner
-
fixed module naming and versioning
- 49. By Matthias Brantner
-
improve documentation
- 50. By Nicolae Brinza
-
Removed unecessary includes
- 51. By Nicolae Brinza
-
Changed module's errors to the new modules guidelines; Potential fix for execvpe() on Macs
- 52. By Nicolae Brinza
-
Merged with process module trunk
Unmerged revisions
Preview Diff
1 | === modified file 'src/com/zorba-xquery/www/modules/CMakeLists.txt' | |||
2 | --- src/com/zorba-xquery/www/modules/CMakeLists.txt 2011-07-01 09:24:09 +0000 | |||
3 | +++ src/com/zorba-xquery/www/modules/CMakeLists.txt 2013-05-17 14:51:23 +0000 | |||
4 | @@ -12,4 +12,4 @@ | |||
5 | 12 | # See the License for the specific language governing permissions and | 12 | # See the License for the specific language governing permissions and |
6 | 13 | # limitations under the License. | 13 | # limitations under the License. |
7 | 14 | 14 | ||
9 | 15 | DECLARE_ZORBA_MODULE (URI "http://www.zorba-xquery.com/modules/process" VERSION 1.0 FILE "process.xq") | 15 | DECLARE_ZORBA_MODULE (URI "http://www.zorba-xquery.com/modules/process" VERSION 2.0 FILE "process.xq") |
10 | 16 | 16 | ||
11 | === modified file 'src/com/zorba-xquery/www/modules/process.xq' | |||
12 | --- src/com/zorba-xquery/www/modules/process.xq 2012-12-06 02:13:28 +0000 | |||
13 | +++ src/com/zorba-xquery/www/modules/process.xq 2013-05-17 14:51:23 +0000 | |||
14 | @@ -28,14 +28,17 @@ | |||
15 | 28 | : | 28 | : |
16 | 29 | : Potential result: | 29 | : Potential result: |
17 | 30 | : <pre class="ace-static" ace-mode="xquery"><![CDATA[ | 30 | : <pre class="ace-static" ace-mode="xquery"><![CDATA[ |
23 | 31 | : <result xmlns="http://www.zorba-xquery.com/modules/process"> | 31 | : { |
24 | 32 | : <stdout>myfile.txt</stout> | 32 | : "exit-code": 0, |
25 | 33 | : <stderr/> | 33 | : "stdout": "myfile.txt", |
26 | 34 | : <exit-code>0</exit-code> | 34 | : "stderr": "" |
27 | 35 | : </result> | 35 | : } |
28 | 36 | : ]]></pre> | 36 | : ]]></pre> |
29 | 37 | : | 37 | : |
31 | 38 | : @author Cezar Andrei | 38 | : The exec-command() set of functions allows execution of commands through the operating |
32 | 39 | : system's command line interpreter, such as "sh" on Linux or "cmd.exe" on Windows. | ||
33 | 40 | : | ||
34 | 41 | : @author Cezar Andrei, Nicolae Brinza | ||
35 | 39 | : @project Zorba/IO/Process | 42 | : @project Zorba/IO/Process |
36 | 40 | : | 43 | : |
37 | 41 | :) | 44 | :) |
38 | @@ -44,7 +47,100 @@ | |||
39 | 44 | declare namespace an = "http://www.zorba-xquery.com/annotations"; | 47 | declare namespace an = "http://www.zorba-xquery.com/annotations"; |
40 | 45 | 48 | ||
41 | 46 | declare namespace ver = "http://www.zorba-xquery.com/options/versioning"; | 49 | declare namespace ver = "http://www.zorba-xquery.com/options/versioning"; |
43 | 47 | declare option ver:module-version "1.0"; | 50 | declare option ver:module-version "2.0"; |
44 | 51 | |||
45 | 52 | |||
46 | 53 | (:~ | ||
47 | 54 | : Executes the specified program in a separate process. | ||
48 | 55 | : This function does not allow arguments to be passed to | ||
49 | 56 | : the command. The $filename parameter can contain the full path to the | ||
50 | 57 | : executable. On Linux systems, if the specified filename does not contain | ||
51 | 58 | : a slash "/", the function duplicates the actions of the shell in searching | ||
52 | 59 | : for an executable file. The file is sought in the colon-separated list of | ||
53 | 60 | : directory pathnames specified in the PATH environment variable. If this | ||
54 | 61 | : variable isn't defined, the path list defaults to the current directory | ||
55 | 62 | : followed by the list of directories returned by the operating system. | ||
56 | 63 | : | ||
57 | 64 | : @param $filename the name of program to be executed | ||
58 | 65 | : | ||
59 | 66 | : @return the result of the execution as an object as | ||
60 | 67 | : shown in the documentation of this module. The exit-code | ||
61 | 68 | : returns the exit code of the child process. | ||
62 | 69 | : For POSIX compliant platforms: returns the program exit code. If the program is | ||
63 | 70 | : terminated or stopped: 128 + termination signal code. | ||
64 | 71 | : For Windows platforms: returns the return value of the program or the exit | ||
65 | 72 | : or terminate process specified value. | ||
66 | 73 | : | ||
67 | 74 | : @error process:PROC01 if an error occurred while communicating | ||
68 | 75 | : with the executed process. | ||
69 | 76 | :) | ||
70 | 77 | declare %an:sequential function process:exec( | ||
71 | 78 | $filename as xs:string | ||
72 | 79 | ) as object() external; | ||
73 | 80 | |||
74 | 81 | (:~ | ||
75 | 82 | : Executes the specified program in a separate process. | ||
76 | 83 | : The $filename parameter can contain the full path to the | ||
77 | 84 | : executable. On Linux systems, if the specified filename does not contain | ||
78 | 85 | : a slash "/", the function duplicates the actions of the shell in searching | ||
79 | 86 | : for an executable file. The file is sought in the colon-separated list of | ||
80 | 87 | : directory pathnames specified in the PATH environment variable. If this | ||
81 | 88 | : variable isn't defined, the path list defaults to the current directory | ||
82 | 89 | : followed by the list of directories returned by the operating system. | ||
83 | 90 | : The $args parameters will be passed to the executable file as arguments. | ||
84 | 91 | : | ||
85 | 92 | : @param $filename the name of program to be executed | ||
86 | 93 | : @param $args arguments to be passed to the executable | ||
87 | 94 | : | ||
88 | 95 | : @return the result of the execution as an object as | ||
89 | 96 | : shown in the documentation of this module. The exit-code | ||
90 | 97 | : returns the exit code of the child process. | ||
91 | 98 | : For POSIX compliant platforms: returns the program exit code. If the program is | ||
92 | 99 | : terminated or stopped: 128 + termination signal code. | ||
93 | 100 | : For Windows platforms: returns the return value of the program or the exit | ||
94 | 101 | : or terminate process specified value. | ||
95 | 102 | : | ||
96 | 103 | : @error process:PROC01 if an error occurred while communicating | ||
97 | 104 | : with the executed process. | ||
98 | 105 | :) | ||
99 | 106 | declare %an:sequential function process:exec( | ||
100 | 107 | $filename as xs:string, | ||
101 | 108 | $args as xs:string* | ||
102 | 109 | ) as object() external; | ||
103 | 110 | |||
104 | 111 | (:~ | ||
105 | 112 | : Executes the specified program in a separate process. | ||
106 | 113 | : The $filename parameter can contain the full path to the | ||
107 | 114 | : executable. On Linux systems, if the specified filename does not contain | ||
108 | 115 | : a slash "/", the function duplicates the actions of the shell in searching | ||
109 | 116 | : for an executable file. The file is sought in the colon-separated list of | ||
110 | 117 | : directory pathnames specified in the PATH environment variable. If this | ||
111 | 118 | : variable isn't defined, the path list defaults to the current directory | ||
112 | 119 | : followed by the list of directories returned by the operating system. | ||
113 | 120 | : The $args parameters will be passed to the executable file as arguments. | ||
114 | 121 | : The $env allows defining and passing environment variables to the target | ||
115 | 122 | : process. They should be in the form "ENVVAR=value" where "ENVVAR" is the | ||
116 | 123 | : name of the environment variable and "value' is the string value to set it to. | ||
117 | 124 | : | ||
118 | 125 | : @param $filename the name of program to be executed | ||
119 | 126 | : @param $args arguments to be passed to the executable | ||
120 | 127 | : | ||
121 | 128 | : @return the result of the execution as an object as | ||
122 | 129 | : shown in the documentation of this module. The exit-code | ||
123 | 130 | : returns the exit code of the child process. | ||
124 | 131 | : For POSIX compliant platforms: returns the program exit code. If the program is | ||
125 | 132 | : terminated or stopped: 128 + termination signal code. | ||
126 | 133 | : For Windows platforms: returns the return value of the program or the exit | ||
127 | 134 | : or terminate process specified value. | ||
128 | 135 | : | ||
129 | 136 | : @error process:PROC01 if an error occurred while communicating | ||
130 | 137 | : with the executed process. | ||
131 | 138 | :) | ||
132 | 139 | declare %an:sequential function process:exec( | ||
133 | 140 | $filename as xs:string, | ||
134 | 141 | $args as xs:string*, | ||
135 | 142 | $env as xs:string* | ||
136 | 143 | ) as object() external; | ||
137 | 48 | 144 | ||
138 | 49 | (:~ | 145 | (:~ |
139 | 50 | : Executes the specified string command in a separate process. | 146 | : Executes the specified string command in a separate process. |
140 | @@ -64,9 +160,9 @@ | |||
141 | 64 | : @error process:PROC01 if an error occurred while communicating | 160 | : @error process:PROC01 if an error occurred while communicating |
142 | 65 | : with the executed process. | 161 | : with the executed process. |
143 | 66 | :) | 162 | :) |
145 | 67 | declare %an:sequential function process:exec( | 163 | declare %an:sequential function process:exec-command( |
146 | 68 | $cmd as xs:string | 164 | $cmd as xs:string |
148 | 69 | ) as element(process:result) external; | 165 | ) as object() external; |
149 | 70 | 166 | ||
150 | 71 | (:~ | 167 | (:~ |
151 | 72 | : Executes the specified string command in a separate process. | 168 | : Executes the specified string command in a separate process. |
152 | @@ -87,7 +183,7 @@ | |||
153 | 87 | : @error process:PROC01 if an error occurred while communicating | 183 | : @error process:PROC01 if an error occurred while communicating |
154 | 88 | : with the executed process. | 184 | : with the executed process. |
155 | 89 | :) | 185 | :) |
157 | 90 | declare %an:sequential function process:exec( | 186 | declare %an:sequential function process:exec-command( |
158 | 91 | $cmd as xs:string, | 187 | $cmd as xs:string, |
159 | 92 | $args as xs:string* | 188 | $args as xs:string* |
161 | 93 | ) as element(process:result) external; | 189 | ) as object() external; |
162 | 94 | 190 | ||
163 | === modified file 'src/com/zorba-xquery/www/modules/process.xq.src/process.cpp' | |||
164 | --- src/com/zorba-xquery/www/modules/process.xq.src/process.cpp 2012-12-05 17:29:38 +0000 | |||
165 | +++ src/com/zorba-xquery/www/modules/process.xq.src/process.cpp 2013-05-17 14:51:23 +0000 | |||
166 | @@ -25,7 +25,6 @@ | |||
167 | 25 | 25 | ||
168 | 26 | #ifdef WIN32 | 26 | #ifdef WIN32 |
169 | 27 | # include <windows.h> | 27 | # include <windows.h> |
170 | 28 | |||
171 | 29 | # ifndef NDEBUG | 28 | # ifndef NDEBUG |
172 | 30 | # define _CRTDBG_MAP_ALLOC | 29 | # define _CRTDBG_MAP_ALLOC |
173 | 31 | # include <stdlib.h> | 30 | # include <stdlib.h> |
174 | @@ -49,6 +48,20 @@ | |||
175 | 49 | 48 | ||
176 | 50 | #include "process.h" | 49 | #include "process.h" |
177 | 51 | 50 | ||
178 | 51 | // Provde the execvpe() function since some platforms don't have it | ||
179 | 52 | #ifndef WIN32 | ||
180 | 53 | int execvpe(const char *program, char **argv, char **envp) | ||
181 | 54 | { | ||
182 | 55 | char **saved = environ; | ||
183 | 56 | int rc; | ||
184 | 57 | environ = envp; | ||
185 | 58 | rc = execvp(program, argv); | ||
186 | 59 | environ = saved; | ||
187 | 60 | return rc; | ||
188 | 61 | } | ||
189 | 62 | #endif | ||
190 | 63 | |||
191 | 64 | |||
192 | 52 | namespace zorba { | 65 | namespace zorba { |
193 | 53 | namespace processmodule { | 66 | namespace processmodule { |
194 | 54 | 67 | ||
195 | @@ -100,6 +113,28 @@ | |||
196 | 100 | aFactory->createTextNode(lExitCode, lExitCodeString.str()); | 113 | aFactory->createTextNode(lExitCode, lExitCodeString.str()); |
197 | 101 | } | 114 | } |
198 | 102 | 115 | ||
199 | 116 | void create_result_object( | ||
200 | 117 | zorba::Item& aResult, | ||
201 | 118 | const std::string& aStandardOut, | ||
202 | 119 | const std::string& aErrorOut, | ||
203 | 120 | int aExitCode, | ||
204 | 121 | zorba::ItemFactory* aFactory) | ||
205 | 122 | { | ||
206 | 123 | std::vector<std::pair<zorba::Item,zorba::Item> > pairs; | ||
207 | 124 | |||
208 | 125 | pairs.push_back(std::pair<zorba::Item,zorba::Item>(aFactory->createString("exit-code"), aFactory->createInt(aExitCode))); | ||
209 | 126 | pairs.push_back(std::pair<zorba::Item,zorba::Item>(aFactory->createString("stdout"), aFactory->createString(aStandardOut))); | ||
210 | 127 | pairs.push_back(std::pair<zorba::Item,zorba::Item>(aFactory->createString("stderr"), aFactory->createString(aErrorOut))); | ||
211 | 128 | |||
212 | 129 | aResult = aFactory->createJSONObject(pairs); | ||
213 | 130 | } | ||
214 | 131 | |||
215 | 132 | void free_char_vector(std::vector<char*> argv) | ||
216 | 133 | { | ||
217 | 134 | for (unsigned int i=0; i<argv.size(); i++) | ||
218 | 135 | free(argv[i]); | ||
219 | 136 | } | ||
220 | 137 | |||
221 | 103 | #ifdef WIN32 | 138 | #ifdef WIN32 |
222 | 104 | 139 | ||
223 | 105 | /*********************************************** | 140 | /*********************************************** |
224 | @@ -307,7 +342,7 @@ | |||
225 | 307 | #define READ 0 | 342 | #define READ 0 |
226 | 308 | #define WRITE 1 | 343 | #define WRITE 1 |
227 | 309 | 344 | ||
229 | 310 | pid_t zorba_popen(const char *command, int *infp, int *outfp, int *errfp) | 345 | pid_t exec_helper(int *infp, int *outfp, int *errfp, const char *command, char* argv[], char* env[]) |
230 | 311 | { | 346 | { |
231 | 312 | int p_stdin[2]; | 347 | int p_stdin[2]; |
232 | 313 | int p_stdout[2]; | 348 | int p_stdout[2]; |
233 | @@ -332,7 +367,13 @@ | |||
234 | 332 | close(p_stderr[READ]); | 367 | close(p_stderr[READ]); |
235 | 333 | dup2(p_stderr[WRITE], 2); // duplicate stderr | 368 | dup2(p_stderr[WRITE], 2); // duplicate stderr |
236 | 334 | 369 | ||
238 | 335 | execl("/bin/sh", "sh", "-c", command, NULL); | 370 | if (command) |
239 | 371 | execl("/bin/sh", "sh", "-c", command, NULL); | ||
240 | 372 | else if (env == NULL) | ||
241 | 373 | execvp(argv[0], argv); | ||
242 | 374 | else | ||
243 | 375 | execvpe(argv[0], argv, env); | ||
244 | 376 | |||
245 | 336 | perror("execl"); // output the result to standard error | 377 | perror("execl"); // output the result to standard error |
246 | 337 | exit(errno); | 378 | exit(errno); |
247 | 338 | } | 379 | } |
248 | @@ -358,10 +399,23 @@ | |||
249 | 358 | 399 | ||
250 | 359 | return pid; | 400 | return pid; |
251 | 360 | } | 401 | } |
252 | 402 | |||
253 | 361 | #endif | 403 | #endif |
254 | 362 | 404 | ||
255 | 405 | |||
256 | 363 | /****************************************************************************** | 406 | /****************************************************************************** |
257 | 364 | *****************************************************************************/ | 407 | *****************************************************************************/ |
258 | 408 | String ExecFunction::getOneStringArgument (const Arguments_t& aArgs, int aPos) const | ||
259 | 409 | { | ||
260 | 410 | Item lItem; | ||
261 | 411 | Iterator_t args_iter = aArgs[aPos]->getIterator(); | ||
262 | 412 | args_iter->open(); | ||
263 | 413 | args_iter->next(lItem); | ||
264 | 414 | zorba::String lTmpString = lItem.getStringValue(); | ||
265 | 415 | args_iter->close(); | ||
266 | 416 | return lTmpString; | ||
267 | 417 | } | ||
268 | 418 | |||
269 | 365 | zorba::ItemSequence_t | 419 | zorba::ItemSequence_t |
270 | 366 | ExecFunction::evaluate( | 420 | ExecFunction::evaluate( |
271 | 367 | const Arguments_t& aArgs, | 421 | const Arguments_t& aArgs, |
272 | @@ -370,6 +424,7 @@ | |||
273 | 370 | { | 424 | { |
274 | 371 | std::string lCommand; | 425 | std::string lCommand; |
275 | 372 | std::vector<std::string> lArgs; | 426 | std::vector<std::string> lArgs; |
276 | 427 | std::vector<std::string> lEnv; | ||
277 | 373 | int exit_code = 0; | 428 | int exit_code = 0; |
278 | 374 | 429 | ||
279 | 375 | lCommand = getOneStringArgument(aArgs, 0).c_str(); | 430 | lCommand = getOneStringArgument(aArgs, 0).c_str(); |
280 | @@ -379,12 +434,20 @@ | |||
281 | 379 | zorba::Item lArg; | 434 | zorba::Item lArg; |
282 | 380 | Iterator_t arg1_iter = aArgs[1]->getIterator(); | 435 | Iterator_t arg1_iter = aArgs[1]->getIterator(); |
283 | 381 | arg1_iter->open(); | 436 | arg1_iter->open(); |
286 | 382 | while (arg1_iter->next(lArg)) | 437 | while (arg1_iter->next(lArg)) |
285 | 383 | { | ||
287 | 384 | lArgs.push_back(lArg.getStringValue().c_str()); | 438 | lArgs.push_back(lArg.getStringValue().c_str()); |
288 | 385 | } | ||
289 | 386 | arg1_iter->close(); | 439 | arg1_iter->close(); |
290 | 387 | } | 440 | } |
291 | 441 | |||
292 | 442 | if (aArgs.size() > 2) | ||
293 | 443 | { | ||
294 | 444 | zorba::Item lArg; | ||
295 | 445 | Iterator_t arg1_iter = aArgs[2]->getIterator(); | ||
296 | 446 | arg1_iter->open(); | ||
297 | 447 | while (arg1_iter->next(lArg)) | ||
298 | 448 | lEnv.push_back(lArg.getStringValue().c_str()); | ||
299 | 449 | arg1_iter->close(); | ||
300 | 450 | } | ||
301 | 388 | 451 | ||
302 | 389 | std::ostringstream lTmp; | 452 | std::ostringstream lTmp; |
303 | 390 | 453 | ||
304 | @@ -432,18 +495,38 @@ | |||
305 | 432 | int errfp; | 495 | int errfp; |
306 | 433 | int status; | 496 | int status; |
307 | 434 | pid_t pid; | 497 | pid_t pid; |
308 | 498 | |||
309 | 499 | std::vector<char*> argv(lArgs.size()+2, NULL); | ||
310 | 500 | std::vector<char*> env(lEnv.size()+1, NULL); | ||
311 | 435 | 501 | ||
323 | 436 | pid = zorba_popen(lTmp.str().c_str(), NULL, &outfp, &errfp); | 502 | try |
324 | 437 | if ( pid == -1 ) | 503 | { |
325 | 438 | { | 504 | if (theIsExecProgram) |
326 | 439 | std::stringstream lErrorMsg; | 505 | { |
327 | 440 | lErrorMsg << "Failed to execute the command (" << pid << ")"; | 506 | argv[0] = strdup(lCommand.c_str()); |
328 | 441 | Item lQName = ProcessModule::getItemFactory()->createQName( | 507 | for (unsigned int i=0; i<lArgs.size(); i++) |
329 | 442 | "http://www.zorba-xquery.com/modules/process", "PROC01"); | 508 | argv[i+1] = strdup(lArgs[i].c_str()); |
330 | 443 | throw USER_EXCEPTION(lQName, lErrorMsg.str().c_str()); | 509 | |
331 | 444 | } | 510 | for (unsigned int i=0; i<lEnv.size(); i++) |
332 | 445 | else | 511 | env[i] = strdup(lEnv[i].c_str()); |
333 | 446 | { | 512 | |
334 | 513 | pid = exec_helper(NULL, &outfp, &errfp, NULL, argv.data(), lEnv.size() ? env.data() : NULL); | ||
335 | 514 | } | ||
336 | 515 | else | ||
337 | 516 | { | ||
338 | 517 | pid = exec_helper(NULL, &outfp, &errfp, lTmp.str().c_str(), argv.data(), NULL); | ||
339 | 518 | } | ||
340 | 519 | |||
341 | 520 | if ( pid == -1 ) | ||
342 | 521 | { | ||
343 | 522 | std::stringstream lErrorMsg; | ||
344 | 523 | lErrorMsg << "Failed to execute the command (" << pid << ")"; | ||
345 | 524 | Item lQName = ProcessModule::getItemFactory()->createQName( | ||
346 | 525 | "http://www.zorba-xquery.com/modules/process", "PROC01"); | ||
347 | 526 | throw USER_EXCEPTION(lQName, lErrorMsg.str().c_str()); | ||
348 | 527 | return NULL; | ||
349 | 528 | } | ||
350 | 529 | |||
351 | 447 | char lBuf[PATH_MAX]; | 530 | char lBuf[PATH_MAX]; |
352 | 448 | ssize_t length = 0; | 531 | ssize_t length = 0; |
353 | 449 | while ( (length=read(outfp, lBuf, PATH_MAX)) > 0 ) | 532 | while ( (length=read(outfp, lBuf, PATH_MAX)) > 0 ) |
354 | @@ -504,28 +587,23 @@ | |||
355 | 504 | } | 587 | } |
356 | 505 | 588 | ||
357 | 506 | //std::cout << " exit_code : " << exit_code << std::endl; std::cout.flush(); | 589 | //std::cout << " exit_code : " << exit_code << std::endl; std::cout.flush(); |
359 | 507 | 590 | free_char_vector(argv); | |
360 | 591 | free_char_vector(env); | ||
361 | 592 | } | ||
362 | 593 | catch (...) | ||
363 | 594 | { | ||
364 | 595 | free_char_vector(argv); | ||
365 | 596 | free_char_vector(env); | ||
366 | 597 | throw; | ||
367 | 508 | } | 598 | } |
368 | 509 | #endif // WIN32 | 599 | #endif // WIN32 |
369 | 510 | 600 | ||
370 | 511 | zorba::Item lResult; | 601 | zorba::Item lResult; |
374 | 512 | create_result_node(lResult, lStdout.str(), lStderr.str(), exit_code, | 602 | create_result_object(lResult, lStdout.str(), lStderr.str(), exit_code, |
375 | 513 | theModule->getItemFactory()); | 603 | theModule->getItemFactory()); |
373 | 514 | |||
376 | 515 | return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lResult)); | 604 | return zorba::ItemSequence_t(new zorba::SingletonItemSequence(lResult)); |
377 | 516 | } | 605 | } |
378 | 517 | 606 | ||
379 | 518 | String ExecFunction::getOneStringArgument (const Arguments_t& aArgs, int aPos) | ||
380 | 519 | const | ||
381 | 520 | { | ||
382 | 521 | Item lItem; | ||
383 | 522 | Iterator_t args_iter = aArgs[aPos]->getIterator(); | ||
384 | 523 | args_iter->open(); | ||
385 | 524 | args_iter->next(lItem); | ||
386 | 525 | zorba::String lTmpString = lItem.getStringValue(); | ||
387 | 526 | args_iter->close(); | ||
388 | 527 | return lTmpString; | ||
389 | 528 | } | ||
390 | 529 | 607 | ||
391 | 530 | /****************************************************************************** | 608 | /****************************************************************************** |
392 | 531 | *****************************************************************************/ | 609 | *****************************************************************************/ |
393 | @@ -545,10 +623,14 @@ | |||
394 | 545 | zorba::ExternalFunction*& lFunc = theFunctions[aLocalname]; | 623 | zorba::ExternalFunction*& lFunc = theFunctions[aLocalname]; |
395 | 546 | if (lFind == theFunctions.end()) | 624 | if (lFind == theFunctions.end()) |
396 | 547 | { | 625 | { |
398 | 548 | if (!aLocalname.compare("exec")) | 626 | if (aLocalname.compare("exec-command") == 0) |
399 | 549 | { | 627 | { |
400 | 550 | lFunc = new ExecFunction(this); | 628 | lFunc = new ExecFunction(this); |
401 | 551 | } | 629 | } |
402 | 630 | else if (aLocalname.compare("exec") == 0) | ||
403 | 631 | { | ||
404 | 632 | lFunc = new ExecFunction(this, true); | ||
405 | 633 | } | ||
406 | 552 | } | 634 | } |
407 | 553 | return lFunc; | 635 | return lFunc; |
408 | 554 | } | 636 | } |
409 | 555 | 637 | ||
410 | === modified file 'src/com/zorba-xquery/www/modules/process.xq.src/process.h' | |||
411 | --- src/com/zorba-xquery/www/modules/process.xq.src/process.h 2012-07-21 01:09:37 +0000 | |||
412 | +++ src/com/zorba-xquery/www/modules/process.xq.src/process.h 2013-05-17 14:51:23 +0000 | |||
413 | @@ -74,12 +74,13 @@ | |||
414 | 74 | class ExecFunction : public ContextualExternalFunction | 74 | class ExecFunction : public ContextualExternalFunction |
415 | 75 | { | 75 | { |
416 | 76 | public: | 76 | public: |
418 | 77 | ExecFunction(const ProcessModule* aModule) : theModule(aModule) {} | 77 | ExecFunction(const ProcessModule* aModule, bool aExecProgram = false) |
419 | 78 | : theModule(aModule), theIsExecProgram(aExecProgram) {} | ||
420 | 78 | 79 | ||
421 | 79 | virtual ~ExecFunction() {} | 80 | virtual ~ExecFunction() {} |
422 | 80 | 81 | ||
423 | 81 | virtual zorba::String | 82 | virtual zorba::String |
425 | 82 | getLocalName() const { return "exec"; } | 83 | getLocalName() const { if (theIsExecProgram) return "exec"; else return "exec-command"; } |
426 | 83 | 84 | ||
427 | 84 | virtual zorba::ItemSequence_t | 85 | virtual zorba::ItemSequence_t |
428 | 85 | evaluate(const Arguments_t&, | 86 | evaluate(const Arguments_t&, |
429 | @@ -93,12 +94,14 @@ | |||
430 | 93 | 94 | ||
431 | 94 | protected: | 95 | protected: |
432 | 95 | const ProcessModule* theModule; | 96 | const ProcessModule* theModule; |
433 | 97 | |||
434 | 98 | bool theIsExecProgram; // if set to true, will use the execvpe() version of the system function | ||
435 | 99 | // if set to false, will build a command string and pass it to | ||
436 | 100 | // either "bash" or "cmd.exe" (through execl() on Linux) | ||
437 | 96 | 101 | ||
438 | 97 | String getOneStringArgument (const Arguments_t& aArgs, int index) const; | 102 | String getOneStringArgument (const Arguments_t& aArgs, int index) const; |
439 | 98 | }; | 103 | }; |
440 | 99 | 104 | ||
441 | 100 | |||
442 | 101 | |||
443 | 102 | } /* namespace processmodule */ | 105 | } /* namespace processmodule */ |
444 | 103 | } /* namespace zorba */ | 106 | } /* namespace zorba */ |
445 | 104 | 107 | ||
446 | 105 | 108 | ||
447 | === added file 'test/ExpQueryResults/process2-01.xml.res' | |||
448 | --- test/ExpQueryResults/process2-01.xml.res 1970-01-01 00:00:00 +0000 | |||
449 | +++ test/ExpQueryResults/process2-01.xml.res 2013-05-17 14:51:23 +0000 | |||
450 | @@ -0,0 +1,1 @@ | |||
451 | 1 | true | ||
452 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
453 | 1 | 3 | ||
454 | === added file 'test/ExpQueryResults/process2-02.xml.res' | |||
455 | --- test/ExpQueryResults/process2-02.xml.res 1970-01-01 00:00:00 +0000 | |||
456 | +++ test/ExpQueryResults/process2-02.xml.res 2013-05-17 14:51:23 +0000 | |||
457 | @@ -0,0 +1,1 @@ | |||
458 | 1 | true | ||
459 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
460 | 1 | 3 | ||
461 | === added file 'test/ExpQueryResults/process2-03.xml.res' | |||
462 | --- test/ExpQueryResults/process2-03.xml.res 1970-01-01 00:00:00 +0000 | |||
463 | +++ test/ExpQueryResults/process2-03.xml.res 2013-05-17 14:51:23 +0000 | |||
464 | @@ -0,0 +1,1 @@ | |||
465 | 1 | true | ||
466 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
467 | 1 | 3 | ||
468 | === added file 'test/ExpQueryResults/process2-04.xml.res' | |||
469 | --- test/ExpQueryResults/process2-04.xml.res 1970-01-01 00:00:00 +0000 | |||
470 | +++ test/ExpQueryResults/process2-04.xml.res 2013-05-17 14:51:23 +0000 | |||
471 | @@ -0,0 +1,1 @@ | |||
472 | 1 | true | ||
473 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
474 | 1 | 3 | ||
475 | === added file 'test/ExpQueryResults/process2-05.xml.res' | |||
476 | --- test/ExpQueryResults/process2-05.xml.res 1970-01-01 00:00:00 +0000 | |||
477 | +++ test/ExpQueryResults/process2-05.xml.res 2013-05-17 14:51:23 +0000 | |||
478 | @@ -0,0 +1,1 @@ | |||
479 | 1 | true | ||
480 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
481 | 1 | 3 | ||
482 | === added file 'test/ExpQueryResults/process2-06.xml.res' | |||
483 | --- test/ExpQueryResults/process2-06.xml.res 1970-01-01 00:00:00 +0000 | |||
484 | +++ test/ExpQueryResults/process2-06.xml.res 2013-05-17 14:51:23 +0000 | |||
485 | @@ -0,0 +1,1 @@ | |||
486 | 1 | true | ||
487 | 0 | \ No newline at end of file | 2 | \ No newline at end of file |
488 | 1 | 3 | ||
489 | === modified file 'test/Queries/process.xq' | |||
490 | --- test/Queries/process.xq 2011-08-13 00:08:53 +0000 | |||
491 | +++ test/Queries/process.xq 2013-05-17 14:51:23 +0000 | |||
492 | @@ -2,22 +2,22 @@ | |||
493 | 2 | 2 | ||
494 | 3 | 3 | ||
495 | 4 | { | 4 | { |
500 | 5 | variable $stdOutTest := proc:exec("echo","hello world") ; | 5 | variable $stdOutTest := proc:exec-command("echo","hello world") ; |
501 | 6 | variable $stdErrTest := proc:exec("echo","Ooops. an error. 1>&2"); | 6 | variable $stdErrTest := proc:exec-command("echo","Ooops. an error. 1>&2"); |
502 | 7 | variable $stdOutWinTest := proc:exec("cmd", ("/c", "echo","hello world")) ; | 7 | variable $stdOutWinTest := proc:exec-command("cmd", ("/c", "echo","hello world")) ; |
503 | 8 | variable $stdErrWinTest := proc:exec("cmd", ("/c", "echo","Ooops. an error. 1>&2")); | 8 | variable $stdErrWinTest := proc:exec-command("cmd", ("/c", "echo","Ooops. an error. 1>&2")); |
504 | 9 | 9 | ||
505 | 10 | let $result := | 10 | let $result := |
506 | 11 | <result> | 11 | <result> |
509 | 12 | <out>{normalize-space(data($stdOutTest/proc:stdout))}</out> | 12 | <out>{normalize-space(data($stdOutTest("stdout")))}</out> |
510 | 13 | <err>{normalize-space(data($stdErrTest/proc:stderr))}</err> | 13 | <err>{normalize-space(data($stdErrTest("stderr")))}</err> |
511 | 14 | </result> | 14 | </result> |
512 | 15 | return | 15 | return |
513 | 16 | if (contains($result/err/text(),"is not recognized as an internal or external command")) | 16 | if (contains($result/err/text(),"is not recognized as an internal or external command")) |
514 | 17 | then | 17 | then |
515 | 18 | <result> | 18 | <result> |
518 | 19 | <out>{normalize-space(data($stdOutWinTest/proc:stdout))}</out> | 19 | <out>{normalize-space(data($stdOutWinTest("stdout")))}</out> |
519 | 20 | <err>{normalize-space(data($stdErrWinTest/proc:stderr))}</err> | 20 | <err>{normalize-space(data($stdErrWinTest("stderr")))}</err> |
520 | 21 | </result> | 21 | </result> |
521 | 22 | else | 22 | else |
522 | 23 | $result | 23 | $result |
523 | 24 | 24 | ||
524 | === added file 'test/Queries/process2-01.xq' | |||
525 | --- test/Queries/process2-01.xq 1970-01-01 00:00:00 +0000 | |||
526 | +++ test/Queries/process2-01.xq 2013-05-17 14:51:23 +0000 | |||
527 | @@ -0,0 +1,5 @@ | |||
528 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
529 | 2 | |||
530 | 3 | let $result := proc:exec("echo") | ||
531 | 4 | return $result("stdout") eq " | ||
532 | 5 | " | ||
533 | 0 | 6 | ||
534 | === added file 'test/Queries/process2-02.xq' | |||
535 | --- test/Queries/process2-02.xq 1970-01-01 00:00:00 +0000 | |||
536 | +++ test/Queries/process2-02.xq 2013-05-17 14:51:23 +0000 | |||
537 | @@ -0,0 +1,5 @@ | |||
538 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
539 | 2 | |||
540 | 3 | let $result := proc:exec("echo",("hello","world")) | ||
541 | 4 | return $result("stdout") eq "hello world | ||
542 | 5 | " | ||
543 | 0 | 6 | ||
544 | === added file 'test/Queries/process2-03.xq' | |||
545 | --- test/Queries/process2-03.xq 1970-01-01 00:00:00 +0000 | |||
546 | +++ test/Queries/process2-03.xq 2013-05-17 14:51:23 +0000 | |||
547 | @@ -0,0 +1,5 @@ | |||
548 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
549 | 2 | |||
550 | 3 | let $result := proc:exec("printenv",("TEST_ENV_VAR"),"TEST_ENV_VAR=foo") | ||
551 | 4 | return $result("stdout") eq "foo | ||
552 | 5 | " | ||
553 | 0 | 6 | ||
554 | === added file 'test/Queries/process2-04.xq' | |||
555 | --- test/Queries/process2-04.xq 1970-01-01 00:00:00 +0000 | |||
556 | +++ test/Queries/process2-04.xq 2013-05-17 14:51:23 +0000 | |||
557 | @@ -0,0 +1,6 @@ | |||
558 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
559 | 2 | |||
560 | 3 | let $result := proc:exec("printenv",("TEST_ENV_VAR","VAR2"),("TEST_ENV_VAR=foo","VAR2=bar")) | ||
561 | 4 | return $result("stdout") eq "foo | ||
562 | 5 | bar | ||
563 | 6 | " | ||
564 | 0 | 7 | ||
565 | === added file 'test/Queries/process2-05.xq' | |||
566 | --- test/Queries/process2-05.xq 1970-01-01 00:00:00 +0000 | |||
567 | +++ test/Queries/process2-05.xq 2013-05-17 14:51:23 +0000 | |||
568 | @@ -0,0 +1,5 @@ | |||
569 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
570 | 2 | |||
571 | 3 | let $result := proc:exec("echo","{}[]()()''~!@#$%^&*_-+|<>/?,.") | ||
572 | 4 | return $result("stdout") eq "{}[]()()''~!@#$%^&*_-+|<>/?,. | ||
573 | 5 | " | ||
574 | 0 | 6 | ||
575 | === added file 'test/Queries/process2-06.xq' | |||
576 | --- test/Queries/process2-06.xq 1970-01-01 00:00:00 +0000 | |||
577 | +++ test/Queries/process2-06.xq 2013-05-17 14:51:23 +0000 | |||
578 | @@ -0,0 +1,4 @@ | |||
579 | 1 | import module namespace proc = "http://www.zorba-xquery.com/modules/process"; | ||
580 | 2 | |||
581 | 3 | let $result := proc:exec("this_executable_does_not_exist") | ||
582 | 4 | return $result("exit-code") ne 0 |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ process- 2-2013- 05-17T12- 29-40.913Z/ log.html
Log at: http://