Module: Vapir::Firefox::FirefoxClassAndInstanceMethods
- Included in:
- Vapir::Firefox, Vapir::Firefox
- Defined in:
- lib/vapir-firefox/browser.rb
Defined Under Namespace
Classes: CannotHandlePid
Instance Method Summary collapse
-
#current_os ⇒ Object
returns a symbol representing the platform we’re currently running on - currently implemented platforms are :windows, :macosx, and :linux.
-
#firefox_socket_host ⇒ Object
returns the host which will be configured for a socket.
-
#pid ⇒ Object
returns the pid of the currently-attached Firefox process.
-
#process_running?(pid) ⇒ Boolean
attempts to determine whether the given process is still running.
-
#quit_browser(options = {}) ⇒ Object
quits the browser.
-
#wait_for_process_exit(pid) ⇒ Object
waits until the Firefox process with the given pid has exited.
Instance Method Details
#current_os ⇒ Object
returns a symbol representing the platform we’re currently running on - currently implemented platforms are :windows, :macosx, and :linux. raises NotImplementedError if the current platform isn’t one of those.
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 |
# File 'lib/vapir-firefox/browser.rb', line 665 def current_os @current_os ||= begin platform= if RUBY_PLATFORM =~ /java/ require 'java' java.lang.System.getProperty("os.name") else RUBY_PLATFORM end case platform when /mswin|windows|mingw32/i :windows when /darwin|mac os/i :macosx when /linux/i :linux else raise NotImplementedError, "Unidentified platform #{platform}" end end end |
#firefox_socket_host ⇒ Object
returns the host which will be configured for a socket. same as firefox_socket.host, if that exist, but this is correct even if firefox_socket isn’t initialized.
609 610 611 |
# File 'lib/vapir-firefox/browser.rb', line 609 def firefox_socket_host ['host'] || firefox_socket_class.config.host end |
#pid ⇒ Object
returns the pid of the currently-attached Firefox process.
This only works on Firefox >= 3.6, on platforms supported (see #current_os), and raises CannotHandlePid if it can’t get the pid.
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
# File 'lib/vapir-firefox/browser.rb', line 571 def pid begin raise CannotHandlePid unless firefox_socket.host == 'localhost' begin ctypes = firefox_socket.Components.utils.import("resource://gre/modules/ctypes.jsm").ctypes rescue FirefoxSocketJavascriptError raise CannotHandlePid, "Firefox 3.6 or greater is required for this method.\n\nOriginal error from firefox: #{$!.class}: #{$!.}", $!.backtrace end lib, pidfunction, abi = *case current_os when :macosx ["libc.dylib", 'getpid', ctypes.default_abi] when :linux ["libc.so.6", 'getpid', ctypes.default_abi] when :windows # winapi is correct - we do not want stdcall's mangling. ff4+ does the stdcall # mangling correctly with ctypes.stdcall_abi, and since we don't want mangling, # that fails here. ff < 4 does not do stdcall mangling (and has no winapi abi # to skip mangling) so ends up working correctly. # so, we want winapi if it's defined to skip mangling, but if # it's not defined, use stdcall because it won't mangle anyway. # # see https://bugzilla.mozilla.org/show_bug.cgi?id=585175 ['kernel32', 'GetCurrentProcessId', ctypes['winapi_abi'] || ctypes['stdcall_abi']] else raise CannotHandlePid, "don't know how to get pid for #{current_os}" end lib = ctypes.open(lib) begin getpid = lib.declare(pidfunction, abi, ctypes['int32_t']) return getpid.call() ensure lib.close end end end |
#process_running?(pid) ⇒ Boolean
attempts to determine whether the given process is still running. will raise CannotHandlePid if it can’t determine this.
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 |
# File 'lib/vapir-firefox/browser.rb', line 615 def process_running?(pid) raise CannotHandlePid unless firefox_socket_host == 'localhost' case current_os when :windows kernel32 = Vapir::Firefox.instance_eval do # define this on the class for reuse @kernel32 ||= begin require 'ffi' kernel32 = Module.new kernel32.send :extend, FFI::Library kernel32.ffi_lib 'kernel32' kernel32.ffi_convention :stdcall kernel32.attach_function :OpenProcess, [:ulong, :char, :ulong], :pointer kernel32.attach_function :GetExitCodeProcess, [:pointer, :pointer], :char kernel32.const_set('PROCESS_QUERY_INFORMATION', 0x0400) kernel32.const_set('STILL_ACTIVE', 259) kernel32 end end process_handle = kernel32.OpenProcess(kernel32::PROCESS_QUERY_INFORMATION, 0, pid) exit_code=FFI::MemoryPointer.new(:ulong) result = kernel32.GetExitCodeProcess(process_handle, exit_code) if result == 0 raise "GetExitCodeProcess failed" end return exit_code.get_ulong(0)==kernel32::STILL_ACTIVE when :linux, :macosx `ps -p #{pid}` $? == 0 else raise CannotHandlePid end end |
#quit_browser(options = {}) ⇒ Object
quits the browser.
quit_browser(:force => true) will force the browser to quit.
if there is no existing connection to firefox, this will attempt to create one. If that fails, FirefoxSocketUnableToStart will be raised.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'lib/vapir-firefox/browser.rb', line 537 def quit_browser(={}) firefox_socket(:reset_if_dead => true, :socket_class => firefox_socket_class, :socket_options => ).assert_socket =(, :force => false) pid = @pid || begin self.pid rescue CannotHandlePid nil end # from https://developer.mozilla.org/en/How_to_Quit_a_XUL_Application appStartup= firefox_socket.Components.classes['@mozilla.org/toolkit/app-startup;1'].getService(firefox_socket.Components.interfaces.nsIAppStartup) quitSeverity = [:force] ? firefox_socket.Components.interfaces.nsIAppStartup.eForceQuit : firefox_socket.Components.interfaces.nsIAppStartup.eAttemptQuit firefox_socket.handling_connection_error(:handle => proc{ Vapir::Firefox.uninitialize_firefox_socket }) do appStartup.quit(quitSeverity) ::Waiter.try_for(config.quit_timeout, :exception => Exception::WindowFailedToCloseException.new("The browser did not quit")) do firefox_socket.assert_socket # this should error, going up past the waiter to #handling_connection_error false end end wait_for_process_exit(pid) @browser_window_object=@browser_object=@document_object=@content_window_object=nil nil end |
#wait_for_process_exit(pid) ⇒ Object
waits until the Firefox process with the given pid has exited.
if no pid is given, waits the configured amount of time until it is safe to assume the pfirefox process has exited.
652 653 654 655 656 657 658 659 660 |
# File 'lib/vapir-firefox/browser.rb', line 652 def wait_for_process_exit(pid) if pid ::Waiter.try_for(config.quit_timeout, :exception => Exception::WindowFailedToCloseException.new("The browser did not quit")) do !process_running?(pid) end else sleep config.firefox_quit_sleep_time end end |