Advertisement
Guest User

Untitled

a guest
Jun 28th, 2015
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #if defined(__FB_WIN32__)
  2.     #Include Once "windows.bi"
  3. #elseif defined(__FB_LINUX__)
  4.     #include once "crt/linux/unistd.bi"
  5.     declare function ioctl alias "ioctl" (fd as integer, request as ulong, ...) as integer
  6.     #define FIONREAD    &h541B
  7. #endif
  8.  
  9. Type BiPipe
  10.     private:
  11.         #if defined(__FB_WIN32__)
  12.             hProcessHandle As HANDLE
  13.             hWritePipe As HANDLE
  14.             hReadPipe As HANDLE
  15.         #elseif defined(__FB_LINUX__)
  16.             pipeStdin as long
  17.             pipeStdout as long
  18.         #endif
  19.    
  20.     public:
  21.         declare constructor (prgName as string)
  22.         declare destructor ()
  23.         declare function write (text as string) as integer
  24.         declare function read (timeout as uinteger = 100) as string
  25.         declare function readLine (separator As String = "a" & Chr(13,10), timeout as uinteger = 100) as string
  26. End Type
  27.  
  28. #if defined(__FB_WIN32__)
  29.     constructor BiPipe (prgName as string)
  30.         Dim As STARTUPINFO si
  31.         Dim As PROCESS_INFORMATION pi
  32.         Dim As SECURITY_ATTRIBUTES sa
  33.         Dim As HANDLE hReadPipe, hWritePipe, hReadChildPipe, hWriteChildPipe
  34.  
  35.         'set security attributes
  36.         sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
  37.         sa.lpSecurityDescriptor = NULL 'use default descriptor
  38.         sa.bInheritHandle = TRUE
  39.  
  40.         'create one pipe for each direction
  41.         CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0) 'parent to child
  42.         CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0) 'child to parent
  43.  
  44.         GetStartupInfo(@si)
  45.  
  46.         si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
  47.         si.wShowWindow = SW_HIDE 'appearance of child process window
  48.         si.hStdOutput  = hWriteChildPipe
  49.         si.hStdError   = hWriteChildPipe
  50.         si.hStdInput   = hReadChildPipe
  51.  
  52.         CreateProcess(0,PrgName,0,0,TRUE,CREATE_NEW_CONSOLE,0,0,@si,@pi)
  53.  
  54.         CloseHandle(hWriteChildPipe)
  55.         CloseHandle(hReadChildPipe)
  56.  
  57.         this.hProcessHandle = pi.hProcess 'handle to child process
  58.         this.hWritePipe = hWritePipe
  59.         this.hReadPipe = hReadPipe
  60.     end constructor
  61.  
  62.     destructor BiPipe ()
  63.         TerminateProcess(hProcessHandle, 0)
  64.         CloseHandle(hWritePipe)
  65.         CloseHandle(hReadPipe)
  66.     end destructor
  67.  
  68.     function BiPipe.write (text as string) as integer
  69.         dim bytesWritten as integer
  70.  
  71.         WriteFile(hWritePipe, strptr(text), len(text), @bytesWritten, 0)
  72.        
  73.         return bytesWritten
  74.     End Function
  75.  
  76.  
  77.     function BiPipe.read (timeout as uinteger = 100) as string
  78.         'returns the whole pipe content until the pipe is empty or timeout occurs.
  79.         ' timeout default is 100ms to prevent a deadlock
  80.  
  81.         Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage
  82.         Dim As String buffer, retText
  83.         Dim As Double tout = Timer + Cast(Double,timeout) / 1000
  84.  
  85.         Do
  86.             PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
  87.             If iTotalBytesAvail Then
  88.                 buffer = String(iTotalBytesAvail,Chr(0))
  89.                 ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
  90.                 retText &= buffer
  91.             ElseIf Len(retText) Then
  92.                 Exit Do
  93.             EndIf
  94.         Loop Until Timer > tout
  95.  
  96.         Return retText
  97.  
  98.     End Function
  99.  
  100.     function BiPipe.readLine (separator As String = "a" & Chr(13,10), timeout as uinteger = 100) as string
  101.         'returns the pipe content till the first separator if any, or otherwise the whole pipe
  102.         ' content on timeout. timeout default is 100ms to prevent a deadlock
  103.  
  104.         Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage, endPtr
  105.         Dim As String buffer, retText, mode
  106.         Dim As Double tout = Timer + Cast(Double,timeout) / 1000
  107.  
  108.         mode = LCase(Left(separator,1))
  109.         separator = Mid(separator,2)
  110.  
  111.         Do
  112.             PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
  113.             If iTotalBytesAvail Then
  114.                 buffer = String(iTotalBytesAvail,Chr(0))
  115.                 PeekNamedPipe(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead, _
  116.                               @iTotalBytesAvail,@iBytesLeftThisMessage) 'copy pipe content to buffer
  117.                 Select Case mode
  118.                     Case "a" 'any
  119.                         endPtr = InStr(buffer, Any separator) 'look for line end sign
  120.                     Case "e" 'exact
  121.                         endPtr = InStr(buffer, separator) 'look for line end sign
  122.                 End Select
  123.                 If endPtr Then 'return pipe content till line end
  124.                     Select Case mode
  125.                         Case "a"
  126.                             Do While (InStr(separator,Chr(buffer[endPtr - 1]))) And (endPtr < Len(buffer))
  127.                                 endPtr += 1
  128.                             Loop
  129.                             endPtr -= 1
  130.                         Case "e"
  131.                             endPtr += Len(separator)
  132.                     End Select
  133.                     retText = Left(buffer,endPtr)
  134.                     ReadFile(hReadPipe,StrPtr(buffer),endPtr,@iNumberOfBytesRead,0) 'remove read bytes from pipe
  135.                     Select Case mode
  136.                         Case "a"
  137.                             Return RTrim(retText,Any separator) 'remove line end sign from returned string
  138.                         Case "e"
  139.                             Return Left(retText,Len(retText) - Len(separator))
  140.                     End Select
  141.                 EndIf
  142.             EndIf
  143.         Loop Until Timer > tout
  144.  
  145.         If iTotalBytesAvail Then 'return all pipe content
  146.             buffer = String(iTotalBytesAvail,Chr(0))
  147.             ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
  148.             Return buffer
  149.         EndIf
  150.  
  151.         Return ""
  152.  
  153.     End Function
  154. #elseif defined(__FB_LINUX__)
  155.     constructor BiPipe (prgName as string)
  156.         dim pipeStdin(0 to 1) as long
  157.         dim pipeStdout(0 to 1) as long
  158.        
  159.         pipe_(@pipeStdin(0))
  160.         pipe_(@pipeStdout(0))
  161.        
  162.         if fork() = 0 then
  163.             close_(pipeStdin(1))
  164.             close_(pipeStdout(0))
  165.            
  166.             dup2(pipeStdin(0), 0)
  167.             dup2(pipeStdout(1), 1)
  168.            
  169.             execl(strptr("/bin/sh"), strptr("sh"), strptr("-c"), strptr(prgName), cast(ubyte ptr, 0))
  170.             _exit(1)
  171.         end if
  172.        
  173.         this.pipeStdin = pipeStdin(1)
  174.         this.pipeStdout = pipeStdout(0)
  175.        
  176.         close_(pipeStdin(0))
  177.         close_(pipeStdout(1))
  178.     end constructor
  179.  
  180.     destructor BiPipe ()
  181.         close_(pipeStdin)
  182.         close_(pipeStdout)
  183.     end destructor
  184.  
  185.     function BiPipe.write (text as string) as integer
  186.         return write_(pipeStdin, strptr(text), len(text))
  187.     End Function
  188.  
  189.  
  190.     function BiPipe.read (timeout as uinteger = 100) as string
  191.         'returns the whole pipe content until the pipe is empty or timeout occurs.
  192.         ' timeout default is 100ms to prevent a deadlock
  193.  
  194.         Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage
  195.         Dim As String buffer, retText
  196.         Dim As Double tout = Timer + Cast(Double,timeout) / 1000
  197.  
  198.         Do
  199.             ioctl(pipeStdout, FIONREAD, @iTotalBytesAvail)
  200.             If iTotalBytesAvail Then
  201.                 buffer = String(iTotalBytesAvail,Chr(0))
  202.                
  203.                 read_(pipeStdout, strptr(buffer), len(buffer))
  204.                 retText &= buffer
  205.             ElseIf Len(retText) Then
  206.                 Exit Do
  207.             End If
  208.         Loop Until Timer > tout
  209.  
  210.         Return retText
  211.  
  212.     End Function
  213.  
  214.     #if 0
  215.     function BiPipe.readLine (separator As String = "a" & Chr(13,10), timeout as uinteger = 100) as string
  216.         'returns the pipe content till the first separator if any, or otherwise the whole pipe
  217.         ' content on timeout. timeout default is 100ms to prevent a deadlock
  218.  
  219.         Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage, endPtr
  220.         Dim As String buffer, retText, mode
  221.         Dim As Double tout = Timer + Cast(Double,timeout) / 1000
  222.  
  223.         mode = LCase(Left(separator,1))
  224.         separator = Mid(separator,2)
  225.  
  226.         Do
  227.             PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
  228.             If iTotalBytesAvail Then
  229.                 buffer = String(iTotalBytesAvail,Chr(0))
  230.                 PeekNamedPipe(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead, _
  231.                               @iTotalBytesAvail,@iBytesLeftThisMessage) 'copy pipe content to buffer
  232.                 Select Case mode
  233.                     Case "a" 'any
  234.                         endPtr = InStr(buffer, Any separator) 'look for line end sign
  235.                     Case "e" 'exact
  236.                         endPtr = InStr(buffer, separator) 'look for line end sign
  237.                 End Select
  238.                 If endPtr Then 'return pipe content till line end
  239.                     Select Case mode
  240.                         Case "a"
  241.                             Do While (InStr(separator,Chr(buffer[endPtr - 1]))) And (endPtr < Len(buffer))
  242.                                 endPtr += 1
  243.                             Loop
  244.                             endPtr -= 1
  245.                         Case "e"
  246.                             endPtr += Len(separator)
  247.                     End Select
  248.                     retText = Left(buffer,endPtr)
  249.                     ReadFile(hReadPipe,StrPtr(buffer),endPtr,@iNumberOfBytesRead,0) 'remove read bytes from pipe
  250.                     Select Case mode
  251.                         Case "a"
  252.                             Return RTrim(retText,Any separator) 'remove line end sign from returned string
  253.                         Case "e"
  254.                             Return Left(retText,Len(retText) - Len(separator))
  255.                     End Select
  256.                 EndIf
  257.             EndIf
  258.         Loop Until Timer > tout
  259.  
  260.         If iTotalBytesAvail Then 'return all pipe content
  261.             buffer = String(iTotalBytesAvail,Chr(0))
  262.             ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
  263.             Return buffer
  264.         EndIf
  265.  
  266.         Return ""
  267.  
  268.     End Function
  269.     #endif
  270. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement