net-proto 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +9 -0
- data/MANIFEST +6 -6
- data/README +22 -15
- data/Rakefile +7 -58
- data/doc/netproto.txt +14 -17
- data/examples/example_net_proto.rb +11 -11
- data/lib/generic/net/proto.rb +145 -0
- data/lib/linux/net/proto.rb +140 -0
- data/lib/net/proto.rb +10 -0
- data/lib/net/proto/common.rb +37 -0
- data/lib/sunos/net/proto.rb +134 -0
- data/net-proto.gemspec +3 -6
- data/test/test_net_proto.rb +52 -45
- metadata +40 -27
- data/ext/extconf.rb +0 -19
- data/ext/generic/generic.c +0 -168
- data/ext/linux/linux.c +0 -175
- data/ext/sunos/sunos.c +0 -160
- data/ext/version.h +0 -2
- data/ext/windows/windows.c +0 -86
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
== 1.1.0 - 18-Jan-2012
|
2
|
+
* Switched to FFI instead of C backend. Now works with JRuby, too.
|
3
|
+
* Added the generic get_protocol instance method that accepts either a
|
4
|
+
string or an integer and does the right thing. This method should be
|
5
|
+
preferred going forward.
|
6
|
+
* Documentation updates.
|
7
|
+
* Refactored the test suite to use features of test-unit 2.x.
|
8
|
+
* Added a default rake task.
|
9
|
+
|
1
10
|
== 1.0.6 - 22-Oct-2010
|
2
11
|
* Refactored the test suite and removed one test that was implementation
|
3
12
|
dependent and not useful.
|
data/MANIFEST
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
* MANIFEST
|
3
3
|
* README
|
4
4
|
* Rakefile
|
5
|
-
* net-proto.gemspec
|
6
5
|
* doc/netproto.txt
|
6
|
+
* net-proto.gemspec
|
7
|
+
* lib/net/proto.rb
|
8
|
+
* lib/net/proto/common.rb
|
9
|
+
* lib/generic/net/proto.rb
|
10
|
+
* lib/linux/net/proto.rb
|
11
|
+
* lib/sunos/net/proto.rb
|
7
12
|
* examples/example_net_proto.rb
|
8
|
-
* ext/version.h
|
9
|
-
* ext/generic/generic.c
|
10
|
-
* ext/linux/linux.c
|
11
|
-
* ext/sunos/sunos.c
|
12
|
-
* ext/windows/windows.c
|
13
13
|
* test/test_net_proto.rb
|
data/README
CHANGED
@@ -1,34 +1,41 @@
|
|
1
|
-
|
1
|
+
== Description
|
2
2
|
The net-proto package provides a way to get protocol information.
|
3
3
|
|
4
|
-
|
4
|
+
This is a wrapper for the getprotobyname(), getprotobynumber() and
|
5
|
+
the getprotoent() functions.
|
6
|
+
|
7
|
+
== Installation
|
5
8
|
gem install net-proto
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
== Prerequisites
|
11
|
+
ffi 1.0.0 or later.
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
== Synopsis
|
14
|
+
require 'net/proto'
|
12
15
|
|
13
|
-
|
16
|
+
# Using generic method
|
17
|
+
Net::Proto.get_protocol(1) # => 'icmp'
|
18
|
+
Net::Proto.get_protocol('icmp') # => 1
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
# Using type specific methods
|
21
|
+
Net::Proto.getprotobynumber(6) # => 'tcp'
|
22
|
+
Net::Proto.getprotobyname('tcp') # => 6
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
# Iterating over all protocols
|
25
|
+
Net::Proto.getprotoent do |ent|
|
26
|
+
p ent
|
27
|
+
end
|
22
28
|
|
29
|
+
== MS Windows
|
23
30
|
The Proto.getprotoent method is not supported on MS Windows because the
|
24
31
|
underlying function isn't supported by the MS Windows API.
|
25
32
|
|
26
|
-
|
33
|
+
== Why should I use this?
|
27
34
|
Ruby has a predefined set of constants in socket.c in the general form of
|
28
35
|
IPPROTO_XXX, Y. However, using constants in this fashion can be unreliable
|
29
36
|
because it's easy to define your own protocols (I set 'echo' to 7, for
|
30
37
|
example), or to modify/delete entries in /etc/protocols.
|
31
38
|
|
32
|
-
|
39
|
+
== Further Documentation
|
33
40
|
See the 'netproto.txt' file under the 'doc' directory for more details. There
|
34
41
|
is also an example under the 'examples' directory.
|
data/Rakefile
CHANGED
@@ -1,80 +1,29 @@
|
|
1
1
|
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
2
|
require 'rake/testtask'
|
4
|
-
require '
|
5
|
-
include Config
|
6
|
-
|
7
|
-
desc 'Clean the build files for the net-proto source'
|
8
|
-
task :clean do
|
9
|
-
Dir['*.gem'].each{ |f| File.delete(f) }
|
10
|
-
Dir['**/*.rbc'].each{ |f| File.delete(f) }
|
11
|
-
|
12
|
-
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
13
|
-
|
14
|
-
Dir.chdir('ext') do
|
15
|
-
proto_file = 'proto.' + Config::CONFIG['DLEXT']
|
16
|
-
if File.exists?('proto.o') || File.exists?(proto_file)
|
17
|
-
sh "#{make} distclean"
|
18
|
-
end
|
19
|
-
rm_rf('proto.c') if File.exists?('proto.c')
|
20
|
-
rm_rf('net') if File.exists?('net')
|
21
|
-
end
|
22
|
-
|
23
|
-
rm_rf('net') if File.exists?('net')
|
24
|
-
rm_rf('lib') if File.exists?('lib')
|
25
|
-
end
|
3
|
+
require 'rake/clean'
|
26
4
|
|
27
|
-
|
28
|
-
task :build => [:clean] do
|
29
|
-
make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make'
|
30
|
-
Dir.chdir('ext') do
|
31
|
-
ruby 'extconf.rb'
|
32
|
-
sh make
|
33
|
-
build_file = 'proto.' + Config::CONFIG['DLEXT']
|
34
|
-
Dir.mkdir('net') unless File.exists?('net')
|
35
|
-
FileUtils.cp(build_file, 'net')
|
36
|
-
end
|
37
|
-
end
|
5
|
+
CLEAN.include('**/*.gem', '**/*.rbx', '**/*.rbc')
|
38
6
|
|
39
|
-
namespace
|
40
|
-
desc '
|
7
|
+
namespace 'gem' do
|
8
|
+
desc 'Create the net-proto gem'
|
41
9
|
task :create => :clean do
|
42
|
-
rm_rf('lib') if File.exists?('lib')
|
43
|
-
spec = eval(IO.read('net-proto.gemspec'))
|
44
|
-
Gem::Builder.new(spec).build
|
45
|
-
end
|
46
|
-
|
47
|
-
desc 'Build a binary gem'
|
48
|
-
task :create_binary => [:build] do
|
49
|
-
file = 'ext/net/proto.' + CONFIG['DLEXT']
|
50
|
-
mkdir_p('lib/net')
|
51
|
-
mv(file, 'lib/net')
|
52
|
-
|
53
10
|
spec = eval(IO.read('net-proto.gemspec'))
|
54
|
-
spec.extensions = nil
|
55
|
-
spec.files = spec.files.reject{ |f| f.include?('ext/') }
|
56
|
-
spec.platform = Gem::Platform::CURRENT
|
57
|
-
|
58
11
|
Gem::Builder.new(spec).build
|
59
12
|
end
|
60
13
|
|
61
|
-
desc 'Install the net-proto
|
14
|
+
desc 'Install the net-proto gem'
|
62
15
|
task :install => [:create] do
|
63
|
-
ruby 'net-proto.gemspec'
|
64
16
|
file = Dir["net-proto*.gem"].last
|
65
17
|
sh "gem install #{file}"
|
66
18
|
end
|
67
19
|
end
|
68
20
|
|
69
21
|
desc 'Run the example net-proto program'
|
70
|
-
task :example
|
71
|
-
|
72
|
-
ruby '-Iext examples/example_net_proto.rb'
|
22
|
+
task :example do
|
23
|
+
ruby '-Ilib examples/example_net_proto.rb'
|
73
24
|
end
|
74
25
|
|
75
26
|
Rake::TestTask.new do |t|
|
76
|
-
task :test => :build
|
77
|
-
t.libs << 'ext'
|
78
27
|
t.warning = true
|
79
28
|
t.verbose = true
|
80
29
|
end
|
data/doc/netproto.txt
CHANGED
@@ -44,39 +44,36 @@ Proto.getprotoent{ |struct| ... }
|
|
44
44
|
|
45
45
|
== Notes
|
46
46
|
This module uses the reentrant (i.e. thread safe) functions on those
|
47
|
-
platforms that support them.
|
47
|
+
platforms that support them. In some cases, e.g. FreeBSD and HP-UX, the
|
48
48
|
standard function names are reentrant by default (i.e. there is no '_r'
|
49
|
-
version, or it's not needed)
|
50
|
-
all platforms.
|
49
|
+
version, or it's not needed).
|
51
50
|
|
52
51
|
The 'setprotoent()' and 'endprotoent()' functions are not implemented as
|
53
|
-
separate method calls.
|
52
|
+
separate method calls. Rather, these are called internally by the various
|
54
53
|
methods, except on Windows, which does not support them.
|
55
54
|
|
56
55
|
The 'getprotoent()' method is not supported on the MS Windows platform.
|
57
56
|
It's not part of the API as of Windows XP.
|
58
57
|
|
59
58
|
== Known Bugs
|
60
|
-
|
61
|
-
|
59
|
+
None that I'm aware of. Please log any bug reports on the project page
|
60
|
+
at https://github.com/djberg96/net-proto.
|
62
61
|
|
63
62
|
== Future Plans
|
64
|
-
|
65
|
-
|
63
|
+
Use the asynchronous calls (WSAAsyncGetProtoByName and
|
64
|
+
WSAAsyncGetProtoByNumber) on MS Windows systems.
|
66
65
|
|
67
66
|
== Copyright
|
68
|
-
|
69
|
-
|
67
|
+
(C) 2003-2012 Daniel J. Berger
|
68
|
+
All rights reserved.
|
70
69
|
|
71
70
|
== Warranty
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
This package is provided "as is" and without any express or
|
72
|
+
implied warranties, including, without limitation, the implied
|
73
|
+
warranties of merchantability and fitness for a particular purpose.
|
75
74
|
|
76
75
|
== License
|
77
|
-
|
76
|
+
Artistic 2.0
|
78
77
|
|
79
78
|
== Author
|
80
|
-
|
81
|
-
djberg96 at gmail dot com
|
82
|
-
imperator on IRC (Freenode)
|
79
|
+
Daniel J. Berger
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# A generic test program for general futzing. You cna run this example
|
5
5
|
# code via the 'rake example' task.
|
6
6
|
#########################################################################
|
7
|
-
require 'net/proto'
|
7
|
+
require 'net/proto'
|
8
8
|
include Net
|
9
9
|
|
10
10
|
puts "VERSION: " + Proto::VERSION
|
@@ -12,14 +12,14 @@ puts "VERSION: " + Proto::VERSION
|
|
12
12
|
puts "UDP port: " + Proto.getprotobyname("udp").to_s
|
13
13
|
|
14
14
|
unless File::ALT_SEPARATOR
|
15
|
-
|
16
|
-
|
15
|
+
puts "Name\t\tProto\tAliases"
|
16
|
+
puts "=========================="
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
25
|
-
end
|
18
|
+
Proto.getprotoent.each{ |s|
|
19
|
+
if s.name.length > 7
|
20
|
+
puts s.name + "\t" + s.proto.to_s + "\t" + s.aliases.join(", ")
|
21
|
+
else
|
22
|
+
puts s.name + "\t\t" + s.proto.to_s + "\t" + s.aliases.join(", ")
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'net/proto/common'
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
# The Proto class serves as the base class for the various protocol methods.
|
6
|
+
class Proto
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
ffi_lib FFI::Library::LIBC
|
10
|
+
|
11
|
+
if File::ALT_SEPARATOR
|
12
|
+
ffi_lib 'ws2_32'
|
13
|
+
ffi_convention :stdcall
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# These should exist on every platform.
|
19
|
+
attach_function :getprotobyname_c, :getprotobyname, [:string], :pointer
|
20
|
+
attach_function :getprotobynumber_c, :getprotobynumber, [:int], :pointer
|
21
|
+
|
22
|
+
# These are defined on most platforms, but not all.
|
23
|
+
begin
|
24
|
+
attach_function :setprotoent, [:int], :void
|
25
|
+
attach_function :endprotoent, [], :void
|
26
|
+
attach_function :getprotoent_c, :getprotoent, [], :pointer
|
27
|
+
rescue FFI::NotFoundError
|
28
|
+
# Ignore, not supported. Probably Windows.
|
29
|
+
else
|
30
|
+
private_class_method :setprotoent
|
31
|
+
private_class_method :endprotoent
|
32
|
+
private_class_method :getprotoent_c
|
33
|
+
end
|
34
|
+
|
35
|
+
private_class_method :getprotobyname_c
|
36
|
+
private_class_method :getprotobynumber_c
|
37
|
+
|
38
|
+
public
|
39
|
+
|
40
|
+
# If given a protocol string, returns the corresponding number. If
|
41
|
+
# given a protocol number, returns the corresponding string.
|
42
|
+
#
|
43
|
+
# Returns nil if not found in either case.
|
44
|
+
#
|
45
|
+
# Examples:
|
46
|
+
#
|
47
|
+
# Net::Proto.get_protocol('tcp') # => 6
|
48
|
+
# Net::Proto.get_protocol(1) # => 'icmp'
|
49
|
+
#
|
50
|
+
def self.get_protocol(arg)
|
51
|
+
if arg.is_a?(String)
|
52
|
+
getprotobyname(arg)
|
53
|
+
else
|
54
|
+
getprotobynumber(arg)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Given a protocol string, returns the corresponding number, or nil if
|
59
|
+
# not found.
|
60
|
+
#
|
61
|
+
# Examples:
|
62
|
+
#
|
63
|
+
# Net::Proto.getprotobyname('tcp') # => 6
|
64
|
+
# Net::Proto.getprotobyname('bogus') # => nil
|
65
|
+
#
|
66
|
+
def self.getprotobyname(protocol)
|
67
|
+
raise TypeError unless protocol.is_a?(String)
|
68
|
+
|
69
|
+
begin
|
70
|
+
setprotoent(0) if respond_to?(:setprotoent, true)
|
71
|
+
ptr = getprotobyname_c(protocol)
|
72
|
+
struct = ProtocolStruct.new(ptr) unless ptr.null?
|
73
|
+
ensure
|
74
|
+
endprotoent() if respond_to?(:endprotoent, true)
|
75
|
+
end
|
76
|
+
|
77
|
+
ptr.null? ? nil : struct[:p_proto]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Given a protocol number, returns the corresponding string, or nil if
|
81
|
+
# not found.
|
82
|
+
#
|
83
|
+
# Examples:
|
84
|
+
#
|
85
|
+
# Net::Proto.getprotobynumber(6) # => 'tcp'
|
86
|
+
# Net::Proto.getprotobynumber(999) # => nil
|
87
|
+
#
|
88
|
+
def self.getprotobynumber(protocol)
|
89
|
+
raise TypeError unless protocol.is_a?(Integer)
|
90
|
+
|
91
|
+
begin
|
92
|
+
setprotoent(0) if respond_to?(:setprotoent, true)
|
93
|
+
ptr = getprotobynumber_c(protocol)
|
94
|
+
struct = ProtocolStruct.new(ptr) unless ptr.null?
|
95
|
+
ensure
|
96
|
+
endprotoent() if respond_to?(:endprotoent, true)
|
97
|
+
end
|
98
|
+
|
99
|
+
ptr.null? ? nil: struct[:p_name]
|
100
|
+
end
|
101
|
+
|
102
|
+
# In block form, yields each entry from /etc/protocols as a struct of type
|
103
|
+
# Proto::ProtoStruct. In non-block form, returns an array of structs.
|
104
|
+
#
|
105
|
+
# The fields are 'name' (a string), 'aliases' (an array of strings,
|
106
|
+
# though often only one element), and 'proto' (a number).
|
107
|
+
#
|
108
|
+
# Example:
|
109
|
+
#
|
110
|
+
# Net::Proto.getprotoent.each{ |prot|
|
111
|
+
# p prot.name
|
112
|
+
# p prot.aliases
|
113
|
+
# p prot.proto
|
114
|
+
# }
|
115
|
+
#
|
116
|
+
def self.getprotoent
|
117
|
+
raise NoMethodError unless respond_to?(:getprotoent, true)
|
118
|
+
|
119
|
+
structs = block_given? ? nil : []
|
120
|
+
|
121
|
+
begin
|
122
|
+
setprotoent(0)
|
123
|
+
until (ptr = getprotoent_c()).null?
|
124
|
+
ffi_struct = ProtocolStruct.new(ptr)
|
125
|
+
|
126
|
+
ruby_struct = ProtoStruct.new(
|
127
|
+
ffi_struct[:p_name],
|
128
|
+
ffi_struct[:p_aliases].read_array_of_string,
|
129
|
+
ffi_struct[:p_proto]
|
130
|
+
).freeze
|
131
|
+
|
132
|
+
if block_given?
|
133
|
+
yield ruby_struct
|
134
|
+
else
|
135
|
+
structs << ruby_struct
|
136
|
+
end
|
137
|
+
end
|
138
|
+
ensure
|
139
|
+
endprotoent()
|
140
|
+
end
|
141
|
+
|
142
|
+
structs
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'net/proto/common'
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
|
6
|
+
# The Proto class serves as the base class for the various protocol methods.
|
7
|
+
class Proto
|
8
|
+
ffi_lib FFI::Library::LIBC
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attach_function :setprotoent, [:int], :void
|
13
|
+
attach_function :endprotoent, [], :void
|
14
|
+
attach_function :getprotobyname_r, [:string, :pointer, :pointer, :long, :pointer], :int
|
15
|
+
attach_function :getprotobynumber_r, [:int, :pointer, :pointer, :long, :pointer], :int
|
16
|
+
attach_function :getprotoent_r, [:pointer, :pointer, :long, :pointer], :int
|
17
|
+
|
18
|
+
private_class_method :setprotoent, :endprotoent, :getprotobyname_r
|
19
|
+
private_class_method :getprotobynumber_r, :getprotoent_r
|
20
|
+
|
21
|
+
public
|
22
|
+
|
23
|
+
# If given a protocol string, returns the corresponding number. If
|
24
|
+
# given a protocol number, returns the corresponding string.
|
25
|
+
#
|
26
|
+
# Returns nil if not found in either case.
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
#
|
30
|
+
# Net::Proto.get_protocol('tcp') # => 6
|
31
|
+
# Net::Proto.get_protocol(1) # => 'icmp'
|
32
|
+
#
|
33
|
+
def self.get_protocol(argument)
|
34
|
+
if argument.is_a?(String)
|
35
|
+
getprotobyname(argument)
|
36
|
+
else
|
37
|
+
getprotobynumber(argument)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Given a protocol string, returns the corresponding number, or nil if
|
42
|
+
# not found.
|
43
|
+
#
|
44
|
+
# Examples:
|
45
|
+
#
|
46
|
+
# Net::Proto.getprotobyname('tcp') # => 6
|
47
|
+
# Net::Proto.getprotobyname('bogus') # => nil
|
48
|
+
#
|
49
|
+
def self.getprotobyname(protocol)
|
50
|
+
raise TypeError unless protocol.is_a?(String)
|
51
|
+
|
52
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
53
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
54
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
55
|
+
|
56
|
+
begin
|
57
|
+
setprotoent(0)
|
58
|
+
int = getprotobyname_r(protocol, pptr, buf, buf.size, qptr)
|
59
|
+
ensure
|
60
|
+
endprotoent()
|
61
|
+
end
|
62
|
+
|
63
|
+
int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_proto]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Given a protocol number, returns the corresponding string, or nil if
|
67
|
+
# not found.
|
68
|
+
#
|
69
|
+
# Examples:
|
70
|
+
#
|
71
|
+
# Net::Proto.getprotobynumber(6) # => 'tcp'
|
72
|
+
# Net::Proto.getprotobynumber(999) # => nil
|
73
|
+
#
|
74
|
+
def self.getprotobynumber(protocol)
|
75
|
+
raise TypeError unless protocol.is_a?(Integer)
|
76
|
+
|
77
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
78
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
79
|
+
buf = FFI::MemoryPointer.new(:char, 1024)
|
80
|
+
|
81
|
+
begin
|
82
|
+
setprotoent(0)
|
83
|
+
int = getprotobynumber_r(protocol, pptr, buf, buf.size, qptr)
|
84
|
+
ensure
|
85
|
+
endprotoent()
|
86
|
+
end
|
87
|
+
|
88
|
+
int > 0 || qptr.get_pointer(0).null? ? nil : ProtocolStruct.new(pptr)[:p_name]
|
89
|
+
end
|
90
|
+
|
91
|
+
# In block form, yields each entry from /etc/protocols as a struct of type
|
92
|
+
# Proto::ProtoStruct. In non-block form, returns an array of structs.
|
93
|
+
#
|
94
|
+
# The fields are 'name' (a string), 'aliases' (an array of strings,
|
95
|
+
# though often only one element), and 'proto' (a number).
|
96
|
+
#
|
97
|
+
# Example:
|
98
|
+
#
|
99
|
+
# Net::Proto.getprotoent.each{ |prot|
|
100
|
+
# p prot.name
|
101
|
+
# p prot.aliases
|
102
|
+
# p prot.proto
|
103
|
+
# }
|
104
|
+
#
|
105
|
+
def self.getprotoent
|
106
|
+
structs = block_given? ? nil : []
|
107
|
+
|
108
|
+
pptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
109
|
+
qptr = FFI::MemoryPointer.new(ProtocolStruct.size)
|
110
|
+
buf = FFI::MemoryPointer.new(1024)
|
111
|
+
|
112
|
+
begin
|
113
|
+
setprotoent(0)
|
114
|
+
|
115
|
+
while int = getprotoent_r(pptr, buf, buf.size, qptr)
|
116
|
+
break if int > 0 || qptr.null?
|
117
|
+
buf = FFI::MemoryPointer.new(1024)
|
118
|
+
|
119
|
+
ffi_struct = ProtocolStruct.new(pptr)
|
120
|
+
|
121
|
+
ruby_struct = ProtoStruct.new(
|
122
|
+
ffi_struct[:p_name],
|
123
|
+
ffi_struct[:p_aliases].read_array_of_string,
|
124
|
+
ffi_struct[:p_proto]
|
125
|
+
).freeze
|
126
|
+
|
127
|
+
if block_given?
|
128
|
+
yield ruby_struct
|
129
|
+
else
|
130
|
+
structs << ruby_struct
|
131
|
+
end
|
132
|
+
end
|
133
|
+
ensure
|
134
|
+
endprotoent
|
135
|
+
end
|
136
|
+
|
137
|
+
structs
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|