Commit | Line | Data |
2986a63f |
1 | |
2 | /* |
3 | * Copyright © 2001 Novell, Inc. All Rights Reserved. |
4 | * |
5 | * You may distribute under the terms of either the GNU General Public |
6 | * License or the Artistic License, as specified in the README file. |
7 | * |
8 | */ |
9 | |
10 | /* |
11 | * FILENAME : NWPipe.c |
12 | * DESCRIPTION : Functions to implement pipes on NetWare. |
13 | * Author : HYAK |
14 | * Date : January 2001. |
15 | * |
16 | */ |
17 | |
18 | |
19 | |
20 | #include <nwadv.h> |
21 | #include <nwdsdefs.h> |
22 | |
23 | #include "win32ish.h" |
24 | #include "nwpipe.h" |
25 | #include "nwplglob.h" |
26 | |
27 | |
28 | // This was added since the compile failed saying "undefined P_WAIT" |
29 | // when USE_ITHREADS was commented in the makefile |
30 | #ifndef P_WAIT |
31 | #define P_WAIT 0 |
32 | #endif |
33 | |
34 | #ifndef P_NOWAIT |
35 | #define P_NOWAIT 1 |
36 | #endif |
37 | |
38 | |
39 | |
40 | |
41 | /*============================================================================================ |
42 | |
43 | Function : fnPipeFileMakeArgv |
44 | |
45 | Description : This function makes the argument array. |
46 | |
47 | Parameters : ptpf (IN) - Input structure. |
48 | |
49 | Returns : Boolean. |
50 | |
51 | ==============================================================================================*/ |
52 | |
53 | BOOL fnPipeFileMakeArgv(PTEMPPIPEFILE ptpf) |
54 | { |
55 | int i=0, j=0; |
56 | int dindex = 0; |
57 | int sindex = 0; |
58 | |
59 | ptpf->m_argv_len = 0; |
60 | |
61 | |
62 | // Below 2 is added for the following reason: |
63 | // - The first one is for an additional value that will be added through ptpf->m_redirect. |
64 | // - The second one is for a NULL termination of the array. |
65 | // This is required for spawnvp API that takes a NULL-terminated array as its 3rd parameter. |
66 | // If the array is NOT NULL-terminated, then the server abends at the spawnvp call !! |
67 | ptpf->m_argv = (char **) malloc((ptpf->m_pipeCommand->m_argc + 2) * sizeof(char*)); |
68 | if (ptpf->m_argv == NULL) |
69 | return FALSE; |
70 | |
71 | // For memory allocation it is just +1 since the last one is only for NULL-termination |
72 | // and no memory is required to be allocated. |
73 | for(i=0; i<(ptpf->m_pipeCommand->m_argc + 1); i++) |
74 | { |
75 | ptpf->m_argv[i] = (char *) malloc(MAX_DN_BYTES * sizeof(char)); |
76 | if (ptpf->m_argv[i] == NULL) |
77 | { |
78 | for(j=0; j<i; j++) |
79 | { |
80 | if(ptpf->m_argv[j]) |
81 | { |
82 | free(ptpf->m_argv[j]); |
83 | ptpf->m_argv[j] = NULL; |
84 | } |
85 | } |
86 | free(ptpf->m_argv); |
87 | ptpf->m_argv = NULL; |
88 | |
89 | return FALSE; |
90 | } |
91 | } |
92 | |
93 | // Copy over parsed items, removing "load" keyword if necessary. |
94 | sindex = ((stricmp(ptpf->m_pipeCommand->m_argv[0], LOAD_COMMAND) == 0) ? 1 : 0); |
95 | while (sindex < ptpf->m_pipeCommand->m_argc) |
96 | { |
97 | strcpy(ptpf->m_argv[dindex], ptpf->m_pipeCommand->m_argv[sindex]); |
98 | dindex++; |
99 | sindex++; |
100 | } |
101 | |
102 | if (stricmp(ptpf->m_argv[0], PERL_COMMAND_NAME) == 0) // If Perl is the first command. |
103 | { |
104 | ptpf->m_launchPerl = TRUE; |
105 | |
106 | #ifdef MPK_ON |
107 | ptpf->m_perlSynchSemaphore = kSemaphoreAlloc((BYTE *)"pipeSemaphore", 0); |
108 | #else |
109 | ptpf->m_perlSynchSemaphore = OpenLocalSemaphore(0); |
110 | #endif //MPK_ON |
111 | } |
112 | else if (stricmp(ptpf->m_argv[0], (char *)"perlglob") == 0) |
113 | ptpf->m_doPerlGlob = TRUE; |
114 | |
115 | |
116 | // Create last argument, which will redirect to or from the temp file |
117 | if (!ptpf->m_doPerlGlob || ptpf->m_mode) |
118 | { |
119 | if (!ptpf->m_mode) // If read mode? |
120 | { |
121 | if (ptpf->m_launchPerl) |
122 | strcpy(ptpf->m_redirect, (char *)">"); |
123 | else |
124 | strcpy(ptpf->m_redirect, (char *)"(CLIB_OPT)/>"); |
125 | } |
126 | else |
127 | { |
128 | if (ptpf->m_launchPerl) |
129 | strcpy(ptpf->m_redirect, (char *)"<"); |
130 | else |
131 | strcpy(ptpf->m_redirect, (char *)"(CLIB_OPT)/<"); |
132 | } |
133 | strcat(ptpf->m_redirect, ptpf->m_fileName); |
134 | |
135 | if (ptpf->m_launchPerl) |
136 | { |
137 | char tbuf[15] = {'\0'}; |
138 | sprintf(tbuf, (char *)" -{%x", ptpf->m_perlSynchSemaphore); |
139 | strcat(ptpf->m_redirect, tbuf); |
140 | } |
141 | |
142 | strcpy(ptpf->m_argv[dindex], (char*) ptpf->m_redirect); |
143 | dindex++; |
144 | } |
145 | |
146 | if (dindex < (ptpf->m_pipeCommand->m_argc + 1)) |
147 | { |
148 | if(ptpf->m_argv[dindex]) |
149 | { |
150 | free(ptpf->m_argv[dindex]); |
151 | ptpf->m_argv[dindex] = NULL; // NULL termination - required for spawnvp call. |
152 | } |
153 | } |
154 | |
155 | ptpf->m_argv_len = dindex; // Length of the argv array OR number of argv string values. |
156 | ptpf->m_argv[ptpf->m_argv_len] = NULL; // NULL termination - required for spawnvp call. |
157 | |
158 | |
159 | return TRUE; |
160 | } |
161 | |
162 | |
163 | /*============================================================================================ |
164 | |
165 | Function : fnPipeFileOpen |
166 | |
167 | Description : This function opens the pipe file. |
168 | |
169 | Parameters : ptpf (IN) - Input structure. |
170 | command (IN) - Input command string. |
171 | mode (IN) - Mode of opening. |
172 | |
173 | Returns : File pointer. |
174 | |
175 | ==============================================================================================*/ |
176 | |
177 | FILE* fnPipeFileOpen(PTEMPPIPEFILE ptpf, char* command, char* mode) |
178 | { |
179 | int i=0, j=0; |
180 | |
181 | char tempName[_MAX_PATH] = {'\0'}; |
182 | |
183 | |
184 | ptpf->m_fileName = (char *) malloc(_MAX_PATH * sizeof(char)); |
185 | if(ptpf->m_fileName == NULL) |
186 | return NULL; |
187 | |
188 | // The char array is emptied so that there is no junk characters. |
189 | strncpy(ptpf->m_fileName, "", (_MAX_PATH * sizeof(char))); |
190 | |
191 | |
192 | // Save off stuff |
193 | // |
194 | if(strchr(mode,'r') != 0) |
195 | ptpf->m_mode = FALSE; // Read mode |
196 | else if(strchr(mode,'w') != 0) |
197 | ptpf->m_mode = TRUE; // Write mode |
198 | else |
199 | { |
200 | if(ptpf->m_fileName != NULL) |
201 | { |
202 | // if (strlen(ptpf->m_fileName)) |
203 | if (ptpf->m_fileName) |
204 | unlink(ptpf->m_fileName); |
205 | |
206 | free(ptpf->m_fileName); |
207 | ptpf->m_fileName = NULL; |
208 | } |
209 | |
210 | return NULL; |
211 | } |
212 | |
213 | |
214 | ptpf->m_pipeCommand = (PCOMMANDLINEPARSER) malloc(sizeof(COMMANDLINEPARSER)); |
215 | if (!ptpf->m_pipeCommand) |
216 | { |
217 | // if (strlen(ptpf->m_fileName)) |
218 | if (ptpf->m_fileName) |
219 | unlink(ptpf->m_fileName); |
220 | |
221 | free(ptpf->m_fileName); |
222 | ptpf->m_fileName = NULL; |
223 | |
224 | return NULL; |
225 | } |
226 | |
227 | // Initialise the variables |
228 | ptpf->m_pipeCommand->m_isValid = TRUE; |
229 | |
230 | /**** |
231 | // Commented since these are not being used. Still retained here. |
232 | // To be removed once things are proved to be working fine to a good confident level, |
233 | |
234 | ptpf->m_pipeCommand->m_redirInName = NULL; |
235 | ptpf->m_pipeCommand->m_redirOutName = NULL; |
236 | ptpf->m_pipeCommand->m_redirErrName = NULL; |
237 | ptpf->m_pipeCommand->m_redirBothName = NULL; |
238 | ptpf->m_pipeCommand->nextarg = NULL; |
239 | ****/ |
240 | |
241 | ptpf->m_pipeCommand->sSkippedToken = NULL; |
242 | ptpf->m_pipeCommand->m_argv = NULL; |
243 | ptpf->m_pipeCommand->new_argv = NULL; |
244 | |
245 | #ifdef MPK_ON |
246 | ptpf->m_pipeCommand->m_qSemaphore = NULL; |
247 | #else |
248 | ptpf->m_pipeCommand->m_qSemaphore = 0L; |
249 | #endif //MPK_ON |
250 | |
251 | ptpf->m_pipeCommand->m_noScreen = 0; |
252 | ptpf->m_pipeCommand->m_AutoDestroy = 0; |
253 | ptpf->m_pipeCommand->m_argc = 0; |
254 | ptpf->m_pipeCommand->m_argv_len = 1; |
255 | |
256 | |
257 | ptpf->m_pipeCommand->m_argv = (char **) malloc(ptpf->m_pipeCommand->m_argv_len * sizeof(char *)); |
258 | if (ptpf->m_pipeCommand->m_argv == NULL) |
259 | { |
260 | free(ptpf->m_pipeCommand); |
261 | ptpf->m_pipeCommand = NULL; |
262 | |
263 | // if (strlen(ptpf->m_fileName)) |
264 | if (ptpf->m_fileName) |
265 | unlink(ptpf->m_fileName); |
266 | |
267 | free(ptpf->m_fileName); |
268 | ptpf->m_fileName = NULL; |
269 | |
270 | return NULL; |
271 | } |
272 | ptpf->m_pipeCommand->m_argv[0] = (char *) malloc(MAX_DN_BYTES * sizeof(char)); |
273 | if (ptpf->m_pipeCommand->m_argv[0] == NULL) |
274 | { |
275 | for(j=0; j<i; j++) |
276 | { |
277 | if(ptpf->m_pipeCommand->m_argv[j]) |
278 | { |
279 | free(ptpf->m_pipeCommand->m_argv[j]); |
280 | ptpf->m_pipeCommand->m_argv[j]=NULL; |
281 | } |
282 | } |
283 | free(ptpf->m_pipeCommand->m_argv); |
284 | ptpf->m_pipeCommand->m_argv=NULL; |
285 | |
286 | free(ptpf->m_pipeCommand); |
287 | ptpf->m_pipeCommand = NULL; |
288 | |
289 | // if (strlen(ptpf->m_fileName)) |
290 | if (ptpf->m_fileName) |
291 | unlink(ptpf->m_fileName); |
292 | |
293 | free(ptpf->m_fileName); |
294 | ptpf->m_fileName = NULL; |
295 | |
296 | return NULL; |
297 | } |
298 | |
299 | |
300 | ptpf->m_redirect = (char *) malloc(MAX_DN_BYTES * sizeof(char)); |
301 | if (ptpf->m_redirect == NULL) |
302 | { |
303 | for(i=0; i<ptpf->m_pipeCommand->m_argv_len; i++) |
304 | { |
305 | if(ptpf->m_pipeCommand->m_argv[i] != NULL) |
306 | { |
307 | free(ptpf->m_pipeCommand->m_argv[i]); |
308 | ptpf->m_pipeCommand->m_argv[i] = NULL; |
309 | } |
310 | } |
311 | |
312 | free(ptpf->m_pipeCommand->m_argv); |
313 | ptpf->m_pipeCommand->m_argv = NULL; |
314 | |
315 | free(ptpf->m_pipeCommand); |
316 | ptpf->m_pipeCommand = NULL; |
317 | |
318 | |
319 | // if (strlen(ptpf->m_fileName)) |
320 | if (ptpf->m_fileName) |
321 | unlink(ptpf->m_fileName); |
322 | |
323 | free(ptpf->m_fileName); |
324 | ptpf->m_fileName = NULL; |
325 | |
326 | return NULL; |
327 | } |
328 | |
329 | // The char array is emptied. |
330 | // If it is not done so, then it could contain some junk values and the string length in that case |
331 | // will not be zero. This causes erroneous results in fnPipeFileMakeArgv() function |
332 | // where strlen(ptpf->m_redirect) is used as a check for incrementing the parameter count and |
333 | // it will wrongly get incremented in such cases. |
334 | strncpy(ptpf->m_redirect, "", (MAX_DN_BYTES * sizeof(char))); |
335 | |
336 | // Parse the parameters. |
337 | fnCommandLineParser(ptpf->m_pipeCommand, (char *)command, TRUE); |
338 | if (!ptpf->m_pipeCommand->m_isValid) |
339 | { |
340 | fnTempPipeFileReleaseMemory(ptpf); |
341 | return NULL; |
342 | } |
343 | |
344 | |
345 | // Create a temporary file name |
346 | // |
1db1659f |
347 | strncpy ( tempName, fnNwGetEnvironmentStr((char *)"TEMP", NWDEFPERLTEMP), (_MAX_PATH - 20) ); |
2986a63f |
348 | tempName[_MAX_PATH-20] = '\0'; |
349 | strcat(tempName, (char *)"\\plXXXXXX.tmp"); |
350 | if (!fnMy_MkTemp(tempName)) |
351 | { |
352 | fnTempPipeFileReleaseMemory(ptpf); |
353 | return NULL; |
354 | } |
355 | |
356 | // create a temporary place-holder file |
357 | fclose(fopen(tempName, (char *)"w")); |
358 | strcpy(ptpf->m_fileName, tempName); |
359 | |
360 | |
361 | // Make the argument array |
362 | if(!fnPipeFileMakeArgv(ptpf)) |
363 | { |
364 | fnTempPipeFileReleaseMemory(ptpf); |
365 | |
366 | // Release additional memory |
367 | if(ptpf->m_argv != NULL) |
368 | { |
369 | for(i=0; i<ptpf->m_argv_len; i++) |
370 | { |
371 | if(ptpf->m_argv[i] != NULL) |
372 | { |
373 | free(ptpf->m_argv[i]); |
374 | ptpf->m_argv[i] = NULL; |
375 | } |
376 | } |
377 | |
378 | free(ptpf->m_argv); |
379 | ptpf->m_argv = NULL; |
380 | } |
381 | |
382 | return NULL; |
383 | } |
384 | |
385 | |
386 | // Open the temp file in the appropriate way... |
387 | // |
388 | if (!ptpf->m_mode) // If Read mode? |
389 | { |
390 | // we wish to spawn a command, intercept its output, |
391 | // and then get that output |
392 | // |
393 | if (!ptpf->m_argv[0]) |
394 | { |
395 | fnTempPipeFileReleaseMemory(ptpf); |
396 | |
397 | // Release additional memory |
398 | if(ptpf->m_argv != NULL) |
399 | { |
400 | for(i=0; i<ptpf->m_argv_len; i++) |
401 | { |
402 | if(ptpf->m_argv[i] != NULL) |
403 | { |
404 | free(ptpf->m_argv[i]); |
405 | ptpf->m_argv[i] = NULL; |
406 | } |
407 | } |
408 | |
409 | free(ptpf->m_argv); |
410 | ptpf->m_argv = NULL; |
411 | } |
412 | |
413 | return NULL; |
414 | } |
415 | |
416 | if (ptpf->m_launchPerl) |
417 | fnPipeFileDoPerlLaunch(ptpf); |
418 | else |
419 | if (ptpf->m_doPerlGlob) |
420 | fnDoPerlGlob(ptpf->m_argv, ptpf->m_fileName); // hack to do perl globbing |
421 | else |
422 | spawnvp(P_WAIT, ptpf->m_argv[0], ptpf->m_argv); |
423 | |
424 | ptpf->m_file = fopen (ptpf->m_fileName, (char *)"r"); // Get the Pipe file handle |
425 | } |
426 | else if (ptpf->m_mode) // If Write mode? |
427 | { |
428 | // we wish to open the file for writing now and |
429 | // do the command later |
430 | // |
431 | ptpf->m_file = fopen(ptpf->m_fileName, (char *)"w"); |
432 | } |
433 | |
434 | fnTempPipeFileReleaseMemory(ptpf); |
435 | |
436 | // Release additional memory |
437 | if(ptpf->m_argv != NULL) |
438 | { |
439 | for(i=0; i<(ptpf->m_argv_len); i++) |
440 | { |
441 | if(ptpf->m_argv[i] != NULL) |
442 | { |
443 | free(ptpf->m_argv[i]); |
444 | ptpf->m_argv[i] = NULL; |
445 | } |
446 | } |
447 | |
448 | free(ptpf->m_argv); |
449 | ptpf->m_argv = NULL; |
450 | } |
451 | |
452 | |
453 | return ptpf->m_file; // Return the Pipe file handle. |
454 | } |
455 | |
456 | |
457 | /*============================================================================================ |
458 | |
459 | Function : fnPipeFileClose |
460 | |
461 | Description : This function closes the pipe file. |
462 | |
463 | Parameters : ptpf (IN) - Input structure. |
464 | |
465 | Returns : Nothing. |
466 | |
467 | ==============================================================================================*/ |
468 | |
469 | void fnPipeFileClose(PTEMPPIPEFILE ptpf) |
470 | { |
471 | int i = 0; |
472 | |
473 | if (ptpf->m_mode) // If Write mode? |
474 | { |
475 | // we wish to spawn a command using our temp file for |
476 | // its input |
477 | // |
478 | if(ptpf->m_file != NULL) |
479 | { |
480 | fclose (ptpf->m_file); |
481 | ptpf->m_file = NULL; |
482 | } |
483 | |
484 | if (ptpf->m_launchPerl) |
485 | fnPipeFileDoPerlLaunch(ptpf); |
486 | else if (ptpf->m_argv) |
487 | spawnvp(P_WAIT, ptpf->m_argv[0], ptpf->m_argv); |
488 | } |
489 | |
490 | |
491 | // Close the temporary Pipe File, if opened |
492 | if (ptpf->m_file) |
493 | { |
494 | fclose(ptpf->m_file); |
495 | ptpf->m_file = NULL; |
496 | } |
497 | // Delete the temporary Pipe Filename if still valid and free the memory associated with the file name. |
498 | if(ptpf->m_fileName != NULL) |
499 | { |
500 | // if (strlen(ptpf->m_fileName)) |
501 | if (ptpf->m_fileName) |
502 | unlink(ptpf->m_fileName); |
503 | |
504 | free(ptpf->m_fileName); |
505 | ptpf->m_fileName = NULL; |
506 | } |
507 | |
508 | /** |
509 | if(ptpf->m_argv != NULL) |
510 | { |
511 | for(i=0; i<(ptpf->m_argv_len); i++) |
512 | { |
513 | if(ptpf->m_argv[i] != NULL) |
514 | { |
515 | free(ptpf->m_argv[i]); |
516 | ptpf->m_argv[i] = NULL; |
517 | } |
518 | } |
519 | |
520 | free(ptpf->m_argv); |
521 | ptpf->m_argv = NULL; |
522 | } |
523 | **/ |
524 | |
525 | if (ptpf->m_perlSynchSemaphore) |
526 | { |
527 | #ifdef MPK_ON |
528 | kSemaphoreFree(ptpf->m_perlSynchSemaphore); |
529 | #else |
530 | CloseLocalSemaphore(ptpf->m_perlSynchSemaphore); |
531 | #endif //MPK_ON |
532 | } |
533 | |
534 | |
535 | return; |
536 | } |
537 | |
538 | |
539 | /*============================================================================================ |
540 | |
541 | Function : fnPipeFileDoPerlLaunch |
542 | |
543 | Description : This function launches Perl. |
544 | |
545 | Parameters : ptpf (IN) - Input structure. |
546 | |
547 | Returns : Nothing. |
548 | |
549 | ==============================================================================================*/ |
550 | |
551 | void fnPipeFileDoPerlLaunch(PTEMPPIPEFILE ptpf) |
552 | { |
553 | char curdir[_MAX_PATH] = {'\0'}; |
554 | char* pcwd = NULL; |
555 | |
556 | int i=0; |
557 | |
558 | |
559 | // save off the current working directory to restore later |
560 | // this is just a hack! these problems of synchronization and |
561 | // restoring calling context need a much better solution! |
562 | pcwd = (char *)getcwd(curdir, sizeof(curdir)-1); |
563 | fnSystemCommand(ptpf->m_argv, ptpf->m_argv_len); |
564 | if (ptpf->m_perlSynchSemaphore) |
565 | { |
566 | #ifdef MPK_ON |
567 | kSemaphoreWait(ptpf->m_perlSynchSemaphore); |
568 | #else |
569 | WaitOnLocalSemaphore(ptpf->m_perlSynchSemaphore); |
570 | #endif //MPK_ON |
571 | } |
572 | |
573 | if (pcwd) |
574 | chdir(pcwd); |
575 | |
576 | return; |
577 | } |
578 | |
579 | |
580 | /*============================================================================================ |
581 | |
582 | Function : fnTempPipeFile |
583 | |
584 | Description : This function initialises the variables of the structure passed in. |
585 | |
586 | Parameters : ptpf (IN) - Input structure. |
587 | |
588 | Returns : Nothing. |
589 | |
590 | ==============================================================================================*/ |
591 | |
592 | void fnTempPipeFile(PTEMPPIPEFILE ptpf) |
593 | { |
594 | ptpf->m_fileName = NULL; |
595 | |
596 | ptpf->m_mode = FALSE; // Default mode = Read mode. |
597 | ptpf->m_file = NULL; |
598 | ptpf->m_pipeCommand = NULL; |
599 | ptpf->m_argv = NULL; |
600 | |
601 | ptpf->m_redirect = NULL; |
602 | |
603 | ptpf->m_launchPerl = FALSE; |
604 | ptpf->m_doPerlGlob = FALSE; |
605 | |
606 | #ifdef MPK_ON |
607 | ptpf->m_perlSynchSemaphore = NULL; |
608 | #else |
609 | ptpf->m_perlSynchSemaphore = 0L; |
610 | #endif |
611 | |
612 | ptpf->m_argv_len = 0; |
613 | |
614 | return; |
615 | } |
616 | |
617 | |
618 | /*============================================================================================ |
619 | |
620 | Function : fnTempPipeFileReleaseMemory |
621 | |
622 | Description : This function frees the memory allocated to various buffers. |
623 | |
624 | Parameters : ptpf (IN) - Input structure. |
625 | |
626 | Returns : Nothing. |
627 | |
628 | ==============================================================================================*/ |
629 | |
630 | void fnTempPipeFileReleaseMemory(PTEMPPIPEFILE ptpf) |
631 | { |
632 | int i=0; |
633 | |
634 | |
635 | if (ptpf->m_pipeCommand) |
636 | { |
637 | if(ptpf->m_pipeCommand->m_argv != NULL) |
638 | { |
639 | for(i=0; i<ptpf->m_pipeCommand->m_argv_len; i++) |
640 | { |
641 | if(ptpf->m_pipeCommand->m_argv[i] != NULL) |
642 | { |
643 | free(ptpf->m_pipeCommand->m_argv[i]); |
644 | ptpf->m_pipeCommand->m_argv[i] = NULL; |
645 | } |
646 | } |
647 | |
648 | free(ptpf->m_pipeCommand->m_argv); |
649 | ptpf->m_pipeCommand->m_argv = NULL; |
650 | } |
651 | |
652 | if(ptpf->m_pipeCommand->sSkippedToken != NULL) |
653 | { |
654 | free(ptpf->m_pipeCommand->sSkippedToken); |
655 | ptpf->m_pipeCommand->sSkippedToken = NULL; |
656 | } |
657 | /**** |
658 | // Commented since these are not being used. Still retained here. |
659 | // To be removed once things are proved to be working fine to a good confident level, |
660 | |
661 | if(ptpf->m_pipeCommand->nextarg) |
662 | { |
663 | free(ptpf->m_pipeCommand->nextarg); |
664 | ptpf->m_pipeCommand->nextarg = NULL; |
665 | } |
666 | |
667 | if(ptpf->m_pipeCommand->m_redirInName) |
668 | { |
669 | free(ptpf->m_pipeCommand->m_redirInName); |
670 | ptpf->m_pipeCommand->m_redirInName = NULL; |
671 | } |
672 | if(ptpf->m_pipeCommand->m_redirOutName) |
673 | { |
674 | free(ptpf->m_pipeCommand->m_redirOutName); |
675 | ptpf->m_pipeCommand->m_redirOutName = NULL; |
676 | } |
677 | if(ptpf->m_pipeCommand->m_redirErrName) |
678 | { |
679 | free(ptpf->m_pipeCommand->m_redirErrName); |
680 | ptpf->m_pipeCommand->m_redirErrName = NULL; |
681 | } |
682 | if(ptpf->m_pipeCommand->m_redirBothName) |
683 | { |
684 | free(ptpf->m_pipeCommand->m_redirBothName); |
685 | ptpf->m_pipeCommand->m_redirBothName = NULL; |
686 | } |
687 | ****/ |
688 | |
689 | if(ptpf->m_pipeCommand != NULL) |
690 | { |
691 | free(ptpf->m_pipeCommand); |
692 | ptpf->m_pipeCommand = NULL; |
693 | } |
694 | } |
695 | |
696 | if(ptpf->m_redirect != NULL) |
697 | { |
698 | free(ptpf->m_redirect); |
699 | ptpf->m_redirect = NULL; |
700 | } |
701 | |
702 | return; |
703 | } |
704 | |