ffi-libc 0.0.3 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0102b721ed989c2427b5531a522da0001f4dfda43cf1c295e8eda3071891e02d
4
+ data.tar.gz: 4e06ead22308e1fdb667d24defc2ea3a069d4737732b1ab046777b663a4d5e00
5
+ SHA512:
6
+ metadata.gz: 9c4a840ac2740ba51db453edc891b17db0fae22dfe5cebdf5598107b175377ba2436d1dfebbead02fec119bc10a39703b64fa74595467100c0ee35952871a303
7
+ data.tar.gz: beca1246d6d97ce653c508025f636c70c0dd19ffbd11ff4ffea569495b230f5d401819c89949607c5caa3b94baacc3be4b0c092933f1a2126ac13bfca8fd8fe5
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on: [ push, pull_request ]
4
+
5
+ jobs:
6
+ tests:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby:
12
+ - 2.4
13
+ - 2.5
14
+ - 2.6
15
+ - 2.7
16
+ - 3.0
17
+ - jruby
18
+ - truffleruby
19
+ name: Ruby ${{ matrix.ruby }}
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ - name: Install dependencies
27
+ run: bundle install --jobs 4 --retry 3
28
+ - name: Run tests
29
+ run: bundle exec rake test
data/.gitignore CHANGED
@@ -1,4 +1,6 @@
1
- doc
2
- pkg
3
- .bundle
4
- .yardoc
1
+ /Gemfile.lock
2
+ /doc/
3
+ /pkg/
4
+ /.bundle
5
+ /.yardoc
6
+ /vendor/bundle
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/ChangeLog.md CHANGED
@@ -1,3 +1,47 @@
1
+ ### 0.1.1 / 2021-09-22
2
+
3
+ * Removed `sys_errlist` and `sys_nerr` variables, as they have been removed
4
+ from glibc (see:
5
+ https://sourceware.org/pipermail/libc-announce/2020/000029.html).
6
+ * Load `libc` via `FFI::Library::LIBC`.
7
+
8
+ ### 0.1.0 / 2013-08-15
9
+
10
+ * Require ffi ~> 1.0.
11
+ * Added `alarm`.
12
+ * Added `clock`.
13
+ * Added `getc`.
14
+ * Added `getchar`.
15
+ * Added `gets`.
16
+ * Added `ungetc`.
17
+ * Added `getifaddrs`.
18
+ * Added `puts`.
19
+ * Added `putchar`.
20
+ * Added `putc`.
21
+ * Added `strcmp`.
22
+ * Added `strncmp`.
23
+ * Added {FFI::LibC::NULL}.
24
+ * Added {FFI::LibC::Ifaddrs}.
25
+ * Added {FFI::LibC.raise_error}.
26
+ * Added {FFI::LibC.each_ifaddr}.
27
+ * Added {FFI::LibC.rusage}.
28
+
29
+ ### 0.0.5 / 2011-05-11
30
+
31
+ * Skip `clearenv`, `memrchr`, `stdin`, `stdout` and `stderr` if they cannot
32
+ be loaded (thanks FreneticEntropy and mephux).
33
+ * The `libc` installed on OSX lacks these functions/global-variables.
34
+ * Opt into `test.rubygems.org`.
35
+
36
+ ### 0.0.4 / 2011-02-03
37
+
38
+ * Require ffi >= 0.6.0, <= 1.1.0:
39
+ * JRuby requires ffi >= 1.0.0.
40
+ * A lot of projects still require ffi ~> 0.6.0.
41
+ * Added `stdin`.
42
+ * Added `stdout`.
43
+ * Added `stderr`.
44
+
1
45
  ### 0.0.3 / 2010-08-03
2
46
 
3
47
  * Load libc from the current process.
@@ -11,10 +55,10 @@
11
55
  * Added the Structs:
12
56
  * {FFI::LibC::InAddr}.
13
57
  * {FFI::LibC::In6Addr}.
14
- * {FFI::LibC::SockAddr}.
15
- * {FFI::LibC::SockAddrDL}.
16
- * {FFI::LibC::SockAddrIn}.
17
- * {FFI::LibC::SockAddrIn6}.
58
+ * {FFI::LibC::Sockaddr}.
59
+ * {FFI::LibC::SockaddrDL}.
60
+ * {FFI::LibC::SockaddrIn}.
61
+ * {FFI::LibC::SockaddrIn6}.
18
62
 
19
63
  ### 0.0.1 / 2010-05-19
20
64
 
data/Gemfile CHANGED
@@ -1,24 +1,11 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group(:runtime) do
4
- gem 'ffi', '~> 0.6.0'
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ gem 'rspec', '~> 3.0'
9
+ gem 'kramdown'
10
+ gem 'yard', '~> 0.9'
5
11
  end
6
-
7
- group(:development) do
8
- gem 'bundler', '~> 0.9.25'
9
- gem 'rake', '~> 0.8.7'
10
- gem 'jeweler', '~> 1.4.0', :git => 'git://github.com/technicalpickles/jeweler.git'
11
- end
12
-
13
- group(:doc) do
14
- case RUBY_PLATFORM
15
- when 'java'
16
- gem 'maruku', '~> 0.6.0'
17
- else
18
- gem 'rdiscount', '~> 1.6.3'
19
- end
20
-
21
- gem 'yard', '~> 0.5.3'
22
- end
23
-
24
- gem 'rspec', '~> 1.3.0', :group => [:development, :test]
data/LICENSE.txt CHANGED
@@ -1,7 +1,4 @@
1
-
2
- The MIT License
3
-
4
- Copyright (c) 2010 Hal Brodigan
1
+ Copyright (c) 2010-2021 Hal Brodigan
5
2
 
6
3
  Permission is hereby granted, free of charge, to any person obtaining
7
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # ffi-libc
2
2
 
3
- * [github.com/postmodern/ffi-libc](http://github.com/postmodern/ffi-libc/)
4
- * [github.com/postmodern/ffi-libc/issues](http://github.com/postmodern/ffi-libc/issues)
5
- * Postmodern (postmodern.mod3 at gmail.com)
3
+ [![CI](https://github.com/postmodern/ffi-libc/actions/workflows/ruby.yml/badge.svg)](https://github.com/postmodern/ffi-libc/actions/workflows/ruby.yml)
4
+ [![Code Climate](https://codeclimate.com/github/postmodern/ffi-libc.svg)](https://codeclimate.com/github/postmodern/ffi-libc)
5
+
6
+ * [Source](https://github.com/postmodern/ffi-libc/)
7
+ * [Issues](https://github.com/postmodern/ffi-libc/issues)
8
+ * [Documentation](https://rubydoc.info/gems/ffi-libc)
6
9
 
7
10
  ## Description
8
11
 
@@ -10,18 +13,122 @@ Useful Ruby FFI bindings for `libc`.
10
13
 
11
14
  ## Features
12
15
 
13
- * Provides common Structs used in `libc`.
14
- * Binds to common functions and global variables in `libc`.
16
+ * Provides common Structs used in `libc`:
17
+ * {FFI::LibC::Ifaddrs}
18
+ * {FFI::LibC::In6Addr}
19
+ * {FFI::LibC::InAddr}
20
+ * {FFI::LibC::SockaddrDL}
21
+ * {FFI::LibC::SockaddrFamily}
22
+ * {FFI::LibC::SockaddrIn6}
23
+ * {FFI::LibC::SockaddrIn}
24
+ * {FFI::LibC::Sockaddr}
25
+ * {FFI::LibC::Timeval}
26
+ * {FFI::LibC::Timezone}
27
+ * {FFI::LibC::RUsage}
28
+ * Binds to common functions and global variables in `libc`:
29
+ * `errno.h`:
30
+ * `sys_errlist` (BSD)
31
+ * `sys_nerr` (BSD)
32
+ * `errno`
33
+ * `unistd.h`:
34
+ * `brk`
35
+ * `sbrk`
36
+ * `getpid`
37
+ * `getppid`
38
+ * `getuid`
39
+ * `geteuid`
40
+ * `getgid`
41
+ * `getegid`
42
+ * `stdlib.h`:
43
+ * `calloc`
44
+ * `malloc`
45
+ * `free`
46
+ * `realloc`
47
+ * `getenv`
48
+ * `putenv`
49
+ * `unsetenv`
50
+ * `clearenv`
51
+ * `time.h`:
52
+ * `time`
53
+ * `sys/time.h`:
54
+ * `gettimeofday`
55
+ * `settimeofday`
56
+ * `sys/resource.h` / `bits/resource.h`:
57
+ * `getrusage`
58
+ * `sys/mman.h`:
59
+ * `mmap`
60
+ * `munmap`
61
+ * `string.h`:
62
+ * `bzero`
63
+ * `memset`
64
+ * `memcpy`
65
+ * `memcmp`
66
+ * `memchr`
67
+ * `memrchr`
68
+ * `strcpy`
69
+ * `strncpy`
70
+ * `strlen`
71
+ * `index`
72
+ * `rindex`
73
+ * `strchr`
74
+ * `strrchr`
75
+ * `strstr`
76
+ * `strerror`
77
+ * `stdio.h`:
78
+ * `stdin`
79
+ * `stdout`
80
+ * `stderr`
81
+ * `fopen`
82
+ * `fdopen`
83
+ * `freopen`
84
+ * `fseek`
85
+ * `ftell`
86
+ * `rewind`
87
+ * `fread`
88
+ * `fwrite`
89
+ * `fgetc`
90
+ * `fgets`
91
+ * `fputc`
92
+ * `fputs`
93
+ * `fflush`
94
+ * `fclose`
95
+ * `clearerr`
96
+ * `feof`
97
+ * `ferror`
98
+ * `fileno`
99
+ * `perror`
100
+ * `netdb.h`:
101
+ * `getnameinfo`
102
+ * `ifaddrs.h`:
103
+ * `getifaddrs`
104
+ * `freeifaddrs`
15
105
 
16
106
  ## Requirements
17
107
 
18
- * [ffi](http://github.com/ffi/ffi) ~> 0.6.0
108
+ * [ffi] ~> 1.0
19
109
 
20
110
  ## Install
21
111
 
22
- $ sudo gem install ffi-libc
112
+ ```shell
113
+ $ gem install ffi-libc
114
+ ```
115
+
116
+ ### gemspec
117
+
118
+ ```ruby
119
+ gem.add_dependency 'ffi-libc', '~> 0.1'
120
+ ```
121
+
122
+ ### Gemfile
123
+
124
+ ```ruby
125
+ gem 'ffi-libc', '~> 0.1'
126
+ ```
23
127
 
24
128
  ## License
25
129
 
130
+ Copyright (c) 2010-2021 Hal Brodigan
131
+
26
132
  See {file:LICENSE.txt} for license information.
27
133
 
134
+ [ffi]: https://github.com/ffi/ffi#readme
data/Rakefile CHANGED
@@ -1,38 +1,13 @@
1
1
  require 'rubygems'
2
- require 'bundler'
3
2
 
4
- begin
5
- Bundler.setup(:development, :doc)
6
- rescue Bundler::BundlerError => e
7
- STDERR.puts e.message
8
- STDERR.puts "Run `bundle install` to install missing gems"
9
- exit e.status_code
10
- end
3
+ require 'rubygems/tasks'
4
+ Gem::Tasks.new
11
5
 
12
- require 'rake'
13
- require 'rake/clean'
14
- require 'jeweler'
15
-
16
- Jeweler::Tasks.new do |gem|
17
- gem.name = 'ffi-libc'
18
- gem.licenses = ['MIT']
19
- gem.summary = %Q{Useful FFI bindings for libc}
20
- gem.email = 'postmodern.mod3@gmail.com'
21
- gem.homepage = %Q{http://github.com/postmodern/ffi-libc}
22
- gem.description = %Q{Useful Ruby FFI bindings for libc.}
23
- gem.authors = ['Postmodern']
24
- gem.has_rdoc = 'yard'
25
- end
26
-
27
- require 'spec/rake/spectask'
28
-
29
- desc "Run all specifications"
30
- Spec::Rake::SpecTask.new(:spec) do |spec|
31
- spec.libs += ['lib', 'spec']
32
- spec.spec_files = FileList['spec/**/*_spec.rb']
33
- spec.spec_opts = ['--options', '.specopts']
34
- end
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new
8
+ task :test => :spec
35
9
  task :default => :spec
36
10
 
37
11
  require 'yard'
38
12
  YARD::Rake::YardocTask.new
13
+ task :doc => :yard
data/ffi-libc.gemspec CHANGED
@@ -1,77 +1,61 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
1
+ # encoding: utf-8
5
2
 
6
- Gem::Specification.new do |s|
7
- s.name = %q{ffi-libc}
8
- s.version = "0.0.3"
3
+ require 'yaml'
9
4
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Postmodern"]
12
- s.date = %q{2010-08-03}
13
- s.description = %q{Useful Ruby FFI bindings for libc.}
14
- s.email = %q{postmodern.mod3@gmail.com}
15
- s.extra_rdoc_files = [
16
- "ChangeLog.md",
17
- "LICENSE.txt",
18
- "README.md"
19
- ]
20
- s.files = [
21
- ".gitignore",
22
- ".specopts",
23
- ".yardopts",
24
- "ChangeLog.md",
25
- "Gemfile",
26
- "LICENSE.txt",
27
- "README.md",
28
- "Rakefile",
29
- "VERSION",
30
- "ffi-libc.gemspec",
31
- "lib/ffi/libc.rb",
32
- "lib/ffi/libc/af.rb",
33
- "lib/ffi/libc/in6_addr.rb",
34
- "lib/ffi/libc/in_addr.rb",
35
- "lib/ffi/libc/libc.rb",
36
- "lib/ffi/libc/sock_addr.rb",
37
- "lib/ffi/libc/sock_addr_dl.rb",
38
- "lib/ffi/libc/sock_addr_family.rb",
39
- "lib/ffi/libc/sock_addr_in.rb",
40
- "lib/ffi/libc/sock_addr_in6.rb",
41
- "lib/ffi/libc/timeval.rb",
42
- "lib/ffi/libc/timezone.rb",
43
- "lib/ffi/libc/types.rb"
44
- ]
45
- s.has_rdoc = %q{yard}
46
- s.homepage = %q{http://github.com/postmodern/ffi-libc}
47
- s.licenses = ["MIT"]
48
- s.require_paths = ["lib"]
49
- s.rubygems_version = %q{1.3.7}
50
- s.summary = %q{Useful FFI bindings for libc}
5
+ Gem::Specification.new do |gem|
6
+ gemspec = YAML.load_file('gemspec.yml')
51
7
 
52
- if s.respond_to? :specification_version then
53
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
- s.specification_version = 3
8
+ gem.name = gemspec.fetch('name')
9
+ gem.version = gemspec.fetch('version') do
10
+ lib_dir = File.join(File.dirname(__FILE__),'lib')
11
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
55
12
 
56
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
- s.add_runtime_dependency(%q<ffi>, ["~> 0.6.0"])
58
- s.add_development_dependency(%q<bundler>, ["~> 0.9.25"])
59
- s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
60
- s.add_development_dependency(%q<jeweler>, ["~> 1.4.0"])
61
- s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
62
- else
63
- s.add_dependency(%q<ffi>, ["~> 0.6.0"])
64
- s.add_dependency(%q<bundler>, ["~> 0.9.25"])
65
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
66
- s.add_dependency(%q<jeweler>, ["~> 1.4.0"])
67
- s.add_dependency(%q<rspec>, ["~> 1.3.0"])
13
+ require 'ffi/libc/version'
14
+ FFI::LibC::VERSION
15
+ end
16
+
17
+ gem.summary = gemspec['summary']
18
+ gem.description = gemspec['description']
19
+ gem.licenses = Array(gemspec['license'])
20
+ gem.authors = Array(gemspec['authors'])
21
+ gem.email = gemspec['email']
22
+ gem.homepage = gemspec['homepage']
23
+ gem.metadata = gemspec['metadata'] if gemspec['metadata']
24
+
25
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
26
+
27
+ gem.files = `git ls-files`.split($/)
28
+ gem.files = glob[gemspec['files']] if gemspec['files']
29
+
30
+ gem.executables = gemspec.fetch('executables') do
31
+ glob['bin/*'].map { |path| File.basename(path) }
32
+ end
33
+ gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
34
+
35
+ gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
36
+ gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
37
+ gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
38
+
39
+ gem.require_paths = Array(gemspec.fetch('require_paths') {
40
+ %w[ext lib].select { |dir| File.directory?(dir) }
41
+ })
42
+
43
+ gem.requirements = gemspec['requirements']
44
+ gem.required_ruby_version = gemspec['required_ruby_version']
45
+ gem.required_rubygems_version = gemspec['required_rubygems_version']
46
+ gem.post_install_message = gemspec['post_install_message']
47
+
48
+ split = lambda { |string| string.split(/,\s*/) }
49
+
50
+ if gemspec['dependencies']
51
+ gemspec['dependencies'].each do |name,versions|
52
+ gem.add_dependency(name,split[versions])
68
53
  end
69
- else
70
- s.add_dependency(%q<ffi>, ["~> 0.6.0"])
71
- s.add_dependency(%q<bundler>, ["~> 0.9.25"])
72
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
73
- s.add_dependency(%q<jeweler>, ["~> 1.4.0"])
74
- s.add_dependency(%q<rspec>, ["~> 1.3.0"])
75
54
  end
76
- end
77
55
 
56
+ if gemspec['development_dependencies']
57
+ gemspec['development_dependencies'].each do |name,versions|
58
+ gem.add_development_dependency(name,split[versions])
59
+ end
60
+ end
61
+ end
data/gemspec.yml ADDED
@@ -0,0 +1,21 @@
1
+ name: ffi-libc
2
+ version: 0.1.1
3
+ summary: Useful FFI bindings for libc
4
+ description: Useful Ruby FFI bindings for libc.
5
+ license: MIT
6
+ authors: Postmodern
7
+ email: postmodern.mod3@gmail.com
8
+ homepage: https://github.com/postmodern/ffi-libc#redme
9
+ has_yard: true
10
+
11
+ metadata:
12
+ documentation_uri: https://rubydoc.info/gems/ffi-libc
13
+ source_code_uri: https://github.com/postmodern/ffi-libc
14
+ bug_tracker_uri: https://github.com/postmodern/ffi-libc/issues
15
+ changelog_uri: https://github.com/postmodern/ffi-libc/blob/master/ChangeLog.md
16
+
17
+ dependencies:
18
+ ffi: ~> 1.0
19
+
20
+ development_dependencies:
21
+ bundler: ~> 2.0
@@ -0,0 +1,93 @@
1
+ require 'ffi/libc/ifaddrs_union'
2
+ require 'ffi/libc/sockaddr'
3
+
4
+ module FFI
5
+ module LibC
6
+ #
7
+ # @since 0.1.0
8
+ #
9
+ class Ifaddrs < FFI::Struct
10
+
11
+ layout :ifa_next, :pointer,
12
+ :ifa_name, :string,
13
+ :ifa_flags, :uint,
14
+ :ifa_addr, :pointer,
15
+ :ifa_netmask, :pointer,
16
+ :ifa_ifu, IfaddrsUnion,
17
+ :ifa_data, :pointer
18
+
19
+ #
20
+ # Gets the next Interface Address in the list.
21
+ #
22
+ # @return [Ifaddrs, nil]
23
+ # The next Interface Address in the list.
24
+ #
25
+ def next
26
+ unless self[:ifa_next].null?
27
+ Ifaddrs.new(self[:ifa_next])
28
+ end
29
+ end
30
+
31
+ #
32
+ # The name of the Interface.
33
+ #
34
+ # @return [String]
35
+ # The name.
36
+ #
37
+ def name
38
+ self[:ifa_name]
39
+ end
40
+
41
+ #
42
+ # The flags of the Interface.
43
+ #
44
+ # @return [Integer]
45
+ # The flags.
46
+ #
47
+ def flags
48
+ self[:ifa_flags]
49
+ end
50
+
51
+ #
52
+ # The address of the Interface.
53
+ #
54
+ # @return [Sockaddr]
55
+ # The basic socket address.
56
+ #
57
+ def addr
58
+ Sockaddr.new(self[:ifa_addr])
59
+ end
60
+
61
+ #
62
+ # The netmask of the Interface.
63
+ #
64
+ # @return [Sockaddr]
65
+ # The socket address containing the netmask.
66
+ #
67
+ def netmask
68
+ Sockaddr.new(self[:ifa_netmask])
69
+ end
70
+
71
+ #
72
+ # The broadcast address of the Interface.
73
+ #
74
+ # @return [Sockaddr]
75
+ # The broadcast address.
76
+ #
77
+ def broadaddr
78
+ Sockaddr.new(self[:ifa_ifu][:ifu_broadaddr])
79
+ end
80
+
81
+ #
82
+ # The destination address of the Interface.
83
+ #
84
+ # @return [Sockaddr]
85
+ # The destination address.
86
+ #
87
+ def dstaddr
88
+ Sockaddr.new(self[:ifa_ifu][:ifu_dstaddr])
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,15 @@
1
+ require 'ffi'
2
+
3
+ module FFI
4
+ module LibC
5
+ #
6
+ # @since 0.1.0
7
+ #
8
+ class IfaddrsUnion < FFI::Union
9
+
10
+ layout :ifu_broadaddr, :pointer,
11
+ :ifu_dstaddr, :pointer
12
+
13
+ end
14
+ end
15
+ end
data/lib/ffi/libc/libc.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'ffi/libc/types'
2
2
  require 'ffi/libc/timeval'
3
3
  require 'ffi/libc/timezone'
4
+ require 'ffi/libc/ifaddrs'
5
+ require 'ffi/libc/rusage'
4
6
 
5
7
  require 'ffi'
6
8
 
@@ -8,13 +10,23 @@ module FFI
8
10
  module LibC
9
11
  extend FFI::Library
10
12
 
11
- ffi_lib [FFI::CURRENT_PROCESS, 'c']
13
+ ffi_lib FFI::Library::LIBC
14
+
15
+ # The NULL constant
16
+ NULL = nil
12
17
 
13
18
  # errno.h
14
- attach_variable :sys_errlist, :pointer
15
- attach_variable :sys_nerr, :int
19
+ begin
20
+ attach_variable :sys_errlist, :pointer
21
+ attach_variable :sys_nerr, :int
22
+ rescue FFI::NotFoundError
23
+ end
16
24
  attach_variable :errno, :int
17
25
 
26
+ def self.raise_error(error=self.errno)
27
+ raise(strerror(error))
28
+ end
29
+
18
30
  # unistd.h
19
31
  attach_function :brk, [:pointer], :int
20
32
  attach_function :sbrk, [:pointer], :pointer
@@ -24,6 +36,7 @@ module FFI
24
36
  attach_function :geteuid, [], :uid_t
25
37
  attach_function :getgid, [], :gid_t
26
38
  attach_function :getegid, [], :gid_t
39
+ attach_function :alarm, [:uint], :uint
27
40
 
28
41
  # stdlib.h
29
42
  attach_function :calloc, [:size_t, :size_t], :pointer
@@ -33,9 +46,15 @@ module FFI
33
46
  attach_function :getenv, [:string], :string
34
47
  attach_function :putenv, [:string], :int
35
48
  attach_function :unsetenv, [:string], :int
36
- attach_function :clearenv, [], :int
49
+
50
+ begin
51
+ attach_function :clearenv, [], :int
52
+ rescue FFI::NotFoundError
53
+ # clearenv is not available on OSX
54
+ end
37
55
 
38
56
  # time.h
57
+ attach_function :clock, [], :clock_t
39
58
  attach_function :time, [:pointer], :time_t
40
59
 
41
60
  # sys/time.h
@@ -49,33 +68,48 @@ module FFI
49
68
  # string.h
50
69
  attach_function :bzero, [:pointer, :size_t], :void
51
70
  attach_function :memset, [:pointer, :int, :size_t], :pointer
52
- attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
53
- attach_function :memcmp, [:pointer, :pointer, :size_t], :int
54
- attach_function :memchr, [:pointer, :int, :size_t], :pointer
55
- attach_function :memrchr, [:pointer, :int, :size_t], :pointer
56
- attach_function :strcpy, [:string, :string], :pointer
57
- attach_function :strncpy, [:string, :string, :size_t], :pointer
58
- attach_function :strlen, [:string], :size_t
59
- attach_function :index, [:string, :int], :string
60
- attach_function :rindex, [:string, :int], :string
61
- attach_function :strchr, [:string, :int], :string
62
- attach_function :strrchr, [:string, :int], :string
63
- attach_function :strstr, [:string, :string], :string
71
+ attach_function :memcpy, [:buffer_out, :buffer_in, :size_t], :pointer
72
+ attach_function :memcmp, [:buffer_in, :buffer_in, :size_t], :int
73
+ attach_function :memchr, [:buffer_in, :int, :size_t], :pointer
74
+
75
+ begin
76
+ attach_function :memrchr, [:buffer_in, :int, :size_t], :pointer
77
+ rescue FFI::NotFoundError
78
+ # memrchr is not available on OSX
79
+ end
80
+
81
+ attach_function :strcpy, [:buffer_out, :string], :pointer
82
+ attach_function :strncpy, [:buffer_out, :string, :size_t], :pointer
83
+ attach_function :strcmp, [:buffer_in, :buffer_in], :int
84
+ attach_function :strncmp, [:buffer_in, :buffer_in, :size_t], :int
85
+ attach_function :strlen, [:buffer_in], :size_t
86
+ attach_function :index, [:buffer_in, :int], :pointer
87
+ attach_function :rindex, [:buffer_in, :int], :pointer
88
+ attach_function :strchr, [:buffer_in, :int], :pointer
89
+ attach_function :strrchr, [:buffer_in, :int], :pointer
90
+ attach_function :strstr, [:buffer_in, :string], :pointer
64
91
  attach_function :strerror, [:int], :string
65
92
 
66
- # stdio.h
93
+ begin
94
+ attach_variable :stdin, :pointer
95
+ attach_variable :stdout, :pointer
96
+ attach_variable :stderr, :pointer
97
+ rescue FFI::NotFoundError
98
+ # stdin, stdout, stderr are not available on OSX
99
+ end
100
+
67
101
  attach_function :fopen, [:string, :string], :FILE
68
102
  attach_function :fdopen, [:int, :string], :FILE
69
103
  attach_function :freopen, [:string, :string, :FILE], :FILE
70
104
  attach_function :fseek, [:FILE, :long, :int], :int
71
105
  attach_function :ftell, [:FILE], :long
72
106
  attach_function :rewind, [:FILE], :void
73
- attach_function :fread, [:pointer, :size_t, :size_t, :FILE], :size_t
74
- attach_function :fwrite, [:pointer, :size_t, :size_t, :FILE], :size_t
107
+ attach_function :fread, [:buffer_out, :size_t, :size_t, :FILE], :size_t
108
+ attach_function :fwrite, [:buffer_in, :size_t, :size_t, :FILE], :size_t
75
109
  attach_function :fgetc, [:FILE], :int
76
- attach_function :fgets, [:pointer, :int, :FILE], :pointer
110
+ attach_function :fgets, [:buffer_out, :int, :FILE], :pointer
77
111
  attach_function :fputc, [:int, :FILE], :int
78
- attach_function :fputs, [:string, :FILE], :int
112
+ attach_function :fputs, [:buffer_in, :FILE], :int
79
113
  attach_function :fflush, [:FILE], :int
80
114
  attach_function :fclose, [:FILE], :int
81
115
  attach_function :clearerr, [:FILE], :void
@@ -83,5 +117,104 @@ module FFI
83
117
  attach_function :ferror, [:FILE], :int
84
118
  attach_function :fileno, [:FILE], :int
85
119
  attach_function :perror, [:string], :void
120
+
121
+ attach_function :getc, [:FILE], :int
122
+ attach_function :getchar, [], :int
123
+ attach_function :gets, [:buffer_out], :int
124
+ attach_function :ungetc, [:int, :pointer], :int
125
+
126
+ attach_function :putc, [:int, :FILE], :int
127
+ attach_function :putchar, [:int], :int
128
+ attach_function :puts, [:string], :int
129
+
130
+ # netdb.h
131
+ attach_function :getnameinfo, [
132
+ :pointer,
133
+ :socklen_t, :pointer,
134
+ :socklen_t, :pointer,
135
+ :socklen_t, :int
136
+ ], :int
137
+
138
+ NI_MAXHOST = 1024
139
+ NI_MAXSERV = 32
140
+
141
+ NI_NUMERICHOST = 1 # Don't try to look up hostname.
142
+ NI_NUMERICSERV = 2 # Don't convert port number to name.
143
+ NI_NOFQDN = 4 # Only return nodename portion.
144
+ NI_NAMEREQD = 8 # Don't return numeric addresses.
145
+ NI_DGRAM = 16 # Look up UDP service rather than TCP.
146
+
147
+ # ifaddrs.h
148
+ attach_function :getifaddrs, [:pointer], :int
149
+ attach_function :freeifaddrs, [:pointer], :void
150
+
151
+ #
152
+ # Enumerates over the Interface Addresses.
153
+ #
154
+ # @yield [ifaddr]
155
+ # The given block will be passed each Interface Address.
156
+ #
157
+ # @yieldparam [Ifaddrs] ifaddr
158
+ # An Interface Address.
159
+ #
160
+ # @return [Enumerator]
161
+ # If no block is given, an enumerator will be returned.
162
+ #
163
+ # @since 0.1.0
164
+ #
165
+ def self.each_ifaddr
166
+ return enum_for(__method__) unless block_given?
167
+
168
+ ptr = MemoryPointer.new(:pointer)
169
+
170
+ if getifaddrs(ptr) == -1
171
+ raise_error
172
+ end
173
+
174
+ if (ifaddrs = ptr.get_pointer(0)).null?
175
+ return
176
+ end
177
+
178
+ ifaddr = Ifaddrs.new(ifaddrs)
179
+
180
+ while ifaddr
181
+ yield ifaddr
182
+
183
+ ifaddr = ifaddr.next
184
+ end
185
+
186
+ freeifaddrs(ifaddrs)
187
+ end
188
+
189
+ # bits/resource.h (Linux) / sys/resource.h (Darwin)
190
+ RUSAGE_SELF = 0
191
+ RUSAGE_CHILDREN = -1
192
+ RUSAGE_THREAD = 1 # Linux/glibc only
193
+
194
+ attach_function :getrusage, [:int, :pointer], :int
195
+
196
+ #
197
+ # Gets the RUsage for the user.
198
+ #
199
+ # @param [RUSAGE_SELF, RUSAGE_CHILDREN, RUSAGE_THREAD] who
200
+ # Whome to get RUsage statistics for.
201
+ #
202
+ # @return [RUsage]
203
+ # The RUsage statistics.
204
+ #
205
+ # @raise [RuntimeError]
206
+ # An error has occurred.
207
+ #
208
+ # @since 0.1.0
209
+ #
210
+ def self.rusage(who=RUSAGE_SELF)
211
+ rusage = RUsage.new
212
+
213
+ unless (ret = getrusage(who,rusage)) == 0
214
+ raise_error(ret)
215
+ end
216
+
217
+ return rusage
218
+ end
86
219
  end
87
220
  end
@@ -0,0 +1,30 @@
1
+ require 'ffi/libc/types'
2
+ require 'ffi/libc/timeval'
3
+
4
+ module FFI
5
+ module LibC
6
+ #
7
+ # @since 0.1.0
8
+ #
9
+ class RUsage < FFI::Struct
10
+
11
+ layout :ru_utime, Timeval,
12
+ :ru_stime, Timeval,
13
+ :ru_maxrss, :long,
14
+ :ru_ixrss, :long,
15
+ :ru_idrss, :long,
16
+ :ru_isrss, :long,
17
+ :ru_minflt, :long,
18
+ :ru_majflt, :long,
19
+ :ru_nswap, :long,
20
+ :ru_inblock, :long,
21
+ :ru_oublock, :long,
22
+ :ru_msgsnd, :long,
23
+ :ru_msgrcv, :long,
24
+ :ru_nsignals, :long,
25
+ :ru_nvcsw, :long,
26
+ :ru_nivcsw, :long
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ require 'ffi/libc/types'
2
+ require 'ffi/libc/sockaddr_family'
3
+
4
+ module FFI
5
+ module LibC
6
+ #
7
+ # The generic `sockaddr` structure.
8
+ #
9
+ class Sockaddr < SockaddrFamily
10
+
11
+ layout :family, :sa_family_t,
12
+ :data, [:char, 14]
13
+
14
+ end
15
+ end
16
+ end
@@ -1,12 +1,12 @@
1
1
  require 'ffi/libc/types'
2
- require 'ffi/libc/sock_addr_family'
2
+ require 'ffi/libc/sockaddr_family'
3
3
 
4
4
  module FFI
5
5
  module LibC
6
6
  #
7
7
  # The data-link socket address
8
8
  #
9
- class SockAddrDL < SockAddrFamily
9
+ class SockaddrDL < SockaddrFamily
10
10
 
11
11
  layout :len, :uint8,
12
12
  :family, :sa_family_t,
@@ -5,7 +5,7 @@ module FFI
5
5
  #
6
6
  # Common abstract superclass for all sockaddr struct classes
7
7
  #
8
- class SockAddrFamily < ::FFI::Struct
8
+ class SockaddrFamily < ::FFI::Struct
9
9
 
10
10
  end
11
11
  end
@@ -0,0 +1,19 @@
1
+ require 'ffi/libc/types'
2
+ require 'ffi/libc/sockaddr_family'
3
+
4
+ module FFI
5
+ module LibC
6
+ #
7
+ # sockaddr inet, always good to have around
8
+ #
9
+ class SockaddrIn < SockaddrFamily
10
+
11
+ layout :len, :uint8,
12
+ :family, :sa_family_t,
13
+ :port, :in_port_t,
14
+ :addr, :in_addr_t,
15
+ :_sa_zero, [:uint8, 8]
16
+
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,5 @@
1
1
  require 'ffi/libc/types'
2
+ require 'ffi/libc/sockaddr_family'
2
3
  require 'ffi/libc/in6_addr'
3
4
 
4
5
  module FFI
@@ -6,7 +7,7 @@ module FFI
6
7
  #
7
8
  # IPv6 socket address
8
9
  #
9
- class SockAddrIn6 < SockAddrFamily
10
+ class SockaddrIn6 < SockaddrFamily
10
11
 
11
12
  layout :len, :uint8,
12
13
  :family, :sa_family_t,
@@ -7,5 +7,8 @@ module FFI
7
7
  typedef :pointer, :FILE
8
8
  typedef :uint32, :in_addr_t
9
9
  typedef :uint16, :in_port_t
10
+
11
+ # time.h
12
+ typedef :long, :clock_t
10
13
  end
11
14
  end
data/lib/ffi/libc.rb CHANGED
@@ -1,2 +1,13 @@
1
1
  require 'ffi/libc/types'
2
+ require 'ffi/libc/af'
3
+ require 'ffi/libc/ifaddrs'
4
+ require 'ffi/libc/in_addr'
5
+ require 'ffi/libc/in6_addr'
6
+ require 'ffi/libc/sockaddr'
7
+ require 'ffi/libc/sockaddr_dl'
8
+ require 'ffi/libc/sockaddr_in'
9
+ require 'ffi/libc/sockaddr_in6'
10
+ require 'ffi/libc/timeval'
11
+ require 'ffi/libc/timezone'
12
+ require 'ffi/libc/rusage'
2
13
  require 'ffi/libc/libc'
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'ffi/libc/ifaddrs'
3
+
4
+ describe Ifaddrs do
5
+ subject { LibC.each_ifaddr.first }
6
+
7
+ it "should have a name" do
8
+ expect(subject.name).to_not be_empty
9
+ end
10
+
11
+ it "should have flags" do
12
+ expect(subject.flags).to be_kind_of(Integer)
13
+ end
14
+
15
+ it "should have an addr" do
16
+ expect(subject.addr).to be_kind_of(Sockaddr)
17
+ end
18
+
19
+ it "should have an netmask" do
20
+ expect(subject.netmask).to be_kind_of(Sockaddr)
21
+ end
22
+
23
+ it "should have a broadcast addr" do
24
+ expect(subject.broadaddr).to be_kind_of(Sockaddr)
25
+ end
26
+
27
+ it "should have a destination addr" do
28
+ expect(subject.dstaddr).to be_kind_of(Sockaddr)
29
+ end
30
+ end
data/spec/libc_spec.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'ffi/libc'
3
+
4
+ describe FFI::LibC do
5
+ describe "NULL" do
6
+ subject { described_class::NULL }
7
+
8
+ it { expect(subject).to be == nil }
9
+ end
10
+
11
+ describe "each_ifaddr" do
12
+ it "should yield Ifaddrs" do
13
+ addrs = []
14
+
15
+ described_class.each_ifaddr do |ifaddr|
16
+ addrs << ifaddr
17
+ end
18
+
19
+ expect(addrs).to all(be_kind_of(Ifaddrs))
20
+ end
21
+
22
+ context "when not given a block" do
23
+ subject { described_class.each_ifaddr }
24
+
25
+ it { expect(subject).to be_kind_of(Enumerable) }
26
+ end
27
+ end
28
+
29
+ describe "rusage" do
30
+ subject { described_class.rusage }
31
+
32
+ it "should be able to fetch its own memory usage" do
33
+ expect(subject[:ru_maxrss]).to be > 4000
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ require 'rspec'
2
+ require 'ffi/libc'
3
+
4
+ include FFI
5
+ include FFI::LibC
metadata CHANGED
@@ -1,163 +1,107 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ffi-libc
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 3
9
- version: 0.0.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Postmodern
13
- autorequire:
8
+ autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2010-08-03 00:00:00 -07:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: ffi
22
- requirement: &id001 !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
25
- - - ~>
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 0
29
- - 6
30
- - 0
31
- version: 0.6.0
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
32
20
  type: :runtime
33
21
  prerelease: false
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
36
28
  name: bundler
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
40
- - - ~>
41
- - !ruby/object:Gem::Version
42
- segments:
43
- - 0
44
- - 9
45
- - 25
46
- version: 0.9.25
47
- type: :development
48
- prerelease: false
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: rake
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
- none: false
54
- requirements:
55
- - - ~>
56
- - !ruby/object:Gem::Version
57
- segments:
58
- - 0
59
- - 8
60
- - 7
61
- version: 0.8.7
62
- type: :development
63
- prerelease: false
64
- version_requirements: *id003
65
- - !ruby/object:Gem::Dependency
66
- name: jeweler
67
- requirement: &id004 !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
- - - ~>
71
- - !ruby/object:Gem::Version
72
- segments:
73
- - 1
74
- - 4
75
- - 0
76
- version: 1.4.0
77
- type: :development
78
- prerelease: false
79
- version_requirements: *id004
80
- - !ruby/object:Gem::Dependency
81
- name: rspec
82
- requirement: &id005 !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ~>
86
- - !ruby/object:Gem::Version
87
- segments:
88
- - 1
89
- - 3
90
- - 0
91
- version: 1.3.0
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
92
34
  type: :development
93
35
  prerelease: false
94
- version_requirements: *id005
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
95
41
  description: Useful Ruby FFI bindings for libc.
96
42
  email: postmodern.mod3@gmail.com
97
43
  executables: []
98
-
99
44
  extensions: []
100
-
101
- extra_rdoc_files:
45
+ extra_rdoc_files:
102
46
  - ChangeLog.md
103
47
  - LICENSE.txt
104
48
  - README.md
105
- files:
106
- - .gitignore
107
- - .specopts
108
- - .yardopts
49
+ files:
50
+ - ".github/workflows/ruby.yml"
51
+ - ".gitignore"
52
+ - ".rspec"
53
+ - ".yardopts"
109
54
  - ChangeLog.md
110
55
  - Gemfile
111
56
  - LICENSE.txt
112
57
  - README.md
113
58
  - Rakefile
114
- - VERSION
115
59
  - ffi-libc.gemspec
60
+ - gemspec.yml
116
61
  - lib/ffi/libc.rb
117
62
  - lib/ffi/libc/af.rb
63
+ - lib/ffi/libc/ifaddrs.rb
64
+ - lib/ffi/libc/ifaddrs_union.rb
118
65
  - lib/ffi/libc/in6_addr.rb
119
66
  - lib/ffi/libc/in_addr.rb
120
67
  - lib/ffi/libc/libc.rb
121
- - lib/ffi/libc/sock_addr.rb
122
- - lib/ffi/libc/sock_addr_dl.rb
123
- - lib/ffi/libc/sock_addr_family.rb
124
- - lib/ffi/libc/sock_addr_in.rb
125
- - lib/ffi/libc/sock_addr_in6.rb
68
+ - lib/ffi/libc/rusage.rb
69
+ - lib/ffi/libc/sockaddr.rb
70
+ - lib/ffi/libc/sockaddr_dl.rb
71
+ - lib/ffi/libc/sockaddr_family.rb
72
+ - lib/ffi/libc/sockaddr_in.rb
73
+ - lib/ffi/libc/sockaddr_in6.rb
126
74
  - lib/ffi/libc/timeval.rb
127
75
  - lib/ffi/libc/timezone.rb
128
76
  - lib/ffi/libc/types.rb
129
- has_rdoc: yard
130
- homepage: http://github.com/postmodern/ffi-libc
131
- licenses:
77
+ - spec/ifaddrs_spec.rb
78
+ - spec/libc_spec.rb
79
+ - spec/spec_helper.rb
80
+ homepage: https://github.com/postmodern/ffi-libc#redme
81
+ licenses:
132
82
  - MIT
133
- post_install_message:
83
+ metadata:
84
+ documentation_uri: https://rubydoc.info/gems/ffi-libc
85
+ source_code_uri: https://github.com/postmodern/ffi-libc
86
+ bug_tracker_uri: https://github.com/postmodern/ffi-libc/issues
87
+ changelog_uri: https://github.com/postmodern/ffi-libc/blob/master/ChangeLog.md
88
+ post_install_message:
134
89
  rdoc_options: []
135
-
136
- require_paths:
90
+ require_paths:
137
91
  - lib
138
- required_ruby_version: !ruby/object:Gem::Requirement
139
- none: false
140
- requirements:
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
141
94
  - - ">="
142
- - !ruby/object:Gem::Version
143
- hash: -2959684172308845082
144
- segments:
145
- - 0
146
- version: "0"
147
- required_rubygems_version: !ruby/object:Gem::Requirement
148
- none: false
149
- requirements:
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
150
99
  - - ">="
151
- - !ruby/object:Gem::Version
152
- segments:
153
- - 0
154
- version: "0"
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
155
102
  requirements: []
156
-
157
- rubyforge_project:
158
- rubygems_version: 1.3.7
159
- signing_key:
160
- specification_version: 3
103
+ rubygems_version: 3.2.22
104
+ signing_key:
105
+ specification_version: 4
161
106
  summary: Useful FFI bindings for libc
162
107
  test_files: []
163
-
data/.specopts DELETED
@@ -1 +0,0 @@
1
- --colour --format specdoc
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.3
@@ -1,17 +0,0 @@
1
- require 'ffi/libc/types'
2
- require 'ffi/libc/sock_addr_family'
3
-
4
- module FFI
5
- module LibC
6
- #
7
- # The generic `sock_addr` structure.
8
- #
9
- class SockAddr < SockAddrFamily
10
-
11
- layout :len, :uint8,
12
- :family, :sa_family_t,
13
- :data, :char
14
-
15
- end
16
- end
17
- end
@@ -1,19 +0,0 @@
1
- require 'ffi/libc/types'
2
- require 'ffi/libc/sock_addr_family'
3
-
4
- module FFI
5
- module LibC
6
- #
7
- # sockaddr inet, always good to have around
8
- #
9
- class SockAddrIn < SockAddrFamily
10
-
11
- layout :len, :uint8,
12
- :family, :sa_family_t,
13
- :port, :in_port_t,
14
- :addr, :in_addr_t,
15
- :_sa_zero, [:uint8, 8]
16
-
17
- end
18
- end
19
- end