Code-Beispiel
		
bipipe.bi für Win + Linux
Die hier vorgestellte Bibliothek stellt - per #Include eingebunden - 5 Funktionen zur Verfügung:
    * bipOpen(ProgrammName, [showmode] ) - Öffnet das (Konsolen-)programm ProgrammName und richtet zwei unidirektionale Pipes zur Kommunikation ein. Der optionale Parameter showmode legt die Erscheinungsweise des aufgerufenen Programms fest. Mögliche Parameter siehe 
hier. Default ist SW_NORMAL. Der Rückgabewert ist ein Pointer auf das entsprechende HANDLE - Array (HandlePointer).
    * bipClose(HandlePointer) - Beendet das Programm, schließt die Pipes, löscht die Handles, gibt den Speicher frei und setzt den HandlePointer auf 0.
    * bipWrite(HandlePointer, text, ["b"]) - Sendet einen String zur Standardeingabe des geöffneten Programms. Wird der optionale Parameter "b" (für binary) gesetzt, wird der String unverändert gesendet, ansonsten wird noch ein Chr(13,10) angehängt.
    * bipRead(HandlePointer, [timeout]) - Liest die Standardausgabe des Programms. Default für timeout ist 100ms.
    * bipReadLine(HandlePointer, [separator], [timeout]) - Liest eine Zeile vom gestarteten Programm, analog zum "Line Input" - Befehl. Der optionale Parameter separator ist entweder ein "a" (für any), gefolgt von einer Liste von Zeichen, von denen jedes die Zeile beendet, oder ein "e" (für exact), gefolgt von einem oder mehreren Zeichen, das den Separator darstellt. Default ist "a" & Chr(13,10). Default für timeout ist 100ms.
Die Linux - Routinen wurden von darkinsanity geschrieben, ebenso die Konvertierung des ursprünglichen Codes zum Objekt.
English
This library provides - embedded by #Include - 5 functions:
    * bipOpen(ProgramName, [showmode] ) - Opens the (console-)program ProgramName and establishes two uni-directional pipes for communication. The optional parameter showmode determines the specification how the window of the opened program is shown. Default is SW_NORMAL. The return value is a pointer to the according HANDLE - Array (HandlePointer).
    * bipClose(HandlePointer) - Terminates the program, closes the pipes, deletes the handles, deallocates the memory and sets the HandlePointer to 0.
    * bipWrite(HandlePointer, text, ["b"]) - Sends a string to the standard input of the opened program. With the optional parameter "b" (for binary) set, the string is transmitted unchanged, otherwise a Chr(13,10) is attached.
    * bipRead(HandlePointer, [timeout]) - Reads the standard output of the program. The default for timeout is 100ms.
    * bipReadLine(HandlePointer, [separator], [timeout]) - Reads a line from the opened program, analogue to the "Line Input" - statement. The optional parameter is either an "a" (for any), followed by a list of characters which any of them terminates the line, or an "e" (for exact), followed by one or multiple characters defining the separator. Default it "a" & Chr(13,10). The default for timeout is 100ms.
The Linux - routines were written by darkinsanity, as well as the conversion of the initially code  to an objekt.
#If Defined(__FB_WIN32__)
    #Include Once "windows.bi"
#ElseIf Defined(__FB_LINUX__)
    #Include Once "crt/linux/unistd.bi"
    Declare Function ioctl Alias "ioctl" (fd As Integer, request As ULong, ...) As Integer
    #define FIONREAD    &h541B
#EndIf
Type BiPipe
    Private:
    #If Defined(__FB_WIN32__)
        hProcessHandle As HANDLE
        hWritePipe As HANDLE
        hReadPipe As HANDLE
    #ElseIf Defined(__FB_LINUX__)
        pipeStdin As Long
        pipeStdout As Long
    #EndIf
    Public:
    Declare Constructor (prgName As String,showmode As Short = SW_NORMAL)
    Declare Destructor ()
    Declare Function write (text As String) As Integer
    Declare Function Read (timeout As UInteger = 100) As String
    Declare Function readLine (separator As String = "a" & Chr(13,10), timeout As UInteger = 100) As String
End Type
#If Defined(__FB_WIN32__)
Constructor BiPipe (prgName As String,showmode As Short = SW_NORMAL)
    Dim As STARTUPINFO si
    Dim As PROCESS_INFORMATION pi
    Dim As SECURITY_ATTRIBUTES sa
    Dim As HANDLE hReadPipe, hWritePipe, hReadChildPipe, hWriteChildPipe
    'set security attributes
    sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
    sa.lpSecurityDescriptor = NULL 'use default descriptor
    sa.bInheritHandle = TRUE
    'create one pipe for each direction
    CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0) 'parent to child
    CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0) 'child to parent
    GetStartupInfo(@si)
    si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    si.wShowWindow = showmode 'appearance of child process window
    si.hStdOutput  = hWriteChildPipe
    si.hStdError   = hWriteChildPipe
    si.hStdInput   = hReadChildPipe
    CreateProcess(0,PrgName,0,0,TRUE,CREATE_NEW_CONSOLE,0,0,@si,@pi)
    CloseHandle(hWriteChildPipe)
    CloseHandle(hReadChildPipe)
    this.hProcessHandle = pi.hProcess 'handle to child process
    this.hWritePipe = hWritePipe
    this.hReadPipe = hReadPipe
End Constructor
Destructor BiPipe ()
    TerminateProcess(hProcessHandle, 0)
    CloseHandle(hWritePipe)
    CloseHandle(hReadPipe)
End Destructor
Function BiPipe.write (text As String) As Integer
    Dim bytesWritten As Integer
    WriteFile(hWritePipe, StrPtr(text), Len(text), @bytesWritten, 0)
    Return bytesWritten
End Function
Function BiPipe.read (timeout As UInteger = 100) As String
    'returns the whole pipe content until the pipe is empty or timeout occurs.
    ' timeout default is 100ms to prevent a deadlock
    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage
    Dim As String buffer, retText
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000
    Do
        PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
            retText &= buffer
        ElseIf Len(retText) Then
            Exit Do
        EndIf
    Loop Until Timer > tout
    Return retText
End Function
Function BiPipe.readLine (separator As String = "a" & Chr(13,10), timeout As UInteger = 100) As String
    'returns the pipe content till the first separator if any, or otherwise the whole pipe
    ' content on timeout. timeout default is 100ms to prevent a deadlock
    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage, endPtr
    Dim As String buffer, retText, mode
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000
    mode = LCase(Left(separator,1))
    separator = Mid(separator,2)
    Do
        PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            PeekNamedPipe(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead, _
            @iTotalBytesAvail,@iBytesLeftThisMessage) 'copy pipe content to buffer
            Select Case mode
                Case "a" 'any
                    endPtr = InStr(buffer, Any separator) 'look for line end sign
                Case "e" 'exact
                    endPtr = InStr(buffer, separator) 'look for line end sign
            End Select
            If endPtr Then 'return pipe content till line end
                Select Case mode
                    Case "a"
                        Do While (InStr(separator,Chr(buffer[endPtr - 1]))) And (endPtr < Len(buffer))
                            endPtr += 1
                        Loop
                        endPtr -= 1
                    Case "e"
                        endPtr += Len(separator)
                End Select
                retText = Left(buffer,endPtr)
                ReadFile(hReadPipe,StrPtr(buffer),endPtr,@iNumberOfBytesRead,0) 'remove read bytes from pipe
                Select Case mode
                    Case "a"
                        Return RTrim(retText,Any separator) 'remove line end sign from returned string
                    Case "e"
                        Return Left(retText,Len(retText) - Len(separator))
                End Select
            EndIf
        EndIf
    Loop Until Timer > tout
    If iTotalBytesAvail Then 'return all pipe content
        buffer = String(iTotalBytesAvail,Chr(0))
        ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
        Return buffer
    EndIf
    Return ""
End Function
#ElseIf Defined(__FB_LINUX__)
Constructor BiPipe (prgName As String)
    Dim pipeStdin(0 To 1) As Long
    Dim pipeStdout(0 To 1) As Long
    pipe_(@pipeStdin(0))
    pipe_(@pipeStdout(0))
    If fork() = 0 Then
        close_(pipeStdin(1))
        close_(pipeStdout(0))
        dup2(pipeStdin(0), 0)
        dup2(pipeStdout(1), 1)
        execl(StrPtr("/bin/sh"), StrPtr("sh"), StrPtr("-c"), StrPtr(prgName), Cast(UByte Ptr, 0))
        _exit(1)
    End If
    this.pipeStdin = pipeStdin(1)
    this.pipeStdout = pipeStdout(0)
    close_(pipeStdin(0))
    close_(pipeStdout(1))
End Constructor
Destructor BiPipe ()
    close_(pipeStdin)
    close_(pipeStdout)
End Destructor
Function BiPipe.write (text As String) As Integer
    Return write_(pipeStdin, StrPtr(text), Len(text))
End Function
Function BiPipe.read (timeout As UInteger = 100) As String
    'returns the whole pipe content until the pipe is empty or timeout occurs.
    ' timeout default is 100ms to prevent a deadlock
    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage
    Dim As String buffer, retText
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000
    Do
        ioctl(pipeStdout, FIONREAD, @iTotalBytesAvail)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            read_(pipeStdout, StrPtr(buffer), Len(buffer))
            retText &= buffer
        ElseIf Len(retText) Then
            Exit Do
        End If
    Loop Until Timer > tout
    Return retText
End Function
#If 0
Function BiPipe.readLine (separator As String = "a" & Chr(13,10), timeout As UInteger = 100) As String
    'returns the pipe content till the first separator if any, or otherwise the whole pipe
    ' content on timeout. timeout default is 100ms to prevent a deadlock
    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage, endPtr
    Dim As String buffer, retText, mode
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000
    mode = LCase(Left(separator,1))
    separator = Mid(separator,2)
    Do
        PeekNamedPipe(hReadPipe,0,0,0,@iTotalBytesAvail,0)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            PeekNamedPipe(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead, _
            @iTotalBytesAvail,@iBytesLeftThisMessage) 'copy pipe content to buffer
            Select Case mode
                Case "a" 'any
                    endPtr = InStr(buffer, Any separator) 'look for line end sign
                Case "e" 'exact
                    endPtr = InStr(buffer, separator) 'look for line end sign
            End Select
            If endPtr Then 'return pipe content till line end
                Select Case mode
                    Case "a"
                        Do While (InStr(separator,Chr(buffer[endPtr - 1]))) And (endPtr < Len(buffer))
                            endPtr += 1
                        Loop
                        endPtr -= 1
                    Case "e"
                        endPtr += Len(separator)
                End Select
                retText = Left(buffer,endPtr)
                ReadFile(hReadPipe,StrPtr(buffer),endPtr,@iNumberOfBytesRead,0) 'remove read bytes from pipe
                Select Case mode
                    Case "a"
                        Return RTrim(retText,Any separator) 'remove line end sign from returned string
                    Case "e"
                        Return Left(retText,Len(retText) - Len(separator))
                End Select
            EndIf
        EndIf
    Loop Until Timer > tout
    If iTotalBytesAvail Then 'return all pipe content
        buffer = String(iTotalBytesAvail,Chr(0))
        ReadFile(hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
        Return buffer
    EndIf
    Return ""
End Function
#EndIf
#EndIf
Function bipOpen(PrgName As String, showmode As Short = SW_NORMAL) As BiPipe Ptr
    Return new BiPipe(PrgName,showmode)
End Function
Sub bipClose(ByRef handles As BiPipe Ptr)
    delete handles
    handles = 0
End Sub
Function bipWrite(handles As BiPipe Ptr, text As String) As Integer
    Return handles->write(text)
End Function
Function bipRead(handles As BiPipe Ptr, timeout As UInteger = 100) As String
    Return handles->read(timeout)
End Function
Function bipReadLine(handles As BiPipe Ptr, separator As String = "a" & Chr(13,10), timeout As UInteger = 100) As String
    Return handles->readLine(separator,timeout)
End Function
		
		| Zusätzliche Informationen und Funktionen | 
		
			
				
					- Das Code-Beispiel wurde am 01.07.2015 von 
 grindstone angelegt. 
					- Die aktuellste Version wurde am 06.10.2020 von 
 nemored gespeichert. 
					
				 
			 | 
			
				 
				 
			 |