about summary refs log tree commit homepage
path: root/projects/mongrel_service/native/console_process.bas
diff options
context:
space:
mode:
Diffstat (limited to 'projects/mongrel_service/native/console_process.bas')
-rw-r--r--projects/mongrel_service/native/console_process.bas397
1 files changed, 0 insertions, 397 deletions
diff --git a/projects/mongrel_service/native/console_process.bas b/projects/mongrel_service/native/console_process.bas
deleted file mode 100644
index a2bb5c9..0000000
--- a/projects/mongrel_service/native/console_process.bas
+++ /dev/null
@@ -1,397 +0,0 @@
-'#--
-'# Copyright (c) 2007 Luis Lavena, Multimedia systems
-'#
-'# This source code is released under the MIT License.
-'# See MIT-LICENSE file for details
-'#++
-
-#include once "console_process.bi"
-
-constructor ConsoleProcess(byref new_filename as string = "", byref new_arguments as string = "")
-    '# assign filename and arguments
-    
-    '# if filename contains spaces, automatically quote it!
-    if (instr(new_filename, " ") > 0) then
-        _filename = !"\"" + new_filename + !"\""
-    else
-        _filename = new_filename
-    endif
-    
-    _arguments = new_arguments
-end constructor
-
-destructor ConsoleProcess()
-    '# in case process still running
-    if (running = true) then
-        terminate(true)
-        
-        '# close opened handles
-        '# ...
-        CloseHandle(_process_info.hProcess)
-        CloseHandle(_process_info.hThread)
-    end if
-end destructor
-
-property ConsoleProcess.filename() as string
-    return _filename
-end property
-
-property ConsoleProcess.filename(byref rhs as string)
-    if not (running = true) then
-        _filename = rhs
-    end if
-end property
-
-property ConsoleProcess.arguments() as string
-    return _arguments
-end property
-
-property ConsoleProcess.arguments(byref rhs as string)
-    if not (running = true) then
-        _arguments = rhs
-    end if
-end property
-
-property ConsoleProcess.redirected_stdout() as string
-    return _stdout_filename
-end property
-
-property ConsoleProcess.redirected_stderr() as string
-    return _stderr_filename
-end property
-
-'# running is a helper which evaluates _pid and exit_code
-property ConsoleProcess.running() as boolean
-    dim result as boolean
-
-    '# presume not running
-    result = false
-    
-    if not (_pid = 0) then
-        '# that means the process is/was running.
-        '# now evaluate if exit_code = STILL_ACTIVE
-        result = (exit_code = STILL_ACTIVE)
-    end if
-    
-    return result
-end property
-
-property ConsoleProcess.pid() as uinteger
-    return _pid
-end property
-
-property ConsoleProcess.exit_code() as uinteger
-    static previous_code as uinteger
-    dim result as uinteger
-    
-    result = 0
-    
-    '# is _pid valid?
-    if not (_pid = 0) then
-        if not (_process_info.hProcess = NULL) then
-            '# the process reference is valid, get the exit_code
-            if not (GetExitCodeProcess(_process_info.hProcess, @result) = 0) then
-                previous_code = result
-                '# OK
-                '# no error in the query, get result
-                if not (result = STILL_ACTIVE) then
-                    CloseHandle(_process_info.hProcess)
-                    _process_info.hProcess = NULL
-                end if '# (result = STILL_ACTIVE)
-            end if '# not (GetExitCodeProcess() = 0)
-        else
-            result = previous_code
-        end if '# not (proc = NULL)
-    end if '# not (_pid = 0)
-    
-    return result
-end property
-
-function ConsoleProcess.redirect(byval target as ProcessStdEnum, byref new_std_filename as string) as boolean
-    dim result as boolean
-    
-    if not (running = true) then
-        select case target
-            case ProcessStdOut:
-                _stdout_filename = new_std_filename
-                result = true
-                
-            case ProcessStdErr:
-                _stderr_filename = new_std_filename
-                result = true
-                
-            case ProcessStdBoth:
-                _stdout_filename = new_std_filename
-                _stderr_filename = new_std_filename
-                result = true
-        
-        end select
-    end if
-    
-    return result
-end function
-
-function ConsoleProcess.start() as boolean
-    dim result as boolean
-    dim success as boolean
-    
-    '# API
-    '# New Process resources
-    dim context as STARTUPINFO
-    dim proc_sa as SECURITY_ATTRIBUTES = type(sizeof(SECURITY_ATTRIBUTES), NULL, TRUE)
-    
-    '# StdIn, StdOut, StdErr Read and Write Pipes.
-    dim as HANDLE StdInRd, StdOutRd, StdErrRd
-    dim as HANDLE StdInWr, StdOutWr, StdErrWr
-    dim merged as boolean
-    
-    '# cmdline
-    dim cmdline as string
-    
-    '# assume start will fail
-    result = false
-    
-    if (running = false) then
-        '# we should create the std* for the new proc!
-        '# (like good parents, prepare everything!)
-        
-        '# to ensure everything will work, we must allocate a console
-        '# using AllocConsole, even if it fails.
-        '# This solve the problems when running as service.
-        '# we discard result of AllocConsole since we ALWAYS will allocate it.
-        AllocConsole()
-        
-        '# assume all the following steps succeed
-        success = true
-        
-        '# StdIn is the only std that will be created using pipes always
-        '# StdIn
-        if (CreatePipe(@StdInRd, @StdInWr, @proc_sa, 0) = 0) then
-            success = false
-        end if
-        
-        '# Ensure the handles to the pipe are not inherited.
-        if (SetHandleInformation(StdInWr, HANDLE_FLAG_INHERIT, 0) = 0) then
-            success = false
-        end if
-        
-        '# StdOut and StdErr should be redirected?
-        if (not _stdout_filename = "") or _
-            (not _stderr_filename = "") then
-            
-            '# out and err are the same? (merged)
-            if (_stdout_filename = _stderr_filename) then
-                merged = true
-            end if
-        end if
-        
-        '# StdOut if stdout_filename
-        if not (_stdout_filename = "") then
-            StdOutWr = CreateFile(strptr(_stdout_filename), _
-                                    GENERIC_WRITE, _
-                                    FILE_SHARE_READ or FILE_SHARE_WRITE, _
-                                    @proc_sa, _
-                                    OPEN_ALWAYS, _
-                                    FILE_ATTRIBUTE_NORMAL, _
-                                    NULL)
-            
-            if (StdOutWr = INVALID_HANDLE_VALUE) then
-                '# failed to open file
-                success = false
-            else
-                SetFilePointer(StdOutWr, 0, NULL, FILE_END)
-            end if
-        else
-            '# use pipes instead
-            '# StdOut
-            if (CreatePipe(@StdOutRd, @StdOutWr, @proc_sa, 0) = 0) then
-                success = false
-            end if
-            
-            if (SetHandleInformation(StdOutRd, HANDLE_FLAG_INHERIT, 0) = 0) then
-                success = false
-            end if
-        end if 'not (_stdout_filename = "")
-        
-        '# only create stderr if no merged.
-        if (merged = true) then
-            StdErrWr = StdOutWr
-        else
-            '# do the same for StdErr...
-            if not (_stderr_filename = "") then
-                StdErrWr = CreateFile(strptr(_stderr_filename), _
-                                        GENERIC_WRITE, _
-                                        FILE_SHARE_READ or FILE_SHARE_WRITE, _
-                                        @proc_sa, _
-                                        OPEN_ALWAYS, _
-                                        FILE_ATTRIBUTE_NORMAL, _
-                                        NULL)
-                
-                if (StdErrWr = INVALID_HANDLE_VALUE) then
-                    '# failed to open file
-                    success = false
-                else
-                    SetFilePointer(StdErrWr, 0, NULL, FILE_END)
-                end if
-            else
-                '# use pipes instead
-                '# StdOut
-                if (CreatePipe(@StdErrRd, @StdErrWr, @proc_sa, 0) = 0) then
-                    success = false
-                end if
-                
-                if (SetHandleInformation(StdErrRd, HANDLE_FLAG_INHERIT, 0) = 0) then
-                    success = false
-                end if
-                
-            end if 'not (_stderr_filename = "")
-        end if '(merged = true)
-        
-        '# now we must proceed to create the process
-        '# without the pipes, we shouldn't continue!
-        if (success = true) then
-            '# Set the Std* handles ;-)
-            with context
-                .cb = sizeof( context )
-                .hStdError = StdErrWr
-                .hStdOutput = StdOutWr
-                .hStdInput = StdInRd
-                .dwFlags = STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW
-                '# FIXME: .wShowWindow = iif((_show_console = true), SW_SHOW, SW_HIDE)
-                .wShowWindow = SW_HIDE
-            end with
-            
-            '# build the command line
-            cmdline = _filename + " " + _arguments
-            
-            '# now creates the process
-            if (CreateProcess(NULL, _
-                                strptr(cmdline), _
-                                NULL, _
-                                NULL, _
-                                1, _            '# win32 TRUE (1)
-                                0, _
-                                NULL, _
-                                NULL, _
-                                @context, _
-                                @_process_info) = 0) then
-                result = false
-            else
-                '# set the _pid
-                _pid = _process_info.dwProcessId
-                
-                '# OK? yeah, I think so.
-                result = true
-                
-                '# close the Std* handles
-                CloseHandle(StdInRd)
-                CloseHandle(StdInWr)
-                CloseHandle(StdOutRd)
-                CloseHandle(StdOutWr)
-                CloseHandle(StdErrRd)
-                CloseHandle(StdErrWr)
-                
-                '# close children main Thread handle and
-                '# NULLify to avoid issues
-                CloseHandle(_process_info.hThread)
-                _process_info.hThread = NULL
-            end if '# (CreateProcess() = 0)
-        else
-            result = false
-        end if '# (success = TRUE)
-    end if
-    
-    return result
-end function
-
-function ConsoleProcess.terminate(byval force as boolean = false) as boolean
-    dim result as boolean
-    dim success as boolean
-    
-    dim proc as HANDLE
-    dim code as uinteger
-    dim wait_code as uinteger
-    
-    '# is pid valid?
-    if (running = true) then
-        '# hook our custom console handler
-        if not (SetConsoleCtrlHandler(@_console_handler, 1) = 0) then
-            success = true
-        end if
-        
-        if (success = true) then
-            '# get a handle to Process
-            proc = _process_info.hProcess
-            if not (proc = NULL) then
-                '# process is valid, perform actions
-                success = false
-                
-                if not (force = true) then
-                    '# send CTRL_C_EVENT and wait for result
-                    if not (GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0) = 0) then
-                        '# it worked, wait 5 seconds terminates.
-                        wait_code = WaitForSingleObject(proc, 10000)
-                        if not (wait_code = WAIT_TIMEOUT) then
-                            success = true
-                        end if
-                    else
-                        success = false
-                    end if
-                    
-                    '# Ctrl-C didn't work, try Ctrl-Break
-                    if (success = false) then
-                        '# send CTRL_BREAK_EVENT and wait for result
-                        if not (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0) = 0) then
-                            '# it worked, wait 5 seconds terminates.
-                            wait_code = WaitForSingleObject(proc, 10000)
-                            if not (wait_code = WAIT_TIMEOUT) then
-                                success = true
-                            end if
-                        else
-                            success = false
-                        end if
-                    end if
-                    
-                '# only do termination if force was set.
-                elseif (force = true) and (success = false) then
-                    '# still no luck? we should do a hard kill then
-                    if (TerminateProcess(proc, 0) = 0) then
-                        success = false
-                    else
-                        success = true
-                    end if
-                end if
-                
-                '# now get process exit code
-                if (success = true) then
-                    result = true
-                else
-                    result = false
-                end if
-            else
-                '# invalid process handler
-                result = false
-            end if
-            
-        end if '# (success = true)
-        
-        '# remove hooks
-        if not (SetConsoleCtrlHandler(@_console_handler, 0) = 0) then
-            success = true
-        end if
-    end if '# not (pid = 0)
-    
-    return result
-end function
-
-function ConsoleProcess._console_handler(byval dwCtrlType as DWORD) as BOOL
-    dim result as BOOL
-    
-    if (dwCtrlType = CTRL_C_EVENT) then
-        result = 1
-    elseif (dwCtrlType = CTRL_BREAK_EVENT) then
-        result = 1
-    end if
-    
-    return result
-end function