本帖最后由 aa77dd@163.com 于 2016-10-17 13:01 编辑
回复 24# CrLf
set /p 后面的
input10
从 12 到 16 是不是木有改呢
象是关于 cmd 的管道阻塞处理方式
Desktop App>Technologies System Services>Interprocess Communications> ipes
Pipe Functions
管道编程
The Windows Pipes Programming - windows“管道”编程 之 "匿名管道"
那个老版的 CMD 源码中有个 文件 cop.c, 包含了 4 个关于管道的函数 ePipe ,PipeErr, PipeWait, BreakPipes
文件 600+ 行, 我就贴上吧
cop.c | #include "cmd.h" | | | | extern int LastRetCode; | | | | extern int ExtCtrlc; | | | | | | | | unsigned PipeCnt ; | | struct pipedata *PdHead = NULL; | | struct pipedata *PdTail = NULL; | | unsigned PipePid ; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | int eComSep(n) | | struct node *n ; | | { | | Dispatch(RIO_OTHER,n->lhs) ; | | return(Dispatch(RIO_OTHER,n->rhs)) ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | int eOr(n) | | struct node *n ; | | { | | int i ; | | if ((i = Dispatch(RIO_OTHER,n->lhs)) == SUCCESS) | | return(SUCCESS) ; | | else { | | LastRetCode = i; | | return(Dispatch(RIO_OTHER,n->rhs)) ; | | } | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | int eAnd(n) | | struct node *n ; | | { | | int i ; | | | | if ((i = Dispatch(RIO_OTHER,n->lhs)) != SUCCESS) | | return(i) ; | | else | | return(Dispatch(RIO_OTHER,n->rhs)) ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | int ePipe(n) | | struct node *n ; | | { | | struct pipedata *Pd ; | | int k = 0 ; | | struct node *l ; | | struct node *r ; | | extern unsigned start_type ; | | TCHAR cflags ; | | | | l = n->lhs ; | | r = n->rhs ; | | | | DEBUG((OPGRP,PILVL,"PIPES:LH = %d, RH = %d ",l->type,r->type)) ; | | | | if (!(Pd = (struct pipedata *)mkstr(sizeof(struct pipedata)))) { | | | | DEBUG((OPGRP,PILVL,"PIPES:Couldn't alloc structure!")) ; | | | | return(FAILURE) ; | | } ; | | | | if (_pipe((int *)Pd, 0, O_BINARY)) { | | | | DEBUG((OPGRP,PILVL,"PIPES:pipe failed!")) ; | | | | PutStdErr(ERROR_NOT_ENOUGH_MEMORY, NOARGS); | | return(FAILURE) ; | | Abort() ; | | } ; | | | | SetList(Pd->rh) ; | | SetList(Pd->wh) ; | | | | DEBUG((OPGRP,PILVL,"PIPES:Pipe built. Handles: rd = %d wt = %d ",Pd->rh, Pd->wh)) ; | | DEBUG((OPGRP,PILVL,"PIPES:Pipe (pre-index) count = %d", PipeCnt)) ; | | | | if (!PipeCnt++) { | | PdHead = PdTail = Pd ; | | Pd->prvpds = NULL ; | | | | DEBUG((OPGRP,PILVL,"PIPES:This is first pipe.")) ; | | | | } else { | | | | DEBUG((OPGRP,PILVL,"PIPES:This is pipe %d.", PipeCnt)) ; | | | | PdTail->nxtpds = Pd ; | | Pd->prvpds = PdTail ; | | Pd->nxtpds = NULL ; | | PdTail = Pd ; | | } ; | | | | if ((Pd->shw = Cdup(STDOUT)) == BADHANDLE) { | | Pd->shw = BADHANDLE ; | | PipeErr() ; | | } ; | | | | DEBUG((OPGRP,PILVL,"PIPES:STDOUT dup'd to %d.", Pd->shw)) ; | | | | if (Cdup2(Pd->wh, STDOUT) == BADHANDLE) | | PipeErr() ; | | | | Cclose(Pd->wh) ; | | Pd->wh = 0 ; | | | | if (l->type <= CMDTYP) | | { | | FindAndFix( (struct cmdnode *) l, &cflags ) ; | | } | | | | DEBUG((OPGRP,PILVL,"PIPES:Write pipe now STDOUT")) ; | | | | k = Dispatch(RIO_PIPE,l) ; | | | | DuplicateHandle( (HANDLE)PipePid, CRTTONT(Pd->rh), | | NULL, NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE); | | | | if (Cdup2(Pd->shw, STDOUT) == BADHANDLE) | | PipeErr() ; | | | | Cclose(Pd->shw) ; | | Pd->shw = 0 ; | | | | DEBUG((OPGRP,PILVL,"PIPES:STDOUT now handle 1 again.")) ; | | | | if (k) { | | ExtCtrlc = 2; | | Abort() ; | | } | | | | Pd->lPID = PipePid ; | | Pd->lstart = start_type ; | | PipePid = 0 ; | | start_type = NONEPGM ; | | | | DEBUG((OPGRP,PILVL,"PIPES:Dispatch LH side succeeded - LPID = %d.",Pd->lPID)) ; | | | | | | if ((Pd->shr = Cdup(STDIN)) == BADHANDLE) { | | Pd->shr = BADHANDLE ; | | PipeErr() ; | | } ; | | | | DEBUG((OPGRP,PILVL,"PIPES:STDIN dup'd to %d.", Pd->shr)) ; | | | | if (Cdup2(Pd->rh, STDIN) == BADHANDLE) | | PipeErr() ; | | | | Cclose(Pd->rh) ; | | Pd->rh = 0 ; | | | | if (r->type <= CMDTYP) | | { | | FindAndFix( (struct cmdnode *) r, &cflags) ; | | } ; | | | | DEBUG((OPGRP,PILVL,"PIPES:Read pipe now STDIN")) ; | | | | k = Dispatch(RIO_PIPE,r) ; | | | | if (Cdup2(Pd->shr, STDIN) == BADHANDLE) | | PipeErr() ; | | | | Cclose(Pd->shr) ; | | Pd->shr = 0 ; | | | | DEBUG((OPGRP,PILVL,"PIPES:STDIN now handle 0 again.")) ; | | | | if (k) { | | ExtCtrlc = 2; | | Abort() ; | | } | | | | Pd->rPID = PipePid ; | | Pd->rstart = start_type ; | | PipePid = 0 ; | | start_type = NONEPGM ; | | | | DEBUG((OPGRP,PILVL,"PIPES:Dispatch RH side succeeded - RPID = %d.",Pd->rPID)) ; | | | | if (!(--PipeCnt)) { | | | | DEBUG((OPGRP,PILVL,"PIPES:Returning from top level pipe. Cnt = %d", PipeCnt)) ; | | | | return(PipeWait()) ; | | } ; | | | | DEBUG((OPGRP,PILVL,"PIPES:Returning from pipe. Cnt = %d", PipeCnt)) ; | | | | return(k) ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | void PipeErr() | | { | | | | PutStdErr(MSG_PIPE_FAILURE, NOARGS) ; | | Abort() ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PipeWait() | | { | | unsigned i ; | | | | DEBUG((OPGRP,PILVL,"PIPEWAIT:Entered - PipeCnt = %d", PipeCnt)) ; | | | | while (PdHead) { | | if (PdHead->lPID) { | | DEBUG((OPGRP, PILVL, "PIPEWAIT: lPID %d, lstart %d", PdHead->lPID, PdHead->lstart)); | | | | if ( PdHead->lstart == EXECPGM ) | | { | | i = WaitProc(PdHead->lPID) ; | | | | DEBUG((OPGRP,PILVL,"PIPEWAIT:CWAIT on LH - Ret = %d, SPID = %d", i, PdHead->lPID)) ; | | } | | | | | | | | | | | | | | | | } ; | | if (PdHead->rPID) { | | DEBUG((OPGRP, PILVL, "PIPEWAIT: rPID %d, rstart %d", PdHead->rPID, PdHead->rstart)); | | if ( PdHead->rstart == EXECPGM ) | | { | | i = WaitProc(PdHead->rPID) ; | | | | DEBUG((OPGRP,PILVL,"PIPEWAIT:CWAIT on RH - Ret = %d, PID = %d", i, PdHead->rPID)) ; | | } | | | | | | | | | | | | | | | | } ; | | | | PdHead = PdHead->nxtpds ; | | } ; | | | | DEBUG((OPGRP,PILVL,"PIPEWAIT: complete, Retcode = %d", i)) ; | | | | PdTail = NULL ; | | PipeCnt = PipePid = 0 ; | | LastRetCode = i; | | return(i) ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | void BreakPipes() | | { | | unsigned i ; | | struct pipedata *pnode; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:Entered - PipeCnt = %d", PipeCnt)) ; | | | | | | | | | | | | | | | | | | | | pnode = PdTail; | | | | | | while (pnode) { | | if (pnode->lPID) { | | i = KillProc(pnode->lPID, FALSE) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:LH (Pid %d) killed - Retcode = %d", PdTail->lPID, i)) ; | | } ; | | | | if (pnode->rPID) { | | i = KillProc(pnode->rPID, FALSE) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:RH (Pid %d) killed - Retcode = %d", PdTail->rPID, i)) ; | | } ; | | pnode = pnode->prvpds ; | | } | | | | | | while (PdTail) { | | if (PdTail->lPID) { | | if (PdTail->lstart == EXECPGM) { | | i = WaitProc(PdTail->lPID); | | | | | | } | | } ; | | | | if (PdTail->rPID) { | | if (PdTail->rstart == EXECPGM) { | | i = WaitProc(PdTail->rPID); | | | | | | } | | } ; | | | | if (PdTail->rh) { | | Cclose(PdTail->rh) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:Pipe read handle closed")) ; | | } ; | | if (PdTail->wh) { | | Cclose(PdTail->wh) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:Pipe write handle closed")) ; | | } ; | | if(PdTail->shr) { | | FlushFileBuffers(CRTTONT(PdTail->shr)); | | Cdup2(PdTail->shr, STDIN) ; | | Cclose(PdTail->shr) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:STDIN restored.")) ; | | | | } ; | | if(PdTail->shw) { | | Cdup2(PdTail->shw, STDOUT) ; | | Cclose(PdTail->shw) ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:STDOUT restored.")) ; | | | | } ; | | PdTail = PdTail->prvpds ; | | } ; | | | | PdHead = NULL ; | | PipeCnt = PipePid = 0 ; | | | | DEBUG((OPGRP,PILVL,"BRKPIPES:Action complete, returning")) ; | | } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | int eParen(n) | | struct node *n ; | | { | | #ifndef NODEB | | if (n->type == PARTYP) | | DEBUG((OPGRP,PNLVL,"ePAREN: Operator is Paren")) ; | | else if (n->type == SILTYP) | | DEBUG((OPGRP,PNLVL,"ePAREN: Operator is Silent")) ; | | #endif | | | | return(Dispatch(RIO_OTHER,n->lhs)) ; | | }COPY |
我还是去浇花来得轻松
https://play.google.com/store/ap ... m.tedrasoft.plumber |