;;; Code:
+(require 'riece-options)
+(require 'riece-ruby) ;riece-ruby-command,
+ ;riece-ruby-substitute-variables
+
(defgroup riece-async nil
"Connect to IRC server via asynchronous proxy"
:prefix "riece-"
:group 'riece)
-(defcustom riece-async-ruby-command "ruby"
- "Command name for Ruby interpreter."
- :type 'string
- :group 'riece-async)
-
(defcustom riece-async-server-program
'("\
+orequire 'io/nonblock'
socket = TCPSocket.new(" host ", " service ")
-$stdout.write(\"NOTICE CONNECTED #{$$}\r\n\")
+$stdout.write(\"NOTICE CONNECTED #{$$}\\r\\n\")
$stdout.flush
+$stdout.nonblock = true
+trap('STOP', 'IGNORE')
+trap('TSTP', 'IGNORE')
+wfds_in = []
+buf = ''
loop do
- rfds, = select([socket, $stdin])
- if rfds.delete(socket)
- line = socket.gets(\"\r\n\")
+ rfds, wfds, = select([socket, $stdin], wfds_in)
+ unless wfds.empty?
+ until buf.length <= " max-buffer-size "
+ i = buf.index(\"\\r\\n\")
+ break unless i
+ buf.slice!(0 .. i + 1)
+ end
+ begin
+ until buf.empty?
+ len = $stdout.syswrite(buf)
+ buf.slice!(0 .. len)
+ end
+ wfds_in = []
+ rescue Errno::EAGAIN
+ end
+ end
+ if rfds.include?(socket)
+ line = socket.gets(\"\\r\\n\")
break unless line
- if line =~ /^(?::[^ ]+ +)?PING +(.+)\r\n/i
- socket.write(\"PONG #{$1}\r\n\")
+ if line =~ /^(?::[^ ]+ +)?PING +(.+)\\r\\n/i
+ socket.write(\"PONG #{$1}\\r\\n\")
socket.flush
else
- $stdout.write(line)
- $stdout.flush
+ wfds_in = [$stdout]
+ buf << line
end
end
- if rfds.delete($stdin)
- line = $stdin.gets(\"\r\n\")
+ if rfds.include?($stdin)
+ line = $stdin.gets(\"\\r\\n\")
break unless line
socket.write(line)
socket.flush
end
end
socket.close
-exit
")
- "Ruby program of asynchronous proxy"
+ "Ruby program of asynchronous proxy."
:type 'list
:group 'riece-async)
-(defun riece-async-substitute-variables (program variable value)
- (setq program (copy-sequence program))
- (let ((pointer program))
- (while pointer
- (setq pointer (memq variable program))
- (if pointer
- (setcar pointer value)))
- program))
+(defcustom riece-async-max-buffer-size 65535
+ "Maximum size of the write buffer."
+ :type 'integer
+ :group 'riece-async)
+
+(defconst riece-async-description
+ "Keep IRC connection with external process")
;;;###autoload
(defun riece-async-open-network-stream (name buffer host service)
(let* ((process-connection-type nil)
- (process (start-process name buffer "ruby" "-rsocket")))
+ (process (start-process name buffer riece-ruby-command "-rsocket")))
(process-kill-without-query process)
(process-send-string process
- (apply #'concat
- (riece-async-substitute-variables
- (riece-async-substitute-variables
- riece-async-server-program
- 'host
- (concat "'" host "'"))
- 'service
- (if (numberp service)
- (number-to-string service)
- (concat "'" service "'")))))
+ (riece-ruby-substitute-variables
+ (list (cons 'host
+ (concat "'" host "'"))
+ (cons 'service
+ (if (numberp service)
+ (number-to-string service)
+ (concat "'" service "'")))
+ (cons 'max-buffer-size
+ (number-to-string
+ riece-async-max-buffer-size)))))
(process-send-string process "\0\n") ;input to process is needed
(if buffer
(save-excursion