On Aug 9, 2:54 am, Andrea F. [email protected] wrote:
Daniel B. wrote:
Info.getstuff # Null Pointer object
Your script runs smoothly on my system (Ubuntu Linux) returning a proper
NativePointer object. It seems that the issue is related to your
environment rather then FFI.
Ah, yes. I was on OS X. I tried again on Linux.
The Utmpx class will be a subclass of FFI::Struct that mirrors the
layout of the C counterpart. Moreover, as I can see from libc reference
manual[1], utmpx has nested structs within. The good news is that
Ruby-FFI has support for nested structs. The bad one is that you have to
define all the nested structs by hand:
class Pid < FFI::Struct
layout …
end
Looks like FFI has a :pid_t type.
I tried this but I’m still having trouble. Part of the problem may be
that I’m not sure how to declare char[] struct members. The docs
indicate there’s a :char_array type, but FFI doesn’t seem to like it.
require ‘ffi’
class Info
extend FFI::Library
BOOT_TIME = 2
attach_function :setutxent, [], :void
attach_function :getutxent, [], :pointer
attach_function :endutxent, [], :void
class Timeval < FFI::Struct
layout(:tv_sec, :long, :tv_usec, :long)
end
class Utmpx < FFI::Struct
layout(
:ut_user, :char, 32
:ut_id, :char, 4
:ut_line, :char, 32
:ut_pid, :pid_t,
:ut_type, :short,
:ut_tv, Timeval
)
end
def self.getstuff
time = nil
begin
setutxent()
while ent = Utmpx.new(getutxent())
if ent[:ut_type] == BOOT_TIME
time = Time.new(ent[:ut_tv][:tv_sec], ent[:ut_tv]
[:tv_usec])
break
end
end
ensure
endutxent()
end
time
end
end
Info.getstuff
ruby boot_time.rb
boot_time.rb:33:in []': NULL Pointer access attempted (FFI::NullPointerError) from boot_time.rb:33:in
getstuff’
from boot_time.rb:46
Where line 33 is the ent[:ut_type] reference.
Any suggestions?
Regards,
Dan