engine-hacks 0.2.0.pre1

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: 95e4571cc6ce855e88da5f20d9ffcbbb075eb338843240cbc0de0b853064bacf
4
+ data.tar.gz: d37295c1c30e192554bbec47cde9484ad9440475b46f5033d4355e778e7f406a
5
+ SHA512:
6
+ metadata.gz: 3441f2db1981c5ef615e57b9ca1e856b09fd6d126b979a507a235232f76aec9b195b055b79aae1a6758362ab67e5ad5bb72ba8a01268f2a4730fea6e6733090d
7
+ data.tar.gz: 415660b5d73eeadcee378092e9f8902bf6cfaa35d7b13c9da36e48aa858d18a67dfcca906ececf29a98e681282a91c6150d55ecd689cc5fd9905832c712d052a
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in process-wrapper-mid.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rake-compiler", "~> 1.2"
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # EngineHacks Library
2
+
3
+ Ruby Engine-specific extensions to enable SubSpawn.
4
+
5
+ ## Installation
6
+
7
+ For most users, install one the other SubSpawn gems directly instead.
8
+
9
+ Otherwise, install the gem and add to the application's Gemfile by executing:
10
+
11
+ $ bundle add engine-hacks
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ $ gem install engine-hacks
16
+
17
+ ## Usage
18
+
19
+ For most users, use one of the other SubSpawn API's directly.
20
+
21
+ ```rb
22
+ require 'engine-hacks'
23
+ ```
24
+
25
+ An RBS file exists for this gem.
26
+
27
+ ## Development
28
+
29
+ See parent SubSpawn readme
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+
9
+ require 'rake/extensiontask'
10
+
11
+ Rake::ExtensionTask.new "engine_hacks" do |ext|
12
+ ext.lib_dir = "lib/engine-hacks"
13
+ end
14
+
15
+
16
+ task default: :build
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/engine-hacks/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "engine-hacks"
7
+ spec.version = EngineHacks::VERSION
8
+ spec.authors = ["Patrick Plenefisch"]
9
+ spec.email = ["simonpatp@gmail.com"]
10
+
11
+ spec.summary = "Engine-specific hacks to enable implement spawn in Ruby"
12
+ spec.description = "A SubSpawn subproject to provide c/java extensions to modify non-ruby-modifiable classes necessary to implementing SubSpawn, or any other spawn/popen API in pure Ruby"
13
+ final_github = "https://github.com/byteit101/subspawn"
14
+ spec.homepage = final_github
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ #spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = final_github
21
+ spec.metadata["changelog_uri"] = final_github
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(__dir__) do
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
+ end
29
+ end
30
+ spec.require_paths = ["lib"]
31
+
32
+ if RUBY_PLATFORM =~ /java/
33
+ spec.platform = "java"
34
+ else
35
+ spec.platform = Gem::Platform::RUBY
36
+ spec.extensions = ["ext/engine_hacks/extconf.rb"]
37
+ end
38
+
39
+ # For more information and examples about making a new gem, check out our
40
+ # guide at: https://bundler.io/guides/creating_gem.html
41
+
42
+ # You can use Ruby's license, or any of the JRuby tri-license options
43
+ spec.licenses = ["Ruby", "EPL-2.0", "LGPL-2.1-or-later"]
44
+ end
@@ -0,0 +1,64 @@
1
+ #include "ruby/ruby.h"
2
+ #include "ruby/io.h"
3
+ #include "ruby/intern.h"
4
+
5
+ // global to store the thread local name to read for $? and $CHILD_STATUS
6
+ static VALUE status_holder;
7
+
8
+
9
+ // $? accessor. returns `Thread.current[status_holder[0]]`
10
+ static VALUE
11
+ get_CHILD_STATUS(ID _x, VALUE *_y)
12
+ {
13
+ return rb_thread_local_aref(rb_thread_current(), SYM2ID(RARRAY_AREF(status_holder, 0)));
14
+ }
15
+
16
+ // overwrites old $? definition to our defintion, and save the new status thread local name
17
+ static VALUE
18
+ install_status(VALUE self, VALUE new_status)
19
+ {
20
+ rb_define_virtual_variable("$?", get_CHILD_STATUS, 0);
21
+ rb_define_virtual_variable("$CHILD_STATUS", get_CHILD_STATUS, 0);
22
+
23
+ // reset, and save the new state
24
+ rb_ary_clear(status_holder);
25
+ new_status = rb_to_symbol(new_status);
26
+ rb_ary_push(status_holder, new_status);
27
+
28
+ // return the name, converted
29
+ return new_status;
30
+ }
31
+
32
+ static VALUE
33
+ join_pipes(VALUE self, VALUE reader, VALUE writer)
34
+ {
35
+ rb_io_set_write_io(reader, writer);
36
+
37
+ // ensure flags are correct
38
+ RFILE(writer)->fptr->mode |= FMODE_SYNC|FMODE_DUPLEX;
39
+ RFILE(reader)->fptr->mode |= FMODE_SYNC|FMODE_DUPLEX;
40
+ RFILE(writer)->fptr->mode &= ~FMODE_READABLE;
41
+ RFILE(reader)->fptr->mode &= ~FMODE_WRITABLE;
42
+
43
+ // not functional, but what IO.popen does as API
44
+ rb_ivar_set(reader, rb_intern("@tied_io_for_writing"), writer);
45
+ return reader;
46
+
47
+ // TODO: we may need to worry that MRI io.c sets pipe_finalize?
48
+ }
49
+
50
+ void Init_engine_hacks(void)
51
+ {
52
+ VALUE EngineHacks = rb_define_module("EngineHacks");
53
+ VALUE EngineHacksMRI = rb_define_module_under(EngineHacks, "MRI");
54
+
55
+ // hold the status in an array, so we can mark the array, and avoid fiddling with making
56
+ // our own marking stuff for the GC. if we don't mark as gc, SEGV
57
+ status_holder = rb_ary_new();
58
+ rb_global_variable(&status_holder);
59
+
60
+ // Exposed methods. Unsafe, do not call these directly, use the cruby.rb wrapper functions only!
61
+ rb_define_singleton_method(EngineHacksMRI, "install_status!", install_status, 1);
62
+ rb_define_singleton_method(EngineHacksMRI, "join_io", join_pipes, 2);
63
+
64
+ }
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile "engine_hacks/engine_hacks"
@@ -0,0 +1,27 @@
1
+ require 'engine_hacks/engine_hacks'
2
+ require 'English'
3
+
4
+ # TODO: this doesn't actually work
5
+ #alias $BUILTIN_CHILD_STATUS $?
6
+
7
+ module EngineHacks
8
+
9
+ def self.use_child_status symbol
10
+ @symbol = symbol.to_sym
11
+ MRI.install_status! symbol
12
+ end
13
+
14
+ def self.child_status= value
15
+ if defined? @symbol
16
+ Thread.current[@symbol] = value
17
+ else
18
+ nil # not installed yet
19
+ end
20
+ end
21
+
22
+ def self.duplex_io(read, write)
23
+ raise ArgumentError.new("Read argument must be IO") unless read.is_a? IO
24
+ raise ArgumentError.new("Write argument must be IO") unless write.is_a? IO
25
+ MRI.join_io(read, write)
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+
2
+ module EngineHacks
3
+
4
+ def self.use_child_status symbol
5
+ # No-op on JRuby
6
+ nil
7
+ end
8
+
9
+ def self.child_status= status
10
+ require 'jruby'
11
+ JRuby.runtime.current_context.last_exit_status = status
12
+ end
13
+
14
+ def self.duplex_io(read, write)
15
+ raise ArgumentError.new("Read argument must be IO") unless read.is_a? IO
16
+ raise ArgumentError.new("Write argument must be IO") unless write.is_a? IO
17
+ require 'jruby'
18
+ readf = JRuby.ref(read).open_file
19
+ writef = JRuby.ref(read).open_file
20
+ raise ArgumentError.new("Read argument must be JRuby IO") if readf.nil?
21
+ raise ArgumentError.new("Write argument must be JRuby IO") if writef.nil?
22
+ readf.tied_io_for_writing = write
23
+ modes = writef.class
24
+ readf.mode = (readf.mode & ~modes::WRITABLE) | modes::SYNC | modes::DUPLEX
25
+ writef.mode = (writef.mode & ~modes::READABLE) | modes::SYNC | modes::DUPLEX
26
+ return read
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EngineHacks
4
+ VERSION = "0.2.0.pre1"
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'engine-hacks/version'
2
+ if defined? JRUBY_VERSION # or: RUBY_PLATFORM =~ /java/
3
+ # JRuby
4
+ require 'engine-hacks/jruby'
5
+ else
6
+ # MRI or TruffleRuby
7
+ require 'engine-hacks/cruby'
8
+ end
@@ -0,0 +1,15 @@
1
+ module EngineHacks
2
+ # Makes $? use the thread-local variable named
3
+ # Returns nil if thread-local hack not necessary, the
4
+ # Symbol otherwise
5
+ def self.use_child_status: (String | Symbol) -> ?Symbol
6
+
7
+ # Sets $? to the given object. returns nil if use_child_status hasn't
8
+ # been called yet
9
+ def self.child_status=: (Object) -> ?Object
10
+
11
+ # Returns an IO that may be either of the input arguments or a new
12
+ # IO that is a duplex IO where .read calls read.read, and .write calls
13
+ # write.write, etc.
14
+ def self.duplex_io: (IO read, IO write) -> IO
15
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: engine-hacks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Patrick Plenefisch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-05-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A SubSpawn subproject to provide c/java extensions to modify non-ruby-modifiable
14
+ classes necessary to implementing SubSpawn, or any other spawn/popen API in pure
15
+ Ruby
16
+ email:
17
+ - simonpatp@gmail.com
18
+ executables: []
19
+ extensions:
20
+ - ext/engine_hacks/extconf.rb
21
+ extra_rdoc_files: []
22
+ files:
23
+ - ".rspec"
24
+ - Gemfile
25
+ - README.md
26
+ - Rakefile
27
+ - engine-hacks.gemspec
28
+ - ext/engine_hacks/engine_hacks.c
29
+ - ext/engine_hacks/extconf.rb
30
+ - lib/engine-hacks.rb
31
+ - lib/engine-hacks/cruby.rb
32
+ - lib/engine-hacks/jruby.rb
33
+ - lib/engine-hacks/version.rb
34
+ - sig/engine-hacks.rbs
35
+ homepage: https://github.com/byteit101/subspawn
36
+ licenses:
37
+ - Ruby
38
+ - EPL-2.0
39
+ - LGPL-2.1-or-later
40
+ metadata:
41
+ homepage_uri: https://github.com/byteit101/subspawn
42
+ source_code_uri: https://github.com/byteit101/subspawn
43
+ changelog_uri: https://github.com/byteit101/subspawn
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.6.0
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.5.3
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Engine-specific hacks to enable implement spawn in Ruby
63
+ test_files: []