lib/darwin/sys/admin.rb in sys-admin-1.6.2 vs lib/darwin/sys/admin.rb in sys-admin-1.6.3
- old
+ new
@@ -5,10 +5,13 @@
module Sys
class Admin
private
+ # :no-doc:
+ BUF_MAX = 65536 # Max buf size for retry.
+
attach_function :getlogin_r, [:pointer, :int], :int
attach_function :getpwnam_r, [:string, :pointer, :pointer, :size_t, :pointer], :int
attach_function :getpwuid_r, [:long, :pointer, :pointer, :size_t, :pointer], :int
attach_function :getgrnam_r, [:string, :pointer, :pointer, :size_t, :pointer], :int
attach_function :getgrgid_r, [:long, :pointer, :pointer, :size_t, :pointer], :int
@@ -107,27 +110,34 @@
#
# Sys::Admin.get_group('admin')
# Sys::Admin.get_group(101)
#
def self.get_group(gid)
- buf = FFI::MemoryPointer.new(:char, 1024)
+ size = 1024
+ buf = FFI::MemoryPointer.new(:char, size)
pbuf = FFI::MemoryPointer.new(PasswdStruct)
temp = GroupStruct.new
- if gid.is_a?(String)
- if getgrnam_r(gid, temp, buf, buf.size, pbuf) != 0
- raise Error, "getgrnam_r function failed: " + strerror(FFI.errno)
+ begin
+ if gid.is_a?(String)
+ val = getgrnam_r(gid, temp, buf, buf.size, pbuf)
+ fun = 'getgrnam_r'
+ else
+ val = getgrgid_r(gid, temp, buf, buf.size, pbuf)
+ fun = 'getgrgid_r'
end
- else
- if getgrgid_r(gid, temp, buf, buf.size, pbuf) != 0
- raise Error, "getgrgid_r function failed: " + strerror(FFI.errno)
- end
+ raise SystemCallError.new(fun, val) if val != 0
+ rescue Errno::ERANGE
+ size += 1024
+ raise if size > BUF_MAX
+ buf = FFI::MemoryPointer.new(:char, size)
+ retry
end
ptr = pbuf.read_pointer
if ptr.null?
- raise Error, "no group found for #{gid}"
+ raise Error, "no group found for '#{gid}'"
end
grp = GroupStruct.new(ptr)
get_group_from_struct(grp)
end