ffi 1.15.5-x64-mingw-ucrt

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +338 -0
  3. data/COPYING +49 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE +24 -0
  6. data/LICENSE.SPECS +22 -0
  7. data/README.md +136 -0
  8. data/Rakefile +191 -0
  9. data/ffi.gemspec +42 -0
  10. data/lib/3.1/ffi_c.so +0 -0
  11. data/lib/ffi/abstract_memory.rb +44 -0
  12. data/lib/ffi/autopointer.rb +203 -0
  13. data/lib/ffi/buffer.rb +4 -0
  14. data/lib/ffi/callback.rb +4 -0
  15. data/lib/ffi/data_converter.rb +67 -0
  16. data/lib/ffi/enum.rb +296 -0
  17. data/lib/ffi/errno.rb +43 -0
  18. data/lib/ffi/ffi.rb +47 -0
  19. data/lib/ffi/io.rb +62 -0
  20. data/lib/ffi/library.rb +592 -0
  21. data/lib/ffi/managedstruct.rb +84 -0
  22. data/lib/ffi/memorypointer.rb +1 -0
  23. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  24. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  25. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  26. data/lib/ffi/platform/aarch64-linux/types.conf +104 -0
  27. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  28. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  29. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  30. data/lib/ffi/platform/arm-linux/types.conf +132 -0
  31. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  32. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  33. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  34. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  35. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  36. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  37. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  38. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  39. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  40. data/lib/ffi/platform/i386-windows/types.conf +52 -0
  41. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  42. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  43. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  44. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  45. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  46. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  47. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  48. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  49. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  50. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  51. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  52. data/lib/ffi/platform/powerpc-linux/types.conf +130 -0
  53. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  54. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  55. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  56. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  57. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  58. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  59. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  60. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  61. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  62. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  63. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  64. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  65. data/lib/ffi/platform/x86_64-darwin/types.conf +130 -0
  66. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  67. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  68. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  69. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  70. data/lib/ffi/platform/x86_64-linux/types.conf +132 -0
  71. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  72. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  73. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  74. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  75. data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
  76. data/lib/ffi/platform.rb +185 -0
  77. data/lib/ffi/pointer.rb +167 -0
  78. data/lib/ffi/struct.rb +316 -0
  79. data/lib/ffi/struct_by_reference.rb +72 -0
  80. data/lib/ffi/struct_layout.rb +96 -0
  81. data/lib/ffi/struct_layout_builder.rb +227 -0
  82. data/lib/ffi/tools/const_generator.rb +232 -0
  83. data/lib/ffi/tools/generator.rb +105 -0
  84. data/lib/ffi/tools/generator_task.rb +32 -0
  85. data/lib/ffi/tools/struct_generator.rb +195 -0
  86. data/lib/ffi/tools/types_generator.rb +137 -0
  87. data/lib/ffi/types.rb +194 -0
  88. data/lib/ffi/union.rb +43 -0
  89. data/lib/ffi/variadic.rb +69 -0
  90. data/lib/ffi/version.rb +3 -0
  91. data/lib/ffi.rb +27 -0
  92. data/rakelib/ffi_gem_helper.rb +65 -0
  93. data/samples/getlogin.rb +8 -0
  94. data/samples/getpid.rb +8 -0
  95. data/samples/gettimeofday.rb +18 -0
  96. data/samples/hello.rb +8 -0
  97. data/samples/inotify.rb +60 -0
  98. data/samples/pty.rb +75 -0
  99. data/samples/qsort.rb +20 -0
  100. metadata +207 -0
data/lib/ffi/types.rb ADDED
@@ -0,0 +1,194 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ # Copyright (c) 2007, 2008 Evan Phoenix
4
+ #
5
+ # This file is part of ruby-ffi.
6
+ #
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are met:
11
+ #
12
+ # * Redistributions of source code must retain the above copyright notice, this
13
+ # list of conditions and the following disclaimer.
14
+ # * Redistributions in binary form must reproduce the above copyright notice
15
+ # this list of conditions and the following disclaimer in the documentation
16
+ # and/or other materials provided with the distribution.
17
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
18
+ # may be used to endorse or promote products derived from this software
19
+ # without specific prior written permission.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
25
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ # see {file:README}
34
+ module FFI
35
+
36
+ # @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type}
37
+ # @param [Symbol] add new type definition's name to add
38
+ # @return [Type]
39
+ # Add a definition type to type definitions.
40
+ def self.typedef(old, add)
41
+ TypeDefs[add] = self.find_type(old)
42
+ end
43
+
44
+ # (see FFI.typedef)
45
+ def self.add_typedef(old, add)
46
+ typedef old, add
47
+ end
48
+
49
+
50
+ # @param [Type, DataConverter, Symbol] name
51
+ # @param [Hash] type_map if nil, {FFI::TypeDefs} is used
52
+ # @return [Type]
53
+ # Find a type in +type_map+ ({FFI::TypeDefs}, by default) from
54
+ # a type objet, a type name (symbol). If +name+ is a {DataConverter},
55
+ # a new {Type::Mapped} is created.
56
+ def self.find_type(name, type_map = nil)
57
+ if name.is_a?(Type)
58
+ name
59
+
60
+ elsif type_map && type_map.has_key?(name)
61
+ type_map[name]
62
+
63
+ elsif TypeDefs.has_key?(name)
64
+ TypeDefs[name]
65
+
66
+ elsif name.is_a?(DataConverter)
67
+ (type_map || TypeDefs)[name] = Type::Mapped.new(name)
68
+ else
69
+ raise TypeError, "unable to resolve type '#{name}'"
70
+ end
71
+ end
72
+
73
+ # List of type definitions
74
+ TypeDefs.merge!({
75
+ # The C void type; only useful for function return types
76
+ :void => Type::VOID,
77
+
78
+ # C boolean type
79
+ :bool => Type::BOOL,
80
+
81
+ # C nul-terminated string
82
+ :string => Type::STRING,
83
+
84
+ # C signed char
85
+ :char => Type::CHAR,
86
+ # C unsigned char
87
+ :uchar => Type::UCHAR,
88
+
89
+ # C signed short
90
+ :short => Type::SHORT,
91
+ # C unsigned short
92
+ :ushort => Type::USHORT,
93
+
94
+ # C signed int
95
+ :int => Type::INT,
96
+ # C unsigned int
97
+ :uint => Type::UINT,
98
+
99
+ # C signed long
100
+ :long => Type::LONG,
101
+
102
+ # C unsigned long
103
+ :ulong => Type::ULONG,
104
+
105
+ # C signed long long integer
106
+ :long_long => Type::LONG_LONG,
107
+
108
+ # C unsigned long long integer
109
+ :ulong_long => Type::ULONG_LONG,
110
+
111
+ # C single precision float
112
+ :float => Type::FLOAT,
113
+
114
+ # C double precision float
115
+ :double => Type::DOUBLE,
116
+
117
+ # C long double
118
+ :long_double => Type::LONGDOUBLE,
119
+
120
+ # Native memory address
121
+ :pointer => Type::POINTER,
122
+
123
+ # 8 bit signed integer
124
+ :int8 => Type::INT8,
125
+ # 8 bit unsigned integer
126
+ :uint8 => Type::UINT8,
127
+
128
+ # 16 bit signed integer
129
+ :int16 => Type::INT16,
130
+ # 16 bit unsigned integer
131
+ :uint16 => Type::UINT16,
132
+
133
+ # 32 bit signed integer
134
+ :int32 => Type::INT32,
135
+ # 32 bit unsigned integer
136
+ :uint32 => Type::UINT32,
137
+
138
+ # 64 bit signed integer
139
+ :int64 => Type::INT64,
140
+ # 64 bit unsigned integer
141
+ :uint64 => Type::UINT64,
142
+
143
+ :buffer_in => Type::BUFFER_IN,
144
+ :buffer_out => Type::BUFFER_OUT,
145
+ :buffer_inout => Type::BUFFER_INOUT,
146
+
147
+ # Used in function prototypes to indicate the arguments are variadic
148
+ :varargs => Type::VARARGS,
149
+ })
150
+
151
+ # This will convert a pointer to a Ruby string (just like `:string`), but
152
+ # also allow to work with the pointer itself. This is useful when you want
153
+ # a Ruby string already containing a copy of the data, but also the pointer
154
+ # to the data for you to do something with it, like freeing it, in case the
155
+ # library handed the memory off to the caller (Ruby-FFI).
156
+ #
157
+ # It's {typedef}'d as +:strptr+.
158
+ class StrPtrConverter
159
+ extend DataConverter
160
+ native_type Type::POINTER
161
+
162
+ # @param [Pointer] val
163
+ # @param ctx not used
164
+ # @return [Array(String, Pointer)]
165
+ # Returns a [ String, Pointer ] tuple so the C memory for the string can be freed
166
+ def self.from_native(val, ctx)
167
+ [ val.null? ? nil : val.get_string(0), val ]
168
+ end
169
+ end
170
+
171
+ typedef(StrPtrConverter, :strptr)
172
+
173
+ # @param type +type+ is an instance of class accepted by {FFI.find_type}
174
+ # @return [Numeric]
175
+ # Get +type+ size, in bytes.
176
+ def self.type_size(type)
177
+ find_type(type).size
178
+ end
179
+
180
+ # Load all the platform dependent types
181
+ begin
182
+ File.open(File.join(Platform::CONF_DIR, 'types.conf'), "r") do |f|
183
+ prefix = "rbx.platform.typedef."
184
+ f.each_line { |line|
185
+ if line.index(prefix) == 0
186
+ new_type, orig_type = line.chomp.slice(prefix.length..-1).split(/\s*=\s*/)
187
+ typedef(orig_type.to_sym, new_type.to_sym)
188
+ end
189
+ }
190
+ end
191
+ typedef :pointer, :caddr_t
192
+ rescue Errno::ENOENT
193
+ end
194
+ end
data/lib/ffi/union.rb ADDED
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright (C) 2009 Andrea Fazzi <andrea.fazzi@alcacoop.it>
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+
32
+ require 'ffi/struct'
33
+
34
+ module FFI
35
+
36
+ class Union < FFI::Struct
37
+ def self.builder
38
+ b = StructLayoutBuilder.new
39
+ b.union = true
40
+ b
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # Copyright (C) 2008, 2009 Wayne Meissner
3
+ # Copyright (C) 2009 Luc Heinrich
4
+ #
5
+ # This file is part of ruby-ffi.
6
+ #
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are met:
11
+ #
12
+ # * Redistributions of source code must retain the above copyright notice, this
13
+ # list of conditions and the following disclaimer.
14
+ # * Redistributions in binary form must reproduce the above copyright notice
15
+ # this list of conditions and the following disclaimer in the documentation
16
+ # and/or other materials provided with the distribution.
17
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
18
+ # may be used to endorse or promote products derived from this software
19
+ # without specific prior written permission.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
25
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ module FFI
34
+ class VariadicInvoker
35
+ def call(*args, &block)
36
+ param_types = Array.new(@fixed)
37
+ param_values = Array.new
38
+ @fixed.each_with_index do |t, i|
39
+ param_values << args[i]
40
+ end
41
+ i = @fixed.length
42
+ while i < args.length
43
+ param_types << FFI.find_type(args[i], @type_map)
44
+ param_values << args[i + 1]
45
+ i += 2
46
+ end
47
+ invoke(param_types, param_values, &block)
48
+ end
49
+
50
+ #
51
+ # Attach the invoker to module +mod+ as +mname+
52
+ #
53
+ def attach(mod, mname)
54
+ invoker = self
55
+ params = "*args"
56
+ call = "call"
57
+ mod.module_eval <<-code
58
+ @@#{mname} = invoker
59
+ def self.#{mname}(#{params})
60
+ @@#{mname}.#{call}(#{params})
61
+ end
62
+ def #{mname}(#{params})
63
+ @@#{mname}.#{call}(#{params})
64
+ end
65
+ code
66
+ invoker
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module FFI
2
+ VERSION = '1.15.5'
3
+ end
data/lib/ffi.rb ADDED
@@ -0,0 +1,27 @@
1
+ if RUBY_ENGINE == 'ruby'
2
+ begin
3
+ require RUBY_VERSION.split('.')[0, 2].join('.') + '/ffi_c'
4
+ rescue Exception
5
+ require 'ffi_c'
6
+ end
7
+
8
+ require 'ffi/ffi'
9
+
10
+ elsif RUBY_ENGINE == 'jruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [9, 2, 20]) >= 0
11
+ JRuby::Util.load_ext("org.jruby.ext.ffi.FFIService")
12
+ require 'ffi/ffi'
13
+
14
+ elsif RUBY_ENGINE == 'truffleruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [20, 1, 0]) >= 0
15
+ require 'truffleruby/ffi_backend'
16
+ require 'ffi/ffi'
17
+
18
+ else
19
+ # Remove the ffi gem dir from the load path, then reload the internal ffi implementation
20
+ $LOAD_PATH.delete(File.dirname(__FILE__))
21
+ $LOAD_PATH.delete(File.join(File.dirname(__FILE__), 'ffi'))
22
+ unless $LOADED_FEATURES.nil?
23
+ $LOADED_FEATURES.delete(__FILE__)
24
+ $LOADED_FEATURES.delete('ffi.rb')
25
+ end
26
+ require 'ffi.rb'
27
+ end
@@ -0,0 +1,65 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_helper'
3
+
4
+ class FfiGemHelper < Bundler::GemHelper
5
+ attr_accessor :cross_platforms
6
+
7
+ def install
8
+ super
9
+
10
+ task "release:guard_clean" => ["release:update_history"]
11
+
12
+ task "release:update_history" do
13
+ update_history
14
+ end
15
+
16
+ task "release:rubygem_push" => ["gem:native", "gem:java"]
17
+ end
18
+
19
+ def hfile
20
+ "CHANGELOG.md"
21
+ end
22
+
23
+ def headline
24
+ '([^\w]*)(\d+\.\d+\.\d+(?:\.\w+)?)([^\w]+)([2Y][0Y][0-9Y][0-9Y]-[0-1M][0-9M]-[0-3D][0-9D])([^\w]*|$)'
25
+ end
26
+
27
+ def reldate
28
+ Time.now.strftime("%Y-%m-%d")
29
+ end
30
+
31
+ def update_history
32
+ hin = File.read(hfile)
33
+ hout = hin.sub(/#{headline}/) do
34
+ raise "#{hfile} isn't up-to-date for version #{version}" unless $2==version.to_s
35
+ $1 + $2 + $3 + reldate + $5
36
+ end
37
+ if hout != hin
38
+ Bundler.ui.confirm "Updating #{hfile} for release."
39
+ File.write(hfile, hout)
40
+ Rake::FileUtilsExt.sh "git", "commit", hfile, "-m", "Update release date in #{hfile}"
41
+ end
42
+ end
43
+
44
+ def tag_version
45
+ Bundler.ui.confirm "Tag release with annotation:"
46
+ m = File.read(hfile).match(/(?<annotation>#{headline}.*?)#{headline}/m) || raise("Unable to find release notes in #{hfile}")
47
+ Bundler.ui.info(m[:annotation].gsub(/^/, " "))
48
+ IO.popen(["git", "tag", "--file=-", version_tag], "w") do |fd|
49
+ fd.write m[:annotation]
50
+ end
51
+ yield if block_given?
52
+ rescue
53
+ Bundler.ui.error "Untagging #{version_tag} due to error."
54
+ sh_with_code "git tag -d #{version_tag}"
55
+ raise
56
+ end
57
+
58
+ def rubygem_push(path)
59
+ cross_platforms.each do |ruby_platform|
60
+ super(path.gsub(/\.gem\z/, "-#{ruby_platform}.gem"))
61
+ end
62
+ super(path.gsub(/\.gem\z/, "-java.gem"))
63
+ super(path)
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ require 'ffi'
2
+
3
+ module Foo
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ attach_function :getlogin, [ ], :string
7
+ end
8
+ puts "getlogin=#{Foo.getlogin}"
data/samples/getpid.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'ffi'
2
+
3
+ module Foo
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ attach_function :getpid, [ ], :int
7
+ end
8
+ puts "My pid=#{Foo.getpid}"
@@ -0,0 +1,18 @@
1
+ require 'ffi'
2
+ require 'rbconfig'
3
+
4
+ class Timeval < FFI::Struct
5
+ layout tv_sec: :ulong, tv_usec: :ulong
6
+ end
7
+ module LibC
8
+ extend FFI::Library
9
+ if FFI::Platform.windows?
10
+ ffi_lib RbConfig::CONFIG["LIBRUBY_SO"]
11
+ else
12
+ ffi_lib FFI::Library::LIBC
13
+ end
14
+ attach_function :gettimeofday, [ :pointer, :pointer ], :int
15
+ end
16
+ t = Timeval.new
17
+ LibC.gettimeofday(t.pointer, nil)
18
+ puts "t.tv_sec=#{t[:tv_sec]} t.tv_usec=#{t[:tv_usec]}"
data/samples/hello.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'ffi'
2
+
3
+ module Foo
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ attach_function("cputs", "puts", [ :string ], :int)
7
+ end
8
+ Foo.cputs("Hello, World via libc puts using FFI on MRI ruby")
@@ -0,0 +1,60 @@
1
+ require 'ffi'
2
+
3
+ module Inotify
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ class Event < FFI::Struct
7
+ layout \
8
+ :wd, :int,
9
+ :mask, :uint,
10
+ :cookie, :uint,
11
+ :len, :uint
12
+ end
13
+ attach_function :init, :inotify_init, [ ], :int
14
+ attach_function :add_watch, :inotify_add_watch, [ :int, :string, :uint ], :int
15
+ attach_function :rm_watch, :inotify_rm_watch, [ :int, :uint ], :int
16
+ attach_function :read, [ :int, :buffer_out, :uint ], :int
17
+ IN_ACCESS=0x00000001
18
+ IN_MODIFY=0x00000002
19
+ IN_ATTRIB=0x00000004
20
+ IN_CLOSE_WRITE=0x00000008
21
+ IN_CLOSE_NOWRITE=0x00000010
22
+ IN_CLOSE=(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
23
+ IN_OPEN=0x00000020
24
+ IN_MOVED_FROM=0x00000040
25
+ IN_MOVED_TO=0x00000080
26
+ IN_MOVE= (IN_MOVED_FROM | IN_MOVED_TO)
27
+ IN_CREATE=0x00000100
28
+ IN_DELETE=0x00000200
29
+ IN_DELETE_SELF=0x00000400
30
+ IN_MOVE_SELF=0x00000800
31
+ # Events sent by the kernel.
32
+ IN_UNMOUNT=0x00002000
33
+ IN_Q_OVERFLOW=0x00004000
34
+ IN_IGNORED=0x00008000
35
+ IN_ONLYDIR=0x01000000
36
+ IN_DONT_FOLLOW=0x02000000
37
+ IN_MASK_ADD=0x20000000
38
+ IN_ISDIR=0x40000000
39
+ IN_ONESHOT=0x80000000
40
+ IN_ALL_EVENTS=(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
41
+ | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
42
+ | IN_MOVED_TO | IN_CREATE | IN_DELETE \
43
+ | IN_DELETE_SELF | IN_MOVE_SELF)
44
+
45
+ end
46
+ if $0 == __FILE__
47
+ fd = Inotify.init
48
+ puts "fd=#{fd}"
49
+ wd = Inotify.add_watch(fd, "/tmp/", Inotify::IN_ALL_EVENTS)
50
+ fp = FFI::IO.for_fd(fd)
51
+ puts "wfp=#{fp}"
52
+ while true
53
+ buf = FFI::Buffer.alloc_out(Inotify::Event.size + 4096, 1, false)
54
+ ev = Inotify::Event.new buf
55
+ ready = IO.select([ fp ], nil, nil, nil)
56
+ n = Inotify.read(fd, buf, buf.total)
57
+ puts "Read #{n} bytes from inotify fd"
58
+ puts "event.wd=#{ev[:wd]} mask=#{ev[:mask]} len=#{ev[:len]} name=#{ev[:len] > 0 ? buf.get_string(16) : 'unknown'}"
59
+ end
60
+ end
data/samples/pty.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'ffi'
2
+
3
+ module PTY
4
+ private
5
+ module LibC
6
+ extend FFI::Library
7
+ ffi_lib FFI::Library::LIBC
8
+ attach_function :forkpty, [ :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int
9
+ attach_function :openpty, [ :buffer_out, :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int
10
+ attach_function :login_tty, [ :int ], :int
11
+ attach_function :close, [ :int ], :int
12
+ attach_function :strerror, [ :int ], :string
13
+ attach_function :fork, [], :int
14
+ attach_function :execv, [ :string, :buffer_in ], :int
15
+ attach_function :execvp, [ :string, :buffer_in ], :int
16
+ attach_function :dup2, [ :int, :int ], :int
17
+ attach_function :dup, [ :int ], :int
18
+ end
19
+ Buffer = FFI::Buffer
20
+ def self.build_args(args)
21
+ cmd = args.shift
22
+ cmd_args = args.map do |arg|
23
+ MemoryPointer.from_string(arg)
24
+ end
25
+ exec_args = MemoryPointer.new(:pointer, 1 + cmd_args.length + 1)
26
+ exec_cmd = MemoryPointer.from_string(cmd)
27
+ exec_args[0].put_pointer(0, exec_cmd)
28
+ cmd_args.each_with_index do |arg, i|
29
+ exec_args[i + 1].put_pointer(0, arg)
30
+ end
31
+ [ cmd, exec_args ]
32
+ end
33
+ public
34
+ def self.getpty(*args)
35
+ mfdp = Buffer.new :int
36
+ name = Buffer.new 1024
37
+ #
38
+ # All the execv setup is done in the parent, since doing anything other than
39
+ # execv in the child after fork is really flakey
40
+ #
41
+ exec_cmd, exec_args = build_args(args)
42
+ pid = LibC.forkpty(mfdp, name, nil, nil)
43
+ raise "forkpty failed: #{LibC.strerror(FFI.errno)}" if pid < 0
44
+ if pid == 0
45
+ LibC.execvp(exec_cmd, exec_args)
46
+ exit 1
47
+ end
48
+ masterfd = mfdp.get_int(0)
49
+ rfp = FFI::IO.for_fd(masterfd, "r")
50
+ wfp = FFI::IO.for_fd(LibC.dup(masterfd), "w")
51
+ if block_given?
52
+ yield rfp, wfp, pid
53
+ rfp.close unless rfp.closed?
54
+ wfp.close unless wfp.closed?
55
+ else
56
+ [ rfp, wfp, pid ]
57
+ end
58
+ end
59
+ def self.spawn(*args, &block)
60
+ self.getpty("/bin/sh", "-c", args[0], &block)
61
+ end
62
+ end
63
+ module LibC
64
+ extend FFI::Library
65
+ attach_function :close, [ :int ], :int
66
+ attach_function :write, [ :int, :buffer_in, :ulong ], :long
67
+ attach_function :read, [ :int, :buffer_out, :ulong ], :long
68
+ end
69
+ PTY.getpty("/bin/ls", "-alR", "/") { |rfd, wfd, pid|
70
+ #PTY.spawn("ls -laR /") { |rfd, wfd, pid|
71
+ puts "child pid=#{pid}"
72
+ while !rfd.eof? && (buf = rfd.gets)
73
+ puts "child: '#{buf.strip}'"
74
+ end
75
+ }
data/samples/qsort.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'ffi'
2
+
3
+ module LibC
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+ callback :qsort_cmp, [ :pointer, :pointer ], :int
7
+ attach_function :qsort, [ :pointer, :ulong, :ulong, :qsort_cmp ], :int
8
+ end
9
+
10
+ p = FFI::MemoryPointer.new(:int, 2)
11
+ p.put_array_of_int32(0, [ 2, 1 ])
12
+ puts "ptr=#{p.inspect}"
13
+ puts "Before qsort #{p.get_array_of_int32(0, 2).join(', ')}"
14
+ LibC.qsort(p, 2, 4) do |p1, p2|
15
+ i1 = p1.get_int32(0)
16
+ i2 = p2.get_int32(0)
17
+ puts "In block: comparing #{i1} and #{i2}"
18
+ i1 < i2 ? -1 : i1 > i2 ? 1 : 0
19
+ end
20
+ puts "After qsort #{p.get_array_of_int32(0, 2).join(', ')}"