sys-uname 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.9.0 - 8-Dec-2011
2
+ * Conversion to FFI.
3
+ * Added some additional methods and information for Solaris.
4
+ * Minor tweaks for 1.9 to silence warnings.
5
+
1
6
  == 0.8.6 - 2-Sep-2011
2
7
  * Fixed a failing test for Ruby 1.9.x.
3
8
  * The gemspec for Windows is now 'universal'.
data/README CHANGED
@@ -1,6 +1,9 @@
1
1
  = Description
2
2
  A Ruby interface for getting operating system information. The name comes
3
- from the Unix 'uname' command, but this library works on Windows as well.
3
+ from the Unix 'uname' command, but this library works on MS Windows as well.
4
+
5
+ = Prerequisites
6
+ ffi 1.0 or later
4
7
 
5
8
  = Installation
6
9
  gem install sys-uname
@@ -15,8 +18,8 @@
15
18
  p Uname.uname
16
19
 
17
20
  = Solaris Notes
18
- Folks building this library on SunOS get two extra methods: architecture()
19
- and platform()
21
+ Users on SunOS get several extra methods: architecture, platform,
22
+ hw_serial, hw_provider, srpc_domain, isa_list, and dhcp_cache.
20
23
 
21
24
  = BSD flavors, including OS X
22
25
  Users on BSD platforms get the extra Uname.model method.
@@ -28,7 +31,7 @@
28
31
 
29
32
  = MS Windows Notes
30
33
  The C version for Windows has been completely scrapped in favor of an OLE
31
- plus WMI approach. It is pure Ruby. Please see the MSDN documentation for
34
+ plus WMI approach. It is pure Ruby. Please see the MSDN documentation for
32
35
  the Win32_OperatingSystem class for a complete list of what each of the
33
36
  UnameStruct members mean.
34
37
 
data/Rakefile CHANGED
@@ -1,73 +1,50 @@
1
1
  require 'rake'
2
- require 'rake/clean'
3
2
  require 'rake/testtask'
3
+ require 'rake/clean'
4
4
  require 'rbconfig'
5
- include Config
6
5
 
7
- WINDOWS = CONFIG['host_os'] =~ /msdos|mswin|win32|windows|mingw|cygwin/i
8
-
9
- CLEAN.include(
10
- '**/*.gem', # Gem files
11
- '**/*.rbc', # Rubinius
12
- '**/*.o', # C object file
13
- '**/*.log', # Ruby extension build log
14
- '**/Makefile', # C Makefile
15
- '**/conftest.dSYM', # OS X build directory
16
- "**/*.#{CONFIG['DLEXT']}" # C shared object
17
- )
18
-
19
- desc "Build the source for C extensions"
20
- task :build => [:clean] do
21
- Dir.chdir("ext"){
22
- ruby "extconf.rb"
23
- sh "make"
24
- cp "uname." + Config::CONFIG['DLEXT'], 'sys'
25
- }
26
- end
6
+ CLEAN.include("**/*.rbc", "**/*.rbx", "**/*.gem")
27
7
 
28
8
  desc "Run the example program"
29
- task :example => [:build] do
30
- if WINDOWS
31
- sh 'ruby -Ilib examples/uname_test.rb'
9
+ task :example do
10
+ if File::ALT_SEPARATOR
11
+ sh 'ruby -Ilib/windows examples/uname_test.rb'
32
12
  else
33
- sh 'ruby -Iext examples/uname_test.rb'
13
+ sh 'ruby -Ilib/unix examples/uname_test.rb'
34
14
  end
35
15
  end
36
16
 
37
- namespace 'gem' do
17
+ namespace :gem do
38
18
  desc "Create the sys-uname gem"
39
- task :create do
19
+ task :create => [:clean] do
40
20
  spec = eval(IO.read('sys-uname.gemspec'))
41
- if WINDOWS
42
- spec.files = spec.files.reject{ |f| f.include?('ext') }
21
+
22
+ if File::ALT_SEPARATOR
43
23
  spec.platform = Gem::Platform::CURRENT
44
24
  spec.platform.cpu = 'universal'
45
25
  spec.platform.version = nil
46
- spec.original_platform = spec.platform
47
- else
48
- spec.files = spec.files.reject{ |f| f.include?('lib') }
49
- spec.extensions = ['ext/extconf.rb']
50
- spec.extra_rdoc_files += ['ext/sys/uname.c']
51
26
  end
27
+
52
28
  Gem::Builder.new(spec).build
53
29
  end
54
30
 
55
31
  desc "Install the sys-uname gem"
56
- task :install => [:create] do
57
- file = Dir['sys-uname*.gem'].first
32
+ task :install => [:build] do
33
+ file = Dir["*.gem"].first
58
34
  sh "gem install #{file}"
59
35
  end
60
36
  end
61
37
 
62
38
  desc "Run the test suite"
63
39
  Rake::TestTask.new("test") do |t|
64
- if WINDOWS
65
- t.libs << 'lib'
40
+ if File::ALT_SEPARATOR
41
+ t.libs << 'lib/windows'
66
42
  else
67
- task :test => :build
68
- t.libs << 'ext'
69
- t.libs.delete('lib')
43
+ t.libs << 'lib/unix'
70
44
  end
45
+
46
+ t.warning = true
47
+ t.verbose = true
71
48
  end
72
49
 
73
50
  task :default => :test
@@ -26,25 +26,25 @@ VERSION
26
26
 
27
27
  == Class Methods
28
28
  Uname.sysname
29
- Returns the operating system name, e.g. "SunOS"
29
+ Returns the operating system name. e.g. "SunOS"
30
30
 
31
31
  Uname.nodename
32
- Returns the nodename. This is usually, but not necessarily, the
32
+ Returns the nodename. This is usually, but not necessarily, the
33
33
  same as the system's hostname.
34
34
 
35
35
  You cannot currently set the nodename (root or otherwise). This may
36
36
  be added in a future release.
37
37
 
38
38
  Uname.machine
39
- Returns the machine hardware type, e.g. "i686"
39
+ Returns the machine hardware type. e.g. "i686"
40
40
 
41
41
  Uname.version
42
- Returns the operating system version. e.g. "5.8". In the case of MS
42
+ Returns the operating system version. e.g. "5.8". In the case of MS
43
43
  Windows, it returns the version plus patch information, separated by
44
44
  a hyphen, e.g. "2915-Service Pack 2".
45
45
 
46
46
  Uname.release
47
- Returns the operating system release, e.g. "2.2.16-3"
47
+ Returns the operating system release. e.g. "2.2.16-3"
48
48
 
49
49
  Uname.uname
50
50
  Returns a struct of type UnameStruct that contains sysname, nodename,
@@ -57,10 +57,10 @@ Uname.uname
57
57
 
58
58
  == Solaris Only
59
59
  Uname.architecture
60
- Returns the instruction set architecture, e.g. "sparc"
60
+ Returns the instruction set architecture. e.g. "sparc"
61
61
 
62
62
  Uname.platform
63
- Returns the platform identifier, e.g. "SUNW,Sun-Blade-100"
63
+ Returns the platform identifier. e.g. "SUNW,Sun-Blade-100"
64
64
 
65
65
  Uname.isa_list
66
66
  Returns a space separated string containing a list of all variant
@@ -88,8 +88,8 @@ Uname.model
88
88
  Returns the model type, e.g. "PowerBook5,1"
89
89
 
90
90
  == HP-UX Only
91
- Uname.id_number
92
- Returns the id number, e.g. 234233587. This is a String, not a Fixnum.
91
+ Uname.id
92
+ Returns the id number, e.g. 234233587. This is a String, not a Fixnum.
93
93
 
94
94
  == Notes
95
95
  Not all of the information that you might be used to seeing with
@@ -109,10 +109,10 @@ Uname.id_number
109
109
  Add additional info for Linux, Solaris, BSD.
110
110
 
111
111
  == License
112
- Artistic 2.0
112
+ Ruby's
113
113
 
114
114
  == Copyright
115
- (C) 2002-2011 Daniel J. Berger
115
+ (C) 2002-2012 Daniel J. Berger
116
116
  All Rights Reserved
117
117
 
118
118
  == Warranty
@@ -5,6 +5,7 @@
5
5
  # should generally be run via the 'rake example' task.
6
6
  ########################################################################
7
7
  require 'sys/uname'
8
+ require 'rbconfig'
8
9
  include Sys
9
10
 
10
11
  puts "VERSION: " + Uname::VERSION
@@ -14,8 +15,8 @@ puts 'Version: ' + Uname.version
14
15
  puts 'Release: ' + Uname.release
15
16
  puts 'Machine: ' + Uname.machine # May be "unknown" on Win32
16
17
 
17
- if RUBY_PLATFORM =~ /sun|solaris/i
18
- print "\nSolaris specific tests\n"
18
+ if RbConfig::CONFIG['host_os'] =~ /sun|solaris/i
19
+ print "\nSolaris specific tests\n"
19
20
  puts "==========================="
20
21
  puts 'Architecture: ' + Uname.architecture
21
22
  puts 'Platform: ' + Uname.platform
@@ -26,13 +27,13 @@ if RUBY_PLATFORM =~ /sun|solaris/i
26
27
  puts 'DHCP Cache: ' + Uname.dhcp_cache # might be empty
27
28
  end
28
29
 
29
- if RUBY_PLATFORM =~ /powerpc|darwin|bsd|mach/i
30
- print "\nBSD/OS X specific tests\n"
30
+ if RbConfig::CONFIG['host_os'] =~ /powerpc|darwin|bsd|mach/i
31
+ print "\nBSD/OS X specific tests\n"
31
32
  puts "======================="
32
33
  puts 'Model: ' + Uname.model
33
34
  end
34
35
 
35
- if RUBY_PLATFORM =~ /hpux/i
36
+ if RbConfig::CONFIG['host_os'] =~ /hpux/i
36
37
  print "\nHP-UX specific tests\n"
37
38
  puts "========================"
38
39
  puts "ID: " + Uname.id
@@ -0,0 +1,327 @@
1
+ require 'ffi'
2
+ require 'rbconfig'
3
+ require 'ostruct'
4
+
5
+ # The Sys module serves as a namespace only.
6
+ module Sys
7
+ # The Uname class encapsulates information about the system.
8
+ class Uname
9
+ extend FFI::Library
10
+ ffi_lib('c')
11
+
12
+ # Error raised if the uname() function fails.
13
+ class Error < StandardError; end
14
+
15
+ # The version of the sys-uname library
16
+ VERSION = '0.9.0'
17
+
18
+ # :stopdoc
19
+
20
+ # Buffer size for uname struct char arrays
21
+ case RbConfig::CONFIG['host_os']
22
+ when /linux/i
23
+ BUFSIZE = 65
24
+ when /bsd/i
25
+ BUFSIZE = 32 # TODO: version method chopped
26
+ when /sunos|solaris/i
27
+ BUFSIZE = 257
28
+ else
29
+ BUFSIZE = 256
30
+ end
31
+
32
+ attach_function :uname, [:pointer], :int
33
+
34
+ begin
35
+ attach_function :sysctl, [:pointer, :uint, :pointer, :pointer, :pointer, :size_t], :int
36
+ CTL_HW = 6 # Generic hardware/cpu
37
+ HW_MODEL = 2 # Specific machine model
38
+ rescue FFI::NotFoundError
39
+ # Ignore. Not suppored.
40
+ end
41
+
42
+ begin
43
+ attach_function :sysinfo, [:int, :pointer, :long], :long
44
+ SI_SYSNAME = 1 # OS name
45
+ SI_HOSTNAME = 2 # Node name
46
+ SI_RELEASE = 3 # Operating system release
47
+ SI_VERSION = 4 # Version field of utsname
48
+ SI_MACHINE = 5 # Machine type
49
+ SI_ARCHITECTURE = 6 # Instruction set architecture
50
+ SI_HW_SERIAL = 7 # Hardware serial number
51
+ SI_HW_PROVIDER = 8 # Hardware manufacturer
52
+ SI_SRPC_DOMAIN = 9 # Secure RPC domain
53
+ SI_PLATFORM = 513 # Platform identifier
54
+ SI_ISALIST = 514 # Supported isalist
55
+ SI_DHCP_CACHE = 515 # Kernel cached DHCPACK
56
+ rescue FFI::NotFoundError
57
+ # Ignore. Not suppored.
58
+ end
59
+
60
+ # Temporarily remove the uname method to avoid function name conflict
61
+ class << self
62
+ alias :uname_c :uname
63
+ remove_method :uname
64
+ end
65
+
66
+ class UnameFFIStruct < FFI::Struct
67
+ members = [
68
+ :sysname, [:char, BUFSIZE],
69
+ :nodename, [:char, BUFSIZE],
70
+ :release, [:char, BUFSIZE],
71
+ :version, [:char, BUFSIZE],
72
+ :machine, [:char, BUFSIZE]
73
+ ]
74
+
75
+ if RbConfig::CONFIG['host_os'] =~ /linux/i
76
+ members.push(:domainname, [:char, BUFSIZE])
77
+ end
78
+
79
+ if RbConfig::CONFIG['host_os'] =~ /hpux/i
80
+ members.push(:__id_number, [:char, BUFSIZE])
81
+ end
82
+
83
+ layout(*members)
84
+ end
85
+
86
+ fields = %w[
87
+ sysname
88
+ nodename
89
+ release
90
+ version
91
+ machine
92
+ ]
93
+
94
+ if RbConfig::CONFIG['host_os'] =~ /linux/i
95
+ fields.push('domainname')
96
+ end
97
+
98
+ if RbConfig::CONFIG['host_os'] =~ /hpux/i
99
+ fields.push('id_number')
100
+ end
101
+
102
+ if RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
103
+ fields.push(
104
+ 'architecture',
105
+ 'dhcp_cache',
106
+ 'hw_provider',
107
+ 'hw_serial',
108
+ 'isa_list',
109
+ 'platform',
110
+ 'srpc_domain'
111
+ )
112
+ end
113
+
114
+ if RbConfig::CONFIG['host_os'] =~ /darwin|bsd/i
115
+ fields.push('model')
116
+ end
117
+
118
+ # :startdoc:
119
+
120
+ UnameStruct = Struct.new("UnameStruct", *fields)
121
+
122
+ # Returns a struct that contains the sysname, nodename, machine, version
123
+ # and release of your system.
124
+ #
125
+ # On OS X it will also include the model.
126
+ #
127
+ # On Solaris, it will also include the architecture and platform.
128
+ #
129
+ # On HP-UX, it will also include the id_number.
130
+ #
131
+ # Example:
132
+ #
133
+ # require 'sys/uname'
134
+ #
135
+ # p Sys::Uname.uname
136
+ #
137
+ def self.uname
138
+ utsname = UnameFFIStruct.new
139
+
140
+ if uname_c(utsname) < 0
141
+ raise Error, "uname() function call failed"
142
+ end
143
+
144
+ struct = UnameStruct.new
145
+ struct[:sysname] = utsname[:sysname].to_s
146
+ struct[:nodename] = utsname[:nodename].to_s
147
+ struct[:release] = utsname[:release].to_s
148
+ struct[:version] = utsname[:version].to_s
149
+ struct[:machine] = utsname[:machine].to_s
150
+
151
+ if RbConfig::CONFIG['host_os'] =~ /darwin|bsd/i
152
+ struct[:model] = get_model()
153
+ end
154
+
155
+ if RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
156
+ struct[:architecture] = get_si(SI_ARCHITECTURE)
157
+ struct[:platform] = get_si(SI_PLATFORM)
158
+ struct[:hw_serial] = get_si(SI_HW_SERIAL)
159
+ struct[:hw_provider] = get_si(SI_HW_PROVIDER)
160
+ struct[:srpc_domain] = get_si(SI_SRPC_DOMAIN)
161
+ struct[:isa_list] = get_si(SI_ISALIST)
162
+ struct[:dhcp_cache] = get_si(SI_DHCP_CACHE)
163
+
164
+ # FFI and Solaris don't get along so well, so we try again
165
+ struct[:sysname] = get_si(SI_SYSNAME) if struct.sysname.empty?
166
+ struct[:nodename] = get_si(SI_HOSTNAME) if struct.nodename.empty?
167
+ struct[:release] = get_si(SI_RELEASE) if struct.release.empty?
168
+ struct[:version] = get_si(SI_VERSION) if struct.version.empty?
169
+ struct[:machine] = get_si(SI_MACHINE) if struct.machine.empty?
170
+ end
171
+
172
+ if RbConfig::CONFIG['host_os'] =~ /hpux/i
173
+ struct[:id_number] = utsname[:__id_number].to_s
174
+ end
175
+
176
+ if RbConfig::CONFIG['host_os'] =~ /linux/i
177
+ struct[:domainname] = utsname[:domainname].to_s
178
+ end
179
+
180
+ # Let's add a members method that works for testing and compatibility
181
+ if struct.members.nil?
182
+ struct.instance_eval(%Q{
183
+ def members
184
+ @table.keys.map{ |k| k.to_s }
185
+ end
186
+ })
187
+ end
188
+
189
+ struct.freeze
190
+ end
191
+
192
+ # Returns the name of this implementation of the operating system.
193
+ #
194
+ # Example:
195
+ #
196
+ # Uname.sysname # => 'SunOS'
197
+ #
198
+ def self.sysname
199
+ uname.sysname
200
+ end
201
+
202
+ # Returns the name of this node within the communications network to
203
+ # which this node is attached, if any. This is often, but not
204
+ # necessarily, the same as the host name.
205
+ #
206
+ # Example:
207
+ #
208
+ # Uname.nodename # => 'your_host.foo.com'
209
+ #
210
+ def self.nodename
211
+ uname.nodename
212
+ end
213
+
214
+ # Returns the current release level of your operating system.
215
+ #
216
+ # Example:
217
+ #
218
+ # Uname.release # => '2.2.16-3'
219
+ #
220
+ def self.release
221
+ uname.release
222
+ end
223
+
224
+ # Returns the current version level of your operating system.
225
+ #
226
+ # Example:
227
+ #
228
+ # Uname.version # => '5.9'
229
+ #
230
+ def self.version
231
+ uname.version
232
+ end
233
+
234
+ # Returns the machine hardware type.
235
+ #
236
+ # Example:
237
+ #
238
+ # Uname.machine # => 'i686'
239
+ #
240
+ def self.machine
241
+ uname.machine
242
+ end
243
+
244
+ if defined? :sysctl
245
+ # Returns the model type.
246
+ #
247
+ # Example:
248
+ #
249
+ # Uname.model # => 'MacBookPro5,3'
250
+ #
251
+ def self.model
252
+ uname.model
253
+ end
254
+ end
255
+
256
+ if defined? :sysinfo
257
+ # The basic instruction set architecture of the current
258
+ # system, e.g. sparc, i386, etc.
259
+ #
260
+ def self.architecture
261
+ uname.architecture
262
+ end
263
+
264
+ # The specific model of the hardware platform, e.g Sun-Blade-1500, etc.
265
+ #
266
+ def self.platform
267
+ uname.platform
268
+ end
269
+
270
+ # The string consisting of the ASCII hexidecimal encoding of the name
271
+ # of the interface configured by boot(1M) followed by the DHCPACK reply
272
+ # from the server.
273
+ #
274
+ def self.dhcp_cache
275
+ uname.dhcp_cache
276
+ end
277
+
278
+ # The variant instruction set architectures executable on the
279
+ # current system.
280
+ #
281
+ def self.isa_list
282
+ uname.isa_list
283
+ end
284
+
285
+ # The ASCII representation of the hardware-specific serial number
286
+ # of the physical machine on which the function is executed.
287
+ #
288
+ def self.hw_serial
289
+ uname.hw_serial.to_i
290
+ end
291
+
292
+ # The name of the of the hardware provider.
293
+ #
294
+ def self.hw_provider
295
+ uname.hw_provider
296
+ end
297
+
298
+ # The Secure Remote Procedure Call domain name.
299
+ #
300
+ def self.srpc_domain
301
+ uname.srpc_domain
302
+ end
303
+ end
304
+
305
+ private
306
+
307
+ # Returns the model for systems that define sysctl().
308
+ #
309
+ def self.get_model
310
+ buf = 0.chr * BUFSIZE
311
+ mib = FFI::MemoryPointer.new(:int, 2).write_array_of_int([CTL_HW, HW_MODEL])
312
+ size = FFI::MemoryPointer.new(:long, 1).write_int(buf.size)
313
+
314
+ sysctl(mib, 2, buf, size, nil, 0)
315
+
316
+ buf.strip
317
+ end
318
+
319
+ # Returns the various sysinfo information based on +flag+.
320
+ #
321
+ def self.get_si(flag)
322
+ buf = 0.chr * BUFSIZE
323
+ sysinfo(flag, buf, BUFSIZE)
324
+ buf.strip
325
+ end
326
+ end
327
+ end