Changeset 210
- Timestamp:
- Oct 7, 2009, 12:09:56 AM (16 years ago)
- Location:
- trunk/src/corelib/io
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/corelib/io/qprocess.cpp ¶
r203 r210 515 515 destroyPipe(childStartedPipe); 516 516 destroyPipe(deathPipe); 517 #else 518 pipeData[InPipe].bytesLeft = 0; 519 pipeData[OutPipe].bytesLeft = pipeData[ErrPipe].bytesLeft = 0; 520 pipeData[InPipe].newBytes = 0; 521 pipeData[OutPipe].newBytes = pipeData[ErrPipe].newBytes = 0; 517 522 #endif 518 523 #ifdef Q_OS_UNIX -
TabularUnified trunk/src/corelib/io/qprocess_os2.cpp ¶
r203 r210 271 271 APIRET arc = NO_ERROR; 272 272 QProcessPrivate *d = process->d_func(); 273 if (d->stdinChannel.pipe.server != HPIPE(~0)) { 273 if (d->stdinChannel.type == QProcessPrivate::Channel::Normal && 274 d->stdinChannel.pipe.server != HPIPE(~0)) { 274 275 arc = DosSetNPipeSem(d->stdinChannel.pipe.server, (HSEM)instance->eventSem, 275 276 toPipeKey(procKey, QProcessPrivate::InPipe)); 276 277 } 277 if (arc == NO_ERROR && d->stdoutChannel.pipe.server != HPIPE(~0)) { 278 if (arc == NO_ERROR && 279 d->stdoutChannel.type == QProcessPrivate::Channel::Normal && 280 d->stdoutChannel.pipe.server != HPIPE(~0)) { 278 281 arc = DosSetNPipeSem(d->stdoutChannel.pipe.server, (HSEM)instance->eventSem, 279 282 toPipeKey(procKey, QProcessPrivate::OutPipe)); 280 283 } 281 if (arc == NO_ERROR && d->stderrChannel.pipe.server != HPIPE(~0)) { 284 if (arc == NO_ERROR && 285 d->stderrChannel.type == QProcessPrivate::Channel::Normal && 286 d->stderrChannel.pipe.server != HPIPE(~0)) { 282 287 arc = DosSetNPipeSem(d->stderrChannel.pipe.server, (HSEM)instance->eventSem, 283 288 toPipeKey(procKey, QProcessPrivate::ErrPipe)); … … 552 557 } 553 558 554 bool QProcessPrivate::createPipe(PipeType type, Channel::Pipe &pipe) 559 bool QProcessPrivate::createPipe(PipeType type, Channel::Pipe &pipe, 560 const char *name /*= 0*/) 555 561 { 556 562 APIRET rc; 557 563 char pathBuf[CCHMAXPATH]; 564 565 pipe.server = HPIPE(~0); 566 pipe.client = HFILE(~0); 558 567 559 568 // we need the process identifier to guarantee pipe name unicity … … 564 573 case InPipe: 565 574 // create our end of the pipe 566 sprintf(pathBuf, "\\pipe\\Qt4\\%08lX\\QProcess\\%p\\ Stdin",567 ppib->pib_ulpid, this->q_func() );575 sprintf(pathBuf, "\\pipe\\Qt4\\%08lX\\QProcess\\%p\\%s", 576 ppib->pib_ulpid, this->q_func(), name ? name : "Stdin"); 568 577 rc = DosCreateNPipe(pathBuf, &pipe.server, 569 NP_ACCESS_OUTBOUND, NP_NOWAIT | NP_TYPE_BYTE | 1, 578 NP_ACCESS_OUTBOUND | NP_NOINHERIT, 579 NP_NOWAIT | NP_TYPE_BYTE | 1, 570 580 PIPE_SIZE_STDIN, 0, 0); 571 581 if (rc == NO_ERROR) { 572 582 DosConnectNPipe(pipe.server); 583 // ensure the other end blocks (vital for process->process redirections) 584 DosSetNPHState(pipe.server, NP_WAIT); 573 585 // open the client end of the pipe 574 586 ULONG action = 0; … … 582 594 // create our end of the pipe 583 595 sprintf(pathBuf, "\\pipe\\Qt4\\%08lX\\QProcess\\%p\\%s", 584 ppib->pib_ulpid, this->q_func(), type == OutPipe ? "Stdout" : "Stderr"); 596 ppib->pib_ulpid, this->q_func(), 597 name ? name : type == OutPipe ? "Stdout" : "Stderr"); 585 598 rc = DosCreateNPipe(pathBuf, &pipe.server, 586 NP_ACCESS_INBOUND, NP_NOWAIT | NP_TYPE_BYTE | 1, 599 NP_ACCESS_INBOUND | NP_NOINHERIT, 600 NP_NOWAIT | NP_TYPE_BYTE | 1, 587 601 0, type == OutPipe ? PIPE_SIZE_STDOUT : PIPE_SIZE_STDERR, 0); 588 602 if (rc == NO_ERROR) { 589 603 DosConnectNPipe(pipe.server); 604 // ensure the other end blocks (vital for process->process redirections) 605 DosSetNPHState(pipe.server, NP_WAIT); 590 606 // open the client end of the pipe 591 607 ULONG action = 0; … … 597 613 } 598 614 599 if (rc != NO_ERROR) 600 qWarning("QProcessPrivate::createPipe: DosCreateNPipe or DosOpen " 601 "returned %lu for PipeType(%d)", rc, type); 615 if (rc != NO_ERROR) { 616 qWarning("QProcessPrivate::createPipe: %s(%s) returned %lu", 617 pipe.server == HPIPE(~0) ? "DosCreateNPipe" : "DosOpen", 618 pathBuf, rc); 619 } 602 620 603 621 return rc == NO_ERROR; … … 689 707 Q_ASSERT_X(channel.process, "QProcess::start", "Internal error"); 690 708 691 Channel *source; 692 Channel *sink; 709 // the first process started is the server, the second one is the client. 710 // the server stores handles to both ends in its channel.pipe member; 711 // the other part will pickup the handle of the client end from there. 693 712 694 713 if (channel.type == Channel::PipeSource) { 695 714 // we are the source 696 source = &channel; 697 sink = &channel.process->stdinChannel; 698 699 Q_ASSERT(source == &stdoutChannel); 700 Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink); 715 Q_ASSERT(&channel == &stdoutChannel); 716 Q_ASSERT(channel.process->stdinChannel.process == this && 717 channel.process->stdinChannel.type == Channel::PipeSink); 718 if (channel.process->stdinChannel.pipe.server != HPIPE(~0)) { 719 // the other process has already started and became the server 720 } else { 721 // note: InPipe, since the type is relative to the other side 722 createPipe(InPipe, channel.pipe, "Source"); 723 } 701 724 } else { 702 // we are the sink; 703 source = &channel.process->stdoutChannel; 704 sink = &channel; 705 706 Q_ASSERT(sink == &stdinChannel); 707 Q_ASSERT(source->process == this && source->type == Channel::PipeSource); 708 } 709 710 if (source->pipe.server != HPIPE(~0)) { 711 // already created, do nothing 712 Q_ASSERT(source->pipe.client == HFILE(~0)); 713 Q_ASSERT(sink->pipe.server == HPIPE(~0) && sink->pipe.client != HFILE(~0)); 714 return true; 715 } else { 716 Q_ASSERT(source->pipe.server == HPIPE(~0) && source->pipe.client == HFILE(~0)); 717 Q_ASSERT(sink->pipe.server == HPIPE(~0) && sink->pipe.client == HFILE(~0)); 718 719 Channel::Pipe pipe; 720 createPipe(OutPipe, pipe); 721 sink->pipe.client = pipe.client; 722 source->pipe.server = pipe.server; 723 724 return true; 725 } 725 // we are the sink (and the server) 726 Q_ASSERT(channel.type == Channel::PipeSink); 727 Q_ASSERT(&channel == &stdinChannel); 728 Q_ASSERT(channel.process->stdoutChannel.process == this && 729 channel.process->stdoutChannel.type == Channel::PipeSource); 730 if (channel.process->stdoutChannel.pipe.server != HPIPE(~0)) { 731 // the other process has already started and became the server 732 } else { 733 // note: OutPipe, since the type is relative to the other side 734 createPipe(OutPipe, channel.pipe, "Sink"); 735 } 736 } 737 738 return true; 726 739 } 727 740 } … … 877 890 // save & copy the stdin handle 878 891 if ((arc = DosDupHandle(realStdin, &tmpStdin)) == NO_ERROR) { 879 arc = DosDupHandle(stdinChannel.pipe.client, &realStdin); 892 HFILE handle = stdinChannel.pipe.client; 893 if (stdinChannel.type == Channel::PipeSink) { 894 // process -> process redirection 895 if (stdinChannel.pipe.server != HPIPE(~0)) { 896 // we are the server 897 handle = (HFILE)stdinChannel.pipe.server; 898 } else { 899 // we are the client, use the server's variable 900 handle = stdinChannel.process->stdoutChannel.pipe.client; 901 } 902 Q_ASSERT(handle != HFILE(~0)); 903 } 904 arc = DosDupHandle(handle, &realStdin); 880 905 } 881 906 if (arc != NO_ERROR) { … … 890 915 // save & copy the stdout handle 891 916 if ((arc = DosDupHandle(realStdout, &tmpStdout)) == NO_ERROR) { 892 arc = DosDupHandle(stdoutChannel.pipe.client, &realStdout); 917 HFILE handle = stdoutChannel.pipe.client; 918 if (stdoutChannel.type == Channel::PipeSource) { 919 // process -> process redirection 920 if (stdoutChannel.pipe.server != HPIPE(~0)) { 921 // we are the server 922 handle = (HFILE)stdoutChannel.pipe.server; 923 } else { 924 // we are the client, use the server's variable 925 handle = stdoutChannel.process->stdinChannel.pipe.client; 926 } 927 Q_ASSERT(handle != HFILE(~0)); 928 } 929 arc = DosDupHandle(handle, &realStdout); 893 930 } 894 931 if (arc != NO_ERROR) { … … 904 941 // merge stdout and stderr if asked to 905 942 if (processChannelMode == QProcess::MergedChannels) { 906 arc = DosDupHandle( stdoutChannel.pipe.client, &realStderr);943 arc = DosDupHandle(realStdout, &realStderr); 907 944 } else { 908 945 arc = DosDupHandle(stderrChannel.pipe.client, &realStderr); … … 959 996 this->pid = Q_PID(pid); 960 997 961 // close the client ends (they are no more necessary) 962 if (stdinChannel.pipe.client != HFILE(~0)) { 963 DosClose(stdinChannel.pipe.client); 964 stdinChannel.pipe.client = HFILE(~0); 965 } 966 if (stdoutChannel.pipe.client != HFILE(~0)) { 967 DosClose(stdoutChannel.pipe.client); 968 stdoutChannel.pipe.client = HFILE(~0); 998 // close the client ends inherited by the started process (it's necessary to 999 // make sure that the started process owns the only handle to the client end 1000 // and when it closes this handle the other party will notice it and e.g. 1001 // stop waiting for new data). 1002 1003 if (stdinChannel.type == Channel::PipeSink) { 1004 // process -> process redirection 1005 if (stdinChannel.pipe.server != HPIPE(~0)) { 1006 // we are the server, leave the handle for the other party 1007 } else { 1008 // we are the client, close the handle 1009 DosClose(stdinChannel.process->stdoutChannel.pipe.client); 1010 stdinChannel.process->stdoutChannel.pipe.client = HFILE(~0); 1011 } 1012 } else { 1013 if (stdinChannel.pipe.client != HFILE(~0)) { 1014 DosClose(stdinChannel.pipe.client); 1015 stdinChannel.pipe.client = HFILE(~0); 1016 } 1017 } 1018 if (stdoutChannel.type == Channel::PipeSource) { 1019 // process -> process redirection 1020 if (stdoutChannel.pipe.server != HPIPE(~0)) { 1021 // we are the server, leave the handle for the other party 1022 } else { 1023 // we are the client, close the handle 1024 DosClose(stdoutChannel.process->stdinChannel.pipe.client); 1025 stdoutChannel.process->stdinChannel.pipe.client = HFILE(~0); 1026 } 1027 } else { 1028 if (stdoutChannel.pipe.client != HFILE(~0)) { 1029 DosClose(stdoutChannel.pipe.client); 1030 stdoutChannel.pipe.client = HFILE(~0); 1031 } 969 1032 } 970 1033 if (stderrChannel.pipe.client != HFILE(~0)) { -
TabularUnified trunk/src/corelib/io/qprocess_p.h ¶
r203 r210 185 185 #if defined(Q_OS_OS2) 186 186 enum PipeType { InPipe = 0, OutPipe = 1, ErrPipe = 2 }; 187 bool createPipe(PipeType type, Channel::Pipe &pipe );187 bool createPipe(PipeType type, Channel::Pipe &pipe, const char *name = 0); 188 188 void destroyPipe(Channel::Pipe &pipe); 189 189 #else
Note:
See TracChangeset
for help on using the changeset viewer.