node/lib/metasm/metasm/os/remote.rb
def gdb_readresp(timeout=nil, outstr=nil)
		@recv_ctx ||= {}
		@recv_ctx[:state] ||= :nosync
		buf = nil

		while @recv_ctx
			if !@recv_ctx[:rbuf]
				return unless IO.select([@io], nil, nil, timeout)
				if @io.kind_of?(UDPSocket)
					raise Errno::EPIPE if not @recv_ctx[:rbuf] = @io.recvfrom(65536)[0]
				else
					raise Errno::EPIPE if not c = @io.read(1)
				end
			end
			if @recv_ctx[:rbuf]
				c = @recv_ctx[:rbuf].slice!(0, 1)
				@recv_ctx.delete :rbuf if @recv_ctx[:rbuf] == ''
			end

			case @recv_ctx[:state]
			when :nosync
				if c == '$'
					@recv_ctx[:state] = :data
					@recv_ctx[:buf] = ''
				end
			when :data
				if c == '#'
					@recv_ctx[:state] = :csum1
					@recv_ctx[:cs] = ''
				else
					@recv_ctx[:buf] << c
				end
			when :csum1
				@recv_ctx[:cs] << c
				@recv_ctx[:state] = :csum2
			when :csum2
				cs = @recv_ctx[:cs] << c
				buf = @recv_ctx[:buf]
				@recv_ctx = nil
				if cs.downcase == gdb_csum(buf).downcase
					@io.write '+'
				else
					log "transmit error"
					@io.write '-'
					return
				end
			end
		end

		case buf
		when /^E(..)$/
			e = $1.to_i(16)
			log "error #{e} (#{PTrace::ERRNO.index(e)})"
			return
		when /^O([0-9a-fA-F]*)$/
			if not outstr
				first = true
				outstr = ''
			end
			outstr << unhex($1)
			ret = gdb_readresp(timeout, outstr)
			outstr.split("\n").each { |o| log 'gdb: ' + o } if first
			return ret
		end

		log "gdb_readresp: got #{buf[0, 64].inspect}#{'...' if buf.length > 64}" if $DEBUG
		buf
	end
# return buf, or nil on error / csum error
# waits IO.select(timeout) between each char
# outstr is used internally only to handle multiline output string
return buf, or nil on error / csum error
waits IO.select(timeout) between each char
outstr is used internally only to handle multiline output string
return buf or nil on error / csum error waits IO . select ( timeout ) between each char outstr is used internally only to handle multiline output string
def gdb_readresp(timeout=nil, outstr=nil)
		@recv_ctx ||= {}
		@recv_ctx[:state] ||= :nosync
		buf = nil
		while @recv_ctx
			if !@recv_ctx[:rbuf]
				return unless IO.select([@io], nil, nil, timeout)
				if @io.kind_of?(UDPSocket)
					raise Errno::EPIPE if not @recv_ctx[:rbuf] = @io.recvfrom(65536)[0]
				else
					raise Errno::EPIPE if not c = @io.read(1)
				end
			end
			if @recv_ctx[:rbuf]
				c = @recv_ctx[:rbuf].slice!(0, 1)
				@recv_ctx.delete :rbuf if @recv_ctx[:rbuf] == ''
			end
			case @recv_ctx[:state]
			when :nosync
				if c == '$'
					@recv_ctx[:state] = :data
					@recv_ctx[:buf] = ''
				end
			when :data
				if c == '#'
					@recv_ctx[:state] = :csum1
					@recv_ctx[:cs] = ''
				else
					@recv_ctx[:buf] << c
				end
			when :csum1
				@recv_ctx[:cs] << c
				@recv_ctx[:state] = :csum2
			when :csum2
				cs = @recv_ctx[:cs] << c
				buf = @recv_ctx[:buf]
				@recv_ctx = nil
				if cs.downcase == gdb_csum(buf).downcase
					@io.write '+'
				else
					log "transmit error"
					@io.write '-'
					return
				end
			end
		end
		case buf
		when /^E(..)$/
			e = $1.to_i(16)
			log "error #{e} (#{PTrace::ERRNO.index(e)})"
			return
		when /^O([0-9a-fA-F]*)$/
			if not outstr
				first = true
				outstr = ''
			end
			outstr << unhex($1)
			ret = gdb_readresp(timeout, outstr)
			outstr.split("\n").each { |o| log 'gdb: ' + o } if first
			return ret
		end
		log "gdb_readresp: got #{buf[0, 64].inspect}#{'...' if buf.length > 64}" if $DEBUG
		buf
	end
def gdb_readresp ( timeout = nil , outstr = nil ) @recv_ctx ||= { } @recv_ctx [ :state ] ||= :nosync buf = nil while @recv_ctx if ! @recv_ctx [ :rbuf ] return unless IO . select ( [ @io ] , nil , nil , timeout ) if @io . kind_of? ( UDPSocket ) raise Errno :: EPIPE if not @recv_ctx [ :rbuf ] = @io . recvfrom ( 65536 ) [ 0 ] else raise Errno :: EPIPE if not c = @io . read ( 1 ) end end if @recv_ctx [ :rbuf ] c = @recv_ctx [ :rbuf ] . slice! ( 0 , 1 ) @recv_ctx . delete :rbuf if @recv_ctx [ :rbuf ] == '' end case @recv_ctx [ :state ] when :nosync if c == '$' @recv_ctx [ :state ] = :data @recv_ctx [ :buf ] = '' end when :data if c == '#' @recv_ctx [ :state ] = :csum1 @recv_ctx [ :cs ] = '' else @recv_ctx [ :buf ] << c end when :csum1 @recv_ctx [ :cs ] << c @recv_ctx [ :state ] = :csum2 when :csum2 cs = @recv_ctx [ :cs ] << c buf = @recv_ctx [ :buf ] @recv_ctx = nil if cs . downcase == gdb_csum ( buf ) . downcase @io . write '+' else log "transmit error" @io . write '-' return end end end case buf when / ^E(..)$ / e = $1 . to_i ( 16 ) log "error #{e} (#{PTrace::ERRNO.index(e)})" return when / ^O([0-9a-fA-F]*)$ / if not outstr first = true outstr = '' end outstr << unhex ( $1 ) ret = gdb_readresp ( timeout , outstr ) outstr . split ( "\n" ) . each { | o | log 'gdb: ' + o } if first return ret end log "gdb_readresp: got #{buf[0, 64].inspect}#{'...' if buf.length > 64}" if $DEBUG buf end
return buf, or nil on error / csum error
waits IO.select(timeout) between each char
outstr is used internally only to handle multiline output string
return buf or nil on error / csum error waits IO . select ( timeout ) between each char outstr is used internally only to handle multiline output string
timeout
outstr