[jruby-dev] [jira] Created: (JRUBY-5067) JRuby FFI bug with getZeroTerminatedByteArray

2010-09-08 Thread Daniel Berger (JIRA)
JRuby FFI bug with getZeroTerminatedByteArray
-

 Key: JRUBY-5067
 URL: http://jira.codehaus.org/browse/JRUBY-5067
 Project: JRuby
  Issue Type: Bug
Affects Versions: JRuby 1.5.2
 Environment: JRuby 1.5.2 and 1.6.0 dev, Ubuntu 10, OpenJDK, java 
version "1.6.0_18"
Reporter: Daniel Berger
Assignee: Thomas E Enebo
 Attachments: hs_err_pid18886.log

See the code below. Calling Net::Proto.getprotoent causes a SIGSEGV. The full 
trace is attached separately.

Here's the code:
{noformat}

require 'ffi'

# The Net module serves as a namespace only.
module Net

  # The Proto class serves as the base class for the various protocol methods.
  class Proto
extend FFI::Library

unless RUBY_PLATFORM == 'java' && JRUBY_VERSION.to_f < 1.5
  ffi_lib(FFI::Library::LIBC)
end

# The version of the net-proto library
VERSION = '1.1.0'

private_class_method :new

private

class ProtocolStruct < FFI::Struct
  layout(
:p_name,:string,
:p_aliases, :pointer,
:p_proto,   :int
  ) 
end

class FFI::Pointer
  def read_array_of_string
elements = []

psz = RUBY_PLATFORM == 'java' ? 4 : self.class.size
loc = self

until ((element = loc.read_pointer).null?)
  elements << element.read_string
  loc += psz
end

 elements
  end
end

ProtoStruct = Struct.new('ProtoStruct', :name, :aliases, :proto)

attach_function 'setprotoent', [:int], :void
attach_function 'endprotoent', [], :void
attach_function 'getprotobyname_r', [:string, :pointer, :pointer, :long, 
:pointer], :int
attach_function 'getprotobynumber_r', [:int, :pointer, :pointer, :long, 
:pointer], :int
attach_function 'getprotoent_r', [:pointer, :string, :long, :pointer], :int

public

# If given a protocol string, returns the corresponding number. If
# given a protocol number, returns the corresponding string.
#
# Returns nil if not found in either case.
#
# Examples:
#
#   Net::Proto.get_protocol('tcp') # => 6
#   Net::Proto.get_protocol(1) # => 'icmp'
#
def self.get_protocol(argument)
  if argument.is_a?(String)
getprotobyname(argument)
  else
getprotobynumber(argument)
  end
end

# Given a protocol string, returns the corresponding number, or nil if
# not found.
#
# Examples:
#
#Net::Proto.getprotobyname('tcp')   # => 6
#Net::Proto.getprotobyname('bogus') # => nil
#
def self.getprotobyname(protocol)
  raise TypeError unless protocol.is_a?(String)

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = FFI::MemoryPointer.new(:char, 1024)

  begin
setprotoent(0)
int = getprotobyname_r(protocol, pptr, buf, buf.size, qptr)
  ensure
endprotoent()
  end

  int > 0 || qptr.get_pointer(0).null? ? nil : 
ProtocolStruct.new(pptr)[:p_proto]
end

# Given a protocol number, returns the corresponding string, or nil if
# not found.
#
# Examples:
#
#   Net::Proto.getprotobynumber(6)   # => 'tcp'
#   Net::Proto.getprotobynumber(999) # => nil
#
def self.getprotobynumber(protocol)
  raise TypeError unless protocol.is_a?(Integer)

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = FFI::MemoryPointer.new(:char, 1024)

  begin
setprotoent(0)
int = getprotobynumber_r(protocol, pptr, buf, buf.size, qptr)
  ensure
endprotoent()
  end

  int > 0 || qptr.get_pointer(0).null? ? nil : 
ProtocolStruct.new(pptr)[:p_name]
end

# In block form, yields each entry from /etc/protocols as a struct of type
# Proto::ProtoStruct. In non-block form, returns an array of structs.
#
# The fields are 'name' (a string), 'aliases' (an array of strings,
# though often only one element), and 'proto' (a number).
#
# Example:
#
#   Net::Proto.getprotoent.each{ |prot|
#  p prot.name
#  p prot.aliases
#  p prot.proto
#   }
#
def self.getprotoent
  structs = block_given? ? nil : []

  pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
  buf  = 1.chr * 1024

  begin
setprotoent(0)

while int = getprotoent_r(pptr, buf, buf.size, qptr)
  break if int > 0 || qptr.null?
  buf = 1.chr * 1024

  ffi_struct = ProtocolStruct.new(pptr) 

  ruby_struct = ProtoStruct.new(
ffi_struct[:p_name],
ffi_struct[:p_aliases].read_array_of_string,
ffi_struct[:p_proto]
  ).freeze

  if block_given?
 

[jruby-dev] [jira] Created: (JRUBY-5068) STDOUT.tty? returns false when running from Cygwin using rxvt (or mintty, putty)

2010-09-08 Thread Andrew Davey (JIRA)
STDOUT.tty? returns false when running from Cygwin using rxvt (or mintty, putty)


 Key: JRUBY-5068
 URL: http://jira.codehaus.org/browse/JRUBY-5068
 Project: JRuby
  Issue Type: Bug
Affects Versions: JRuby 1.5.1
 Environment: Cygwin 1.7
Windows Vista
Java 1.6
Reporter: Andrew Davey
Assignee: Thomas E Enebo


The following command will print false if you run it from cygwin using a 
terminal.

jruby -e 'puts STDOUT.tty?'

If you run the above command from cygwin using the windows console, and/or the 
Windows environment variable CYGWIN contains 'notty', then the tty? returns 
true.

The way that cygwin emulates pty's (which are needed by terminal emulators like 
rvxt and mintty etc) is to redirect stdin and stdout using pipes. 

Calling STDOUT.tty? makes a call to 'isatty' in 
org.jruby.ext.posix.WindowsPOSIX which calls the Win32 function GetFileType(). 
isatty wants GetFileType to return FILE_TYPE_CHAR, instead GetFileType sees 
that STDOUT has been redirected to a pipe (to emulate a pty) and returns 
FILE_TYPE_PIPE.

Forgive me if this is not technically a bug, since there are known issues with 
running non cygwin console apps under cygwin + term.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira



-
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email