Skip to content

Loading…

Elementary cygwin support #32

Open
wants to merge 3 commits into from

2 participants

@mikesimons

This patch adds elementary cygwin support (i.e. xiki process runs and xiki command can talk to it and present responses to terminal).

The general gist of the changes are as follows:

  • FIFO changed to TCPServer / TCPSocket - FIFOs were causing errors during flush on cygwin
  • "running" check changed to use Daemon PID file checks as ps output does not contain script names on cygwin (plus it's a flakey way to check)
  • xiki_process.rb refactored to allow inclusion without slowing down
  • As a result of the above, xiki_process bin script created to execute the server
  • Bug fix in lib/xiki/menu.rb that caused = vs == warning
  • Hack for a bug in ruby_parser 2.3.1 to prevent redeclared constant errors
Mike Simons added some commits
Mike Simons Fix for ruby_parser 2.3.1 bug and a bunch of redeclared constant errors 0b5cb77
Mike Simons Fix for misplaced elif (harmless given the logic but caused a warning…
… regardless)
5e20ff7
Mike Simons Made xiki_process it's own script in bin dir so that etc/command/xiki…
…_process.rb can be included from elsewhere.

Changed fifo to TCPServer / TCPSocket (fifos are behaving badly under cygwin)
Changed process running check to use PID instead of dodgy ps exec
10ec490
@oysteinkrog

Does xiki work on cygwin these days?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 18, 2012
  1. Fix for misplaced elif (harmless given the logic but caused a warning…

    Mike Simons committed
    … regardless)
  2. Made xiki_process it's own script in bin dir so that etc/command/xiki…

    Mike Simons committed
    …_process.rb can be included from elsewhere.
    
    Changed fifo to TCPServer / TCPSocket (fifos are behaving badly under cygwin)
    Changed process running check to use PID instead of dodgy ps exec
Showing with 81 additions and 122 deletions.
  1. +9 −0 bin/xiki_process
  2. +17 −97 etc/command/xiki_command.rb
  3. +42 −24 etc/command/xiki_process.rb
  4. +12 −0 lib/xiki/launcher.rb
  5. +1 −1 lib/xiki/menu.rb
View
9 bin/xiki_process
@@ -0,0 +1,9 @@
+#!/usr/bin/env ruby
+require 'rubygems'
+
+xiki_dir = File.expand_path "#{File.dirname(__FILE__)}/.."
+$:.unshift "#{xiki_dir}/lib" #.sub(/\/$/, '')
+
+require "#{xiki_dir}/etc/command/xiki_process"
+
+XikiProcess.run
View
114 etc/command/xiki_command.rb
@@ -1,4 +1,6 @@
+require 'socket'
require 'timeout'
+require 'xiki_process'
#
# The 'xiki' shell command uses this class to run xiki menus.
@@ -9,12 +11,6 @@
class XikiCommand
@@dont_show_output = false
- @@initial_request = nil
- def self.pop_initial_request
- tmp = @@initial_request
- @@initial_request = nil # So it doesn't loop
- tmp
- end
# Called by the 'xiki' shell command
def self.run
@@ -35,102 +31,26 @@ def self.run
return self.emacs path if flags.member?("-e") # If -p, just prompt user to type a menu name
- wasnt_running = false
+ XikiProcess.start_daemon unless XikiProcess.running?
+ attempts = 0
begin
- `mkfifo -m 600 /tmp/xikirequest` if ! File.exists?("/tmp/xikirequest") # Always create first, so they have to be pipes and can't be files
- `mkfifo -m 600 /tmp/xikiresponse` if ! File.exists?("/tmp/xikiresponse")
-
- # Try writing to pipe...
-
- open("/tmp/xikirequest", 'w+') do |out|
+ attempts += 1
+ TCPSocket.open('localhost', 22112) do |out|
out.puts path
- out.flush # do this when we're done writing data
- out.close
- end
-
- # Try reading from pipe...
-
- response = self.get_response
- return response
-
- rescue Exception=>e
-
- # If error, remember we have to start the process...
-
- if e.is_a?(Timeout::Error) || (e.is_a?(Errno::ENOENT) && e.to_s =~ /\/tmp\/xiki/)
- # Seems like process hasn't been started, so keep going
- wasnt_running = true
- else
- Ol << "Unknown error when trying to call pipe!"
- Ol << "#{e.to_s}\n#{e.backtrace.join "\n"}"
- return
- end
- end
-
- process_succeeded = false
-
- if wasnt_running
-
- # Start the process...
-
- require 'daemons'
-
- begin
-
- # Shell out as async to start it instead - don't know fucking how
-
- pid_orig = Process.pid
-
- @@initial_request = path
- xiki_process = "#{xiki_dir}/etc/command/xiki_process.rb"
- Daemons.run xiki_process, :ARGV=>['start'], :monitor=>false, :multiple=>false, :dir_mode=>:normal, :dir=>"/tmp/", :log_dir=>"/tmp/", :log_output=>true
-
- # Aparently this line never gets reached
- "- Started the process, I think."
- rescue SystemExit=>e
- raise SystemExit.new if pid_orig != Process.pid # If new process that started, just exit
-
- process_succeeded = true
-
- rescue Exception=>e
- puts "- service couldn't start!:#{e.message}\n#{e.backtrace.join("\n")}\n\n"
- end
- end
-
- if process_succeeded
- puts self.get_response # Get response first time
- end
-
- raise SystemExit.new
- end
-
- def self.get_response
-
- # Simulate timeout error if process not running
- process_running = `ps -ef` =~ /xiki_process.rb/
- if ! process_running
- raise Timeout::Error
- end
-
- # TODO: what if menu takes longer than 3 seconds to run?
-
- # TODO: have process send ACK, so we can make timout short
-
- timeout(3) do
- # timeout(0.5) do
- # timeout(1.5) do
- open("/tmp/xikiresponse", "r+") do |response|
-
- # old TODO Try using select here, to see if there's data avaliable
- # old IO.select ["/tmp/xikiresponse"]
- response = response.gets # will block if there's nothing in the pipe
- response.strip!
- response.gsub! "\036", "\n" # Escape linebreaks as 036 char (record separator)
- return "" if @@dont_show_output
- self.add_coloring response
+ timeout( 3 ) do
+ response = out.gets
+ response.strip!
+ response.gsub! "\036", "\n" # Escape linebreaks as 036 char (record separator)
+ return if @@dont_show_output
+ puts self.add_coloring response
+ end
end
+ rescue Exception => e
+ sleep 1
+ retry if attempts < 10
+ # Handle specific errno here
end
end
View
66 etc/command/xiki_process.rb
@@ -1,27 +1,52 @@
-require 'xiki/core_ext'
-require 'xiki/menu'
-require 'xiki/launcher'
+require 'daemons'
-Xiki.init
+class XikiProcess
-# Make named pipes for input and output
+ def self.running?
+ files = Daemons::PidFile.find_files( "/tmp", "xiki_process" )
+ raise "Multiple PID files found for xiki_process!" if files.length > 1
+ return false if files.length == 0
+ pid_file = Daemons::PidFile.existing( files[0] )
+ Daemons::Pid.running? pid_file.pid()
+ end
-class XikiProcess
+ def self.start_daemon
+ xiki_dir = File.expand_path "#{File.dirname(__FILE__)}/../.."
+ begin
+ pid_orig = Process.pid
+ Daemons.run(
+ "#{xiki_dir}/bin/xiki_process",
+ :ARGV => ['start'],
+ :monitor => false,
+ :multiple => false,
+ :dir_mode => :normal,
+ :dir => "/tmp/",
+ :log_dir => "/tmp/",
+ :log_output => true
+ )
+ rescue SystemExit=>e
+ return
+ rescue Exception=>e
+ puts "- service couldn't start!:#{e.message}\n#{e.backtrace.join("\n")}\n\n"
+ end
+ end
def self.run
- open('/tmp/xikirequest', 'r+') do |f|
+ # We require these here so as not to slow down processes just wanting to do andilliary process stuff
+ require 'socket'
+ require 'xiki/core_ext'
+ require 'xiki/menu'
+ require 'xiki/launcher'
- open('/tmp/xikiresponse', 'w+') do |response|
- loop do
+ Xiki.init
- # Read request...
-
- path = XikiCommand.pop_initial_request || f.gets
+ server = TCPServer.open(22112)
+ loop do
+ Thread.start(server.accept) do |client|
+ path = client.gets
path.strip!
- # Invoke menu and send response...
-
menu_output =
begin
Menu[path]
@@ -29,20 +54,13 @@ def self.run
"#{e.message}\n#{e.backtrace.join("\n")}"
end
- if menu_output.nil?
- menu_output = ""
- end
+ menu_output = "" if menu_output.nil?
menu_output.gsub! "\n", "\036" # Escape linebreaks as 036 char (record separator)
- response.puts menu_output
- response.flush
- end
+ client.puts menu_output
end
end
-
rescue Exception=>e
puts "#{e.message}\n#{e.backtrace}"
end
-end
-
-XikiProcess.run
+end
View
12 lib/xiki/launcher.rb
@@ -2,6 +2,18 @@
require 'xiki/requirer'
require 'xiki'
+# ruby_parser 2.3.1 bug hack
+# https://github.com/seattlerb/ruby_parser/issues/18
+class Regexp
+ unless defined? ONCE then
+ ONCE = 0 # 16 # ?
+ ENC_NONE = /x/n.options
+ ENC_EUC = /x/e.options
+ ENC_SJIS = /x/s.options
+ ENC_UTF8 = /x/u.options
+ end
+end
+
require 'sourcify'
require 'ruby_parser'
require 'file-tail'
View
2 lib/xiki/menu.rb
@@ -634,7 +634,7 @@ def self.do_as_menu
elsif line =~ /^[ +-]*@/ && Tree.has_child? # If on ^@... line and there's child on next line...
# Will grab the whole tree and move it up
Tree.subtree.unindent.sub(/^[ @+-]+/, '')
- elsif
+ else
do_launch = true
Tree.path.last
end
Something went wrong with that request. Please try again.