Diff
Not logged in

Differences From Artifact [0f18f47a29]:

To Artifact [02dcf4f2c2]:


462
463
464
465
466
467
468



469
470
471
472
473
474
475
    const char *nextArg;
    int skip, atOK, flags, needCmd, errorToOutput = 0;
    Tcl_Size i, j, lastArg, lastBar;
    Tcl_DString execBuffer;
    TclFile pipeIn;
    TclFile curInFile, curOutFile, curErrFile;
    Tcl_Channel channel;




    if (inPipePtr != NULL) {
	*inPipePtr = NULL;
    }
    if (outPipePtr != NULL) {
	*outPipePtr = NULL;
    }







>
>
>







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
    const char *nextArg;
    int skip, atOK, flags, needCmd, errorToOutput = 0;
    Tcl_Size i, j, lastArg, lastBar;
    Tcl_DString execBuffer;
    TclFile pipeIn;
    TclFile curInFile, curOutFile, curErrFile;
    Tcl_Channel channel;
    int newSyntax = 0;
    Tcl_Size subArgc;
    const char **subArgv = NULL;

    if (inPipePtr != NULL) {
	*inPipePtr = NULL;
    }
    if (outPipePtr != NULL) {
	*outPipePtr = NULL;
    }
497
498
499
500
501
502
503




504
505
506
507
508





509
510
511
512
513
514
515
     * list.
     */

    lastBar = -1;
    cmdCount = 1;
    needCmd = 1;
    for (i = 0; i < argc; i++) {




	errorToOutput = 0;
	skip = 0;
	p = argv[i];
	switch (*p++) {
	case '|':





	    if (*p == '&') {
		p++;
	    }
	    if (*p == '\0') {
		if ((i == (lastBar + 1)) || (i == (argc - 1))) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "illegal use of | or |& in command", -1));







>
>
>
>





>
>
>
>
>







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
     * list.
     */

    lastBar = -1;
    cmdCount = 1;
    needCmd = 1;
    for (i = 0; i < argc; i++) {
	if (newSyntax && needCmd) {
	    needCmd = 0;
	    continue;
	}
	errorToOutput = 0;
	skip = 0;
	p = argv[i];
	switch (*p++) {
	case '|':
	    if ((i == 0) && (*p == '\0')) {
		newSyntax = 1;
		lastBar = 0;
		continue;
	    }
	    if (*p == '&') {
		p++;
	    }
	    if (*p == '\0') {
		if ((i == (lastBar + 1)) || (i == (argc - 1))) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "illegal use of | or |& in command", -1));
673
674
675
676
677
678
679











680
681
682
683
684

685
686
687
688
689
690
691
		if (errorFile == NULL) {
		    goto error;
		}
	    }
	    break;

	default:











	    /*
	     * Got a command word, not a redirection.
	     */

	    needCmd = 0;

	    break;
	}

	if (skip != 0) {
	    for (j = i + skip; j < argc; j++) {
		argv[j - skip] = argv[j];
	    }







>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>







685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
		if (errorFile == NULL) {
		    goto error;
		}
	    }
	    break;

	default:

	    if (newSyntax) {
		Tcl_SetObjResult(interp,
				 Tcl_ObjPrintf(
					       "Unsupported redirection \"%s\"",
					       argv[i]));
		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
				 "PIPESYNTAX", NULL);
		goto error;
	    } else {

		/*
		 * Got a command word, not a redirection.
		 */
		
		needCmd = 0;
	    }
	    break;
	}

	if (skip != 0) {
	    for (j = i + skip; j < argc; j++) {
		argv[j - skip] = argv[j];
	    }
824
825
826
827
828
829
830


831
832
833
834
835
836












837
838
839
840
841
842

843
844
845
846
847
848
849
     * arguments between the "|" characters.
     */

    Tcl_ReapDetachedProcs();
    pidPtr = (Tcl_Pid *)Tcl_Alloc(cmdCount * sizeof(Tcl_Pid));

    curInFile = inputFile;



    for (i = 0; i < argc; i = lastArg + 1) {
	int result, joinThisError;
	Tcl_Pid pid;
	const char *oldName;













	/*
	 * Convert the program name into native form.
	 */

	if (Tcl_TranslateFileName(interp, argv[i], &execBuffer) == NULL) {
	    goto error;

	}

	/*
	 * Find the end of the current segment of the pipeline.
	 */

	joinThisError = 0;







>
>






>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
>







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
     * arguments between the "|" characters.
     */

    Tcl_ReapDetachedProcs();
    pidPtr = (Tcl_Pid *)Tcl_Alloc(cmdCount * sizeof(Tcl_Pid));

    curInFile = inputFile;

    lastArg = argc; /* compiler warning */

    for (i = 0; i < argc; i = lastArg + 1) {
	int result, joinThisError;
	Tcl_Pid pid;
	const char *oldName;

	if (newSyntax) {
	    if (i == 0) {
		lastArg = i;
		continue;
	    }
	    if (Tcl_SplitList(interp, argv[i], &subArgc, &subArgv) != TCL_OK) {
		goto error;
	    }
	    if (Tcl_TranslateFileName(interp, subArgv[0], &execBuffer) == NULL) {
		goto error;
	    }
	} else {
	    /*
	     * Convert the program name into native form.
	     */
	    
	    if (Tcl_TranslateFileName(interp, argv[i], &execBuffer) == NULL) {
		goto error;
	    }
	}

	/*
	 * Find the end of the current segment of the pipeline.
	 */

	joinThisError = 0;
879
880
881
882
883
884
885







886
887
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902

	if (joinThisError != 0) {
	    curErrFile = curOutFile;
	} else {
	    curErrFile = errorFile;
	}








	/*
	 * Restore argv[i], since a caller wouldn't expect the contents of
	 * argv to be modified.
	 */

	oldName = argv[i];
	argv[i] = Tcl_DStringValue(&execBuffer);
	result = TclpCreateProcess(interp, lastArg - i, argv + i,
		curInFile, curOutFile, curErrFile, &pid);
	argv[i] = oldName;

	if (result != TCL_OK) {
	    goto error;
	}
	Tcl_DStringFree(&execBuffer);

	pidPtr[numPids] = pid;
	numPids++;







>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
>







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949

	if (joinThisError != 0) {
	    curErrFile = curOutFile;
	} else {
	    curErrFile = errorFile;
	}

	if (newSyntax) {
	    subArgv[0] = Tcl_DStringValue(&execBuffer);
	    result = TclpCreateProcess(interp, subArgc, subArgv,
				       curInFile, curOutFile, curErrFile, &pid);
	    Tcl_Free(subArgv);
	    subArgv = NULL;
	} else {
	    /*
	     * Restore argv[i], since a caller wouldn't expect the contents of
	     * argv to be modified.
	     */
	    
	    oldName = argv[i];
	    argv[i] = Tcl_DStringValue(&execBuffer);
	    result = TclpCreateProcess(interp, lastArg - i, argv + i,
				       curInFile, curOutFile, curErrFile, &pid);
	    argv[i] = oldName;
	}
	if (result != TCL_OK) {
	    goto error;
	}
	Tcl_DStringFree(&execBuffer);

	pidPtr[numPids] = pid;
	numPids++;
976
977
978
979
980
981
982




983
984
985
986
987
988
989
    if (pidPtr != NULL) {
	for (i = 0; i < numPids; i++) {
	    if (pidPtr[i] != (Tcl_Pid)-1) {
		Tcl_DetachPids(1, &pidPtr[i]);
	    }
	}
	Tcl_Free(pidPtr);




    }
    numPids = -1;
    goto cleanup;
}

/*
 *----------------------------------------------------------------------







>
>
>
>







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
    if (pidPtr != NULL) {
	for (i = 0; i < numPids; i++) {
	    if (pidPtr[i] != (Tcl_Pid)-1) {
		Tcl_DetachPids(1, &pidPtr[i]);
	    }
	}
	Tcl_Free(pidPtr);
    }
    if (subArgv != NULL) {
	Tcl_Free(subArgv);
	subArgv = NULL;
    }
    numPids = -1;
    goto cleanup;
}

/*
 *----------------------------------------------------------------------