cf79702cc6c2779531feb5d46477688e57562310
[deliverable/titan.core.git] / regression_test / XML / XmlWorkflow / PIPEasp_CNL113334 / test / PIPEasp_PT.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Lovassy, Arpad
11 * Raduly, Csaba
12 *
13 ******************************************************************************/
14 /*******************************************************************************
15 * Contributors:
16 * Zoltan Janos Szabo (Ericsson) - initial architecture design and implementation
17 * Roland Gecse (Ericsson) - initial architecture design
18 * Akos Cserveni (Ericsson) - Basic AST in compiler, semantic checking
19 * Gabor Szalai (Ericsson) - RAW and TEXT codecs
20 * Matyas Forstner (Ericsson) - ASN.1 extension of the compiler and BER/CER/DER codecs
21 * Kristof Szabados (Ericsson) - Eclipse Designer, Executor, Titanium UIs
22 * Szabolcs Beres (Ericsson) - Eclipse LogViewer
23 * Ferenc Kovacs (Ericsson) - log interfaces, big number support, subtype checking
24 * Csaba Raduly (Ericsson) - ASN.1 additions, XML encoder/decoder
25 * Adam Delic (Ericsson) - template restrictions, try&catch, support of pre-processor directives in Eclipse
26 * Krisztian Pandi (Ericsson) - import of imports
27 * Peter Dimitrov (Ericsson)- maintenance
28 * Balazs Andor Zalanyi (Ericsson) - code splitting
29 * Gabor Szalai (Ericsson) - RAW encoding/decoding
30 * Jeno Attila Balasko (Ericsson) - tests, maintenance
31 * Csaba Feher (Ericsson) - epoll support
32 * Tamas Buti (Ericsson)- maintenance
33 * Matyas Ormandi (Ericsson) - maintenance
34 * Botond Baranyi (Ericsson) - JSON encoder
35 * Arpad Lovassy (Ericsson) - Java Executor API
36 * Laszlo Baji (Ericsson) - maintenance
37 * Marton Godar (Ericsson) - xsd2ttcn converter
38 *******************************************************************************/
39 //
40 // File: PIPEasp_PT.cc
41 // Description: Source code of PIPE testport implementation
42 // Rev: <RnXnn>
43 // Prodnr: CNL 113 334
44 // Updated: 2008-06-03
45 // Contact: http://ttcn.ericsson.se
46 //
47
48
49 #include "PIPEasp_PT.hh"
50 #include <signal.h> //kill
51 #include <unistd.h> //pipe
52 #include <errno.h> //errno
53 #include <ctype.h> //isspace
54 #include <sys/select.h> //FD_ZERO
55 #include <stdio.h> // sys_errlist
56 #include <sys/types.h> //wait
57 #include <sys/wait.h> //wait
58
59 #ifndef PIPE_BUF_SIZE
60 #define PIPE_BUF_SIZE 655536
61 #endif
62
63 namespace PIPEasp__PortType {
64
65 PIPEasp__PT::PIPEasp__PT(const char *par_port_name)
66 : PIPEasp__PT_BASE(par_port_name)
67 , lineMode(true)
68 , processExecuting(false)
69 , binaryMode(false)
70 , disableSend(false)
71 , processPid(-1) // pid of the process currently executing
72 , processStdin(-1) // fd of stdin of the process
73 , processStdout(-1) // fd of stdout of the process
74 , processStderr(-1) // fd of stderr of the process
75 , processExitCode(0) // exit code of the process
76 {
77 FD_ZERO(&readfds);
78 stdout_buffer.clear();
79 stderr_buffer.clear();
80 }
81
82 PIPEasp__PT::~PIPEasp__PT()
83 {
84 // nothing to do
85 }
86
87 void PIPEasp__PT::set_parameter(const char *parameter_name,
88 const char *parameter_value)
89 {
90 // no config parameters
91 }
92
93 void PIPEasp__PT::Event_Handler(const fd_set *read_fds,
94 const fd_set *write_fds, const fd_set *error_fds,
95 double time_since_last_call)
96 {
97 log("PIPEasp__PT::Event_Handler called");
98 if (processStdout != -1 && FD_ISSET(processStdout, read_fds)) {
99 if (!processExecuting) {
100 TTCN_warning("Unexpected message from stdout, no command is executing");
101 } else {
102 log("Incoming stdout message received from process");
103 }
104
105 long nBytes;
106 int r;
107
108 nBytes = PIPE_BUF_SIZE;
109 unsigned char* buffer;
110 size_t end_len = nBytes;
111 stdout_buffer.get_end(buffer, end_len);
112 r = read(processStdout,buffer,(int)nBytes);
113 if (r <= 0) {
114 log("ttcn_pipe_port: read problem on stdout.\n");
115 // close the pipe and remove it from event handler
116 close(processStdout);
117 FD_CLR(processStdout, &readfds);
118 Install_Handler(&readfds, NULL, NULL, 0.0);
119 processStdout = -1;
120
121 // check if stderr is closed:
122 if (processStderr == -1) {
123 // child died
124 log("Child might have died.");
125 handle_childDeath();
126 }
127 }
128 else {
129 log("incoming stdout %ld bytes\n", r);
130 stdout_buffer.increase_length(r);
131 sendStdout();
132 }
133 return;
134 }
135 if (processStderr != -1 && FD_ISSET(processStderr, read_fds)) {
136 if (!processExecuting) {
137 TTCN_warning("Unexpected message from stderr, no command is executing");
138 } else {
139 log("Incoming stderr message received from process");
140 }
141
142 long nBytes;
143 int r;
144
145 nBytes = PIPE_BUF_SIZE;
146 unsigned char* buffer;
147 size_t end_len = nBytes;
148 stderr_buffer.get_end(buffer, end_len);
149 r = read(processStderr,buffer,(int)nBytes);
150 if (r <= 0) {
151 log("ttcn_pipe_port: read problem on stderr.\n");
152 // close the pipe and remove it from event handler
153 close(processStderr);
154 FD_CLR(processStderr, &readfds);
155 Install_Handler(&readfds, NULL, NULL, 0.0);
156 processStderr = -1;
157
158 // check if stdout is closed:
159 if (processStdout == -1) {
160 // child died
161 log("Child might have died.");
162 handle_childDeath();
163 }
164 }
165 else {
166 log("incoming stderr %ld bytes\n", r);
167 stderr_buffer.increase_length(r);
168 sendStderr();
169 }
170 return;
171 }
172 }
173
174 void PIPEasp__PT::user_map(const char *system_port)
175 {
176 // nothing to do
177 }
178
179 void PIPEasp__PT::user_unmap(const char *system_port)
180 {
181 // nothing to do
182 }
183
184 void PIPEasp__PT::user_start()
185 {
186 // nothing to do
187 }
188
189 void PIPEasp__PT::user_stop()
190 {
191 // nothing to do
192 }
193
194 /*************************************
195 * Specific outgoing_send functions
196 *************************************/
197 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecute& send_par) {
198 log("PIPEasp__PT::outgoing_send_PExecute called");
199 // disable sendStdout, sendStderr until process exits
200 if (processExecuting) {
201 sendError("Pipe Test Port: Command already executing");
202 TTCN_Logger::begin_event(TTCN_DEBUG);
203 TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name());
204 send_par.log();
205 TTCN_Logger::end_event();
206 return;
207 }
208 PIPEasp__Types::ASP__PExecuteBackground message_PExecuteBackground;
209 // starting command
210 message_PExecuteBackground.command() = send_par.command();
211 outgoing_send(message_PExecuteBackground);
212 // sending input
213 PIPEasp__Types::ASP__PStdin message_PStdin;
214 message_PStdin.stdin_() = send_par.stdin_();
215 outgoing_send(message_PStdin);
216 disableSend = true;
217
218 // closing stdin pipe:
219 outgoing_send(PIPEasp__Types::ASP__PEndOfInput());
220
221 log("PIPEasp__PT::outgoing_send_PExecute exited");
222 }
223
224 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecuteBinary& send_par) {
225 log("PIPEasp__PT::outgoing_send_PExecuteBinary called");
226 // disable sendStdout, sendStderr until process exits
227 if (processExecuting) {
228 sendError("Pipe Test Port: Command already executing");
229 TTCN_Logger::begin_event(TTCN_DEBUG);
230 TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name());
231 send_par.log();
232 TTCN_Logger::end_event();
233 return;
234 }
235 PIPEasp__Types::ASP__PExecuteBackground message_PExecuteBackground;
236 // starting command
237 message_PExecuteBackground.command() = send_par.command();
238 outgoing_send(message_PExecuteBackground);
239 // sending input
240 PIPEasp__Types::ASP__PStdinBinary message_PStdinBinary;
241 message_PStdinBinary.stdin_() = send_par.stdin_();
242 outgoing_send(message_PStdinBinary);
243 disableSend = true;
244
245 // closing stdin pipe:
246 outgoing_send(PIPEasp__Types::ASP__PEndOfInput());
247
248 log("PIPEasp__PT::outgoing_send_PExecuteBinary exited");
249 }
250
251 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecuteBackground& send_par) {
252 log("PIPEasp__PT::outgoing_send_PExecuteBackground called");
253
254 if (processExecuting) {
255 log("Process already executing. Cannot start new process.");
256 sendError("Pipe Test Port: Command already executing");
257 TTCN_Logger::begin_event(TTCN_DEBUG);
258 TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name());
259 send_par.log();
260 TTCN_Logger::end_event();
261 log("PIPEasp__PT::outgoing_send_PExecuteBackground exited");
262 return;
263 }
264
265 // creating pipes for process
266 int pipesStdin[2];
267 int pipesStdout[2];
268 int pipesStderr[2];
269
270 if (pipe(pipesStdin) != 0) {
271 sendError("Pipe Test Port: Cannot create stdin pipe");
272 log("PIPEasp__PT::outgoing_send_PExecuteBackground exited");
273 return;
274 }
275 if (pipe(pipesStdout) != 0) {
276 sendError("Pipe Test Port: Cannot create stdout pipe");
277 log("PIPEasp__PT::outgoing_send_PExecuteBackground exited");
278 return;
279 }
280 if (pipe(pipesStderr) != 0) {
281 sendError("Pipe Test Port: Cannot create stderr pipe");
282 log("PIPEasp__PT::outgoing_send_PExecuteBackground exited");
283 return;
284 }
285
286 processStdin = pipesStdin[1];
287 processStdout = pipesStdout[0];
288 processStderr = pipesStderr[0];
289
290 processPid = fork();
291 if (processPid < 0) {
292 //
293 // Error
294 //
295
296 // close the pipes
297 close(pipesStdin[0]);
298 close(pipesStdout[1]);
299 close(pipesStderr[1]);
300
301 close(processStdin);
302 close(processStdout);
303 close(processStderr);
304
305 sendError("Pipe Test Port: Cannot fork");
306 }
307 else if (processPid == 0) {
308
309 //
310 // Child process
311 //
312
313 // close the parent end of the pipes
314 close(processStdin);
315 close(processStdout);
316 close(processStderr);
317
318 /*// set these to the other end of the pipe
319 processStdin = pipesStdin[0];
320 processStdout = pipesStdout[1];
321 processStderr = pipesStderr[1];*/
322
323 int r;
324 // redirect pipeStdin to stdin
325 r = dup2(pipesStdin[0], 0);
326 if (r<0) {
327 TTCN_error("Cannot redirect stdin");
328 exit(errno);
329 }
330
331 // redirect pipeStdout to stdout
332 r = dup2(pipesStdout[1], 1);
333 if (r<0) {
334 TTCN_error("Cannot redirect stdout");
335 exit(errno);
336 }
337
338 // redirect pipeStderr to stderr
339 r = dup2(pipesStderr[1], 2);
340 if (r<0) {
341 TTCN_error("Cannot redirect stderr");
342 exit(errno);
343 }
344
345 processExitCode = execCommand((const char*)send_par.command());
346
347 // There is a problem executing the command
348 // Exiting...
349
350 fflush(stdout);
351 fflush(stderr);
352
353 //closing pipes:
354 close(pipesStdin[0]);
355 close(pipesStdout[1]);
356 close(pipesStderr[1]);
357
358 exit(processExitCode); // end of child process
359 }
360 else {
361
362 //
363 // Parent process
364 //
365
366 log("Process started with pid: %d", processPid);
367 // close child end of the pipes
368 close(pipesStdin[0]);
369 close(pipesStdout[1]);
370 close(pipesStderr[1]);
371
372
373 processExecuting = true;
374
375 // install handler for the process pipes:
376 //FD_SET(processStdin, &readfds);
377 FD_SET(processStdout, &readfds);
378 FD_SET(processStderr, &readfds);
379
380 Install_Handler(&readfds, NULL, NULL, 0.0);
381 }
382
383 log("PIPEasp__PT::outgoing_send_PExecuteBackground exited");
384 }
385
386 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PStdin& send_par) {
387
388 log("PIPEasp__PT::outgoing_send_PStdin called");
389 binaryMode = false;
390 if (!processExecuting) {
391 sendError("Pipe Test Port: No command executing");
392 return;
393 }
394 if (disableSend) { // process was started with PExecute(Binary)
395 sendError("Pipe Test Port: PStdin is not sent: current process is not started with PExecuteBackground!");
396 return;
397 }
398
399 log("will now write to stdin: '%s'",
400 (const char*)(send_par.stdin_()+((lineMode)?"\n":"")));
401 write(processStdin,
402 (const char*)(send_par.stdin_()+((lineMode)?"\n":"")),
403 send_par.stdin_().lengthof()+((lineMode)?1:0));
404
405 log("PIPEasp__PT::outgoing_send_PStdin exited");
406 }
407
408 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PStdinBinary& send_par) {
409 log("PIPEasp__PT::outgoing_send_PStdinBinary called");
410 binaryMode = true;
411 if (!processExecuting) {
412 sendError("Pipe Test Port: No command executing");
413 return;
414 }
415 if (disableSend) { // process was started with PExecute(Binary)
416 sendError("Pipe Test Port: PStdinBinary is not sent: current process is not started with PExecuteBackground!");
417 return;
418 }
419
420 TTCN_Logger::begin_event(TTCN_DEBUG);
421 TTCN_Logger::log_event("PIPE test port (%s): will now write binary data to stdin: ", get_name());
422 send_par.stdin_().log();
423 TTCN_Logger::end_event();
424
425 write(processStdin,
426 (const char*)(const unsigned char*)(send_par.stdin_()),
427 send_par.stdin_().lengthof());
428 log("PIPEasp__PT::outgoing_send_PStdinBinary exited");
429 }
430
431 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PKill& send_par) {
432 log("PIPEasp__PT::outgoing_send_PKill called");
433 if (!processExecuting) {
434 // no process is running
435 log("No process executing.");
436 sendError("Pipe Test Port: No command executing");
437 log("PIPEasp__PT::outgoing_send_PKill exited");
438 return;
439 }
440
441 int signo = (int)send_par.signal();
442 if (signo<1 || signo>31) {
443 // signo out of range;
444 log("Signo out of range.");
445 sendError(
446 "Pipe Test port: Signal number should be "
447 "between 1 and 31");
448 log("PIPEasp__PT::outgoing_send_PKill exited");
449 return;
450 }
451 // killing process
452 log("Killing process %d, signo: %d", processPid, signo);
453 int r = kill(processPid, signo);
454 log("Kill process returned %d", r);
455 log("PIPEasp__PT::outgoing_send_PKill exited");
456 }
457
458 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PLineMode& send_par) {
459 log("PIPEasp__PT::outgoing_send_PLineMode called");
460 lineMode = (bool)send_par.lineMode();
461 log("LineMode is set to %s", (lineMode)?"TRUE":"FALSE");
462 log("PIPEasp__PT::outgoing_send_PLineMode exited");
463 }
464
465 void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PEndOfInput& send_par) {
466 log("PIPEasp__PT::outgoing_send_PEndOfInput called");
467 // close stdin pipe
468 close(processStdin);
469 processStdin = -1;
470 log("stdin closed");
471 log("PIPEasp__PT::outgoing_send_PEndOfInput exited");
472 }
473
474 /********************************
475 * Execute the given command
476 * returns the exitcode of the process
477 *********************************/
478 int PIPEasp__PT::execCommand(const char* command) {
479 log("PIPEasp__PT::execCommand called");
480 log("Executing command: %s", command);
481
482 // with this it is not possible to access the pid of the process
483 //return system(command);
484
485 int argc = 0;
486 char* argv[1024];
487
488 CHARSTRING temp = "";
489 for (int i = 0; command[i] != 0; i++) {
490 if (isspace(command[i])) {
491 argv[argc++] = strdup(temp);
492 log("command argument added: %s", (const char*)temp);
493 while (command[i] != '0' && isspace(command[i])) i++;
494 i--;
495 temp = "";
496 } else {
497 temp = temp + CHARSTRING(1, command+i);
498 }
499 }
500
501 if (temp != "") {
502 argv[argc++] = strdup(temp);
503 log("command argument added: %s", (const char*)temp);
504 }
505
506 argv[argc++] = (char*)NULL;
507
508 log("execCommand(%s,%d)\n", argv[0], argc);
509 execvp(argv[0],argv);
510
511 fprintf(stderr,"Error executing command %s (%d): %s\n",
512 argv[0], errno, strerror(errno));
513 fflush(stderr);
514 // exit(errno);
515 return errno;
516 }
517
518 /***********************************
519 * if the the child process died, gets
520 * the exit code and sends it to TTCN
521 * should be called when stdout/err are closed
522 ************************************/
523 void PIPEasp__PT::handle_childDeath() {
524 log("Getting process status for pid %d...", processPid);
525 processExitCode = 0; // reset the exitcode
526 int pid = wait(&processExitCode);
527 //waitpid(processPid,&processExitCode, 0);
528 if (pid!=processPid) {
529 log("other child died with pid: %d, exit code: %d", pid, processExitCode);
530 return;
531 }
532
533 log("Child process exit status is: %d", processExitCode);
534 // send code to TTCN:
535 sendExitCode();
536 // send result to TTCN
537 sendResult();
538
539 // removing fd-s installed for the process:
540 Uninstall_Handler(); // no handler is needed
541 FD_ZERO(&readfds);
542 /*
543 // equivalent with:
544 //FD_CLR(processStdin, &readfds);
545 FD_CLR(processStdout, &readfds);
546 FD_CLR(processStderr, &readfds);
547 Install_Handler(&readfds, NULL, NULL, 0.0);
548 */
549
550 // closing pipes:
551 close(processStdin);
552 //close(processStdout); // already closed
553 //close(processStderr); // already closed
554
555 processStdin = -1;
556 //processStdout = -1;
557 //processStderr = -1;
558
559 processExecuting = false;
560 disableSend = false;
561 }
562
563 /***************************
564 * Send stdout msg to TTCN
565 ***************************/
566 void PIPEasp__PT::sendStdout() {
567 if (disableSend) return;
568
569 PIPEasp__Types::ASP__PStdout message_PStdout;
570 PIPEasp__Types::ASP__PStdoutBinary message_PStdoutBinary;
571 if (lineMode && !binaryMode) {
572 // send complete lines from buffer
573 const unsigned char* pos = stdout_buffer.get_read_data();
574 for(unsigned int i=0; i<stdout_buffer.get_read_len(); i++) {
575 // not end of line:
576 if (pos[i] != '\n') {
577 continue;
578 }
579
580 // at end of line
581 // length of data is i (+1 is for \n and is not sent)
582 message_PStdout.stdout_() = CHARSTRING(i, (const char*)pos);
583
584 // send message
585 incoming_message(message_PStdout);
586
587 // remove the complete line from buffer,
588 // also set i and pos to the beginning of buffer
589 stdout_buffer.set_pos(i+1);
590 stdout_buffer.cut();
591 i = 0;
592 pos = stdout_buffer.get_read_data();
593 }
594 } else {
595 // lineMode false or binaryMode true
596 if (binaryMode) {
597 message_PStdoutBinary.stdout_() =
598 OCTETSTRING(stdout_buffer.get_read_len(), stdout_buffer.get_read_data());
599 stdout_buffer.clear();
600 incoming_message(message_PStdoutBinary);
601 }
602 else {
603 message_PStdout.stdout_() =
604 CHARSTRING(stdout_buffer.get_read_len(), (const char*)stdout_buffer.get_read_data());
605 stdout_buffer.clear();
606 incoming_message(message_PStdout);
607 }
608 // incoming_message(message);
609 }
610 }
611
612
613 /***************************
614 * Send stderr msg to TTCN
615 ***************************/
616 void PIPEasp__PT::sendStderr() {
617 if (disableSend) return;
618
619 PIPEasp__Types::ASP__PStderr message_PStderr;
620 PIPEasp__Types::ASP__PStderrBinary message_PStderrBinary;
621 if (lineMode && !binaryMode) {
622 // send complete lines from buffer
623 const unsigned char* pos = stderr_buffer.get_read_data();
624 for(unsigned int i=0; i<stderr_buffer.get_read_len(); i++) {
625 // not end of line:
626 if (pos[i] != '\n') {
627 continue;
628 }
629
630 // at end of line
631 // length of data is i (+1 is for \n and is not sent)
632 message_PStderr.stderr_() = CHARSTRING(i, (const char*)pos);
633
634 // send message
635 incoming_message(message_PStderr);
636
637 // remove the complete line from buffer,
638 // also set i and pos to the beginning of buffer
639 stderr_buffer.set_pos(i+1);
640 stderr_buffer.cut();
641 i = 0;
642 pos = stderr_buffer.get_read_data();
643 }
644 } else {
645 // lineMode false or binaryMode true
646 if (binaryMode) {
647 message_PStderrBinary.stderr_() =
648 OCTETSTRING(stderr_buffer.get_read_len(), stderr_buffer.get_read_data());
649 stderr_buffer.clear();
650 incoming_message(message_PStderrBinary);
651 }
652 else {
653 message_PStderr.stderr_() =
654 CHARSTRING(stderr_buffer.get_read_len(), (const char*)stderr_buffer.get_read_data());
655 stderr_buffer.clear();
656 incoming_message(message_PStderr);
657 }
658 // incoming_message(message);
659 }
660 }
661
662
663 /***************************
664 * Send exitcode msg to TTCN
665 ***************************/
666 void PIPEasp__PT::sendExitCode() {
667 if (disableSend) return;
668
669 log("Sending ExitCode to TTCN");
670 PIPEasp__Types::ASP__PExit message_PExit;
671 message_PExit.code() = processExitCode;
672 incoming_message(message_PExit);
673 }
674
675
676 /***************************
677 * Send error msg to TTCN
678 ***************************/
679 void PIPEasp__PT::sendError(const char* error_msg) {
680 PIPEasp__Types::ASP__PError message_PError;
681 message_PError.errorMessage() = error_msg;
682 incoming_message(message_PError);
683 }
684
685
686 /***************************
687 * Send Result msg to TTCN
688 ***************************/
689 void PIPEasp__PT::sendResult() {
690 if (!disableSend) return; // do not send result if process was started by PExecuteBackground
691
692 log("Sending result to TTCN...");
693 PIPEasp__Types::ASP__PResult message_PResult;
694 PIPEasp__Types::ASP__PResultBinary message_PResultBinary;
695 if (binaryMode) {
696 message_PResultBinary.stdout_() =
697 OCTETSTRING(stdout_buffer.get_read_len(), stdout_buffer.get_read_data());
698 message_PResultBinary.stderr_() =
699 OCTETSTRING(stderr_buffer.get_read_len(), stderr_buffer.get_read_data());
700 message_PResultBinary.code() = processExitCode;
701 incoming_message(message_PResultBinary);
702 } else {
703 int messageLen = stdout_buffer.get_read_len();
704 const char* messageData = (const char*)stdout_buffer.get_read_data();
705
706 if (lineMode && messageData[messageLen-1]=='\n') {
707 messageLen--; // remove newline from the end
708 }
709
710 message_PResult.stdout_() = CHARSTRING(messageLen, messageData);
711
712 messageLen = stderr_buffer.get_read_len();
713 messageData = (const char*)stderr_buffer.get_read_data();
714
715 if (lineMode && messageData[messageLen-1]=='\n') {
716 messageLen--; // remove newline from the end
717 }
718
719 message_PResult.stderr_() = CHARSTRING(messageLen, messageData);
720 message_PResult.code() = processExitCode;
721 incoming_message(message_PResult);
722 }
723
724 // clearing the buffers
725 stdout_buffer.clear();
726 stderr_buffer.clear();
727 //incoming_message(message);
728 }
729
730
731 ////////////////
732 // Log function
733 ////////////////
734 void PIPEasp__PT::log(const char *fmt, ...)
735 {
736 TTCN_Logger::begin_event(TTCN_DEBUG);
737 TTCN_Logger::log_event("PIPE test port (%s): ", get_name());
738 va_list ap;
739 va_start(ap, fmt);
740 TTCN_Logger::log_event_va_list(fmt, ap);
741 va_end(ap);
742 TTCN_Logger::end_event();
743 }
744
745 }//namespace
This page took 0.04664 seconds and 5 git commands to generate.