/usr/lib/ruby/vendor_ruby/childprocess/tools/generator.rb is in ruby-childprocess 0.5.9-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | require 'fileutils'
module ChildProcess
module Tools
class Generator
EXE_NAME = "childprocess-sizeof-generator"
TMP_PROGRAM = "childprocess-sizeof-generator.c"
DEFAULT_INCLUDES = %w[stdio.h stddef.h]
def self.generate
new.generate
end
def initialize
@cc = ENV['CC'] || 'gcc'
@out = File.expand_path("../../unix/platform/#{ChildProcess.platform_name}.rb", __FILE__)
@sizeof = {}
@constants = {}
end
def generate
fetch_size 'posix_spawn_file_actions_t', :include => "spawn.h"
fetch_size 'posix_spawnattr_t', :include => "spawn.h"
fetch_size 'sigset_t', :include => "signal.h"
fetch_constant 'POSIX_SPAWN_RESETIDS', :include => 'spawn.h'
fetch_constant 'POSIX_SPAWN_SETPGROUP', :include => 'spawn.h'
fetch_constant 'POSIX_SPAWN_SETSIGDEF', :include => 'spawn.h'
fetch_constant 'POSIX_SPAWN_SETSIGMASK', :include => 'spawn.h'
if ChildProcess.linux?
fetch_constant 'POSIX_SPAWN_USEVFORK', :include => 'spawn.h', :define => {'_GNU_SOURCE' => nil}
end
write
end
def write
FileUtils.mkdir_p(File.dirname(@out))
File.open(@out, 'w') do |io|
io.puts result
end
puts "wrote #{@out}"
end
def fetch_size(type_name, opts = {})
print "sizeof(#{type_name}): "
src = <<-EOF
int main() {
printf("%d", (unsigned int)sizeof(#{type_name}));
return 0;
}
EOF
output = execute(src, opts)
if output.to_i < 1
raise "sizeof(#{type_name}) == #{output.to_i} (output=#{output})"
end
size = output.to_i
@sizeof[type_name] = size
puts size
end
def fetch_constant(name, opts)
print "#{name}: "
src = <<-EOF
int main() {
printf("%d", (unsigned int)#{name});
return 0;
}
EOF
output = execute(src, opts)
value = Integer(output)
@constants[name] = value
puts value
end
def execute(src, opts)
program = Array(opts[:define]).map do |key, value|
<<-SRC
#ifndef #{key}
#define #{key} #{value}
#endif
SRC
end.join("\n")
program << "\n"
includes = Array(opts[:include]) + DEFAULT_INCLUDES
program << includes.map { |include| "#include <#{include}>" }.join("\n")
program << "\n#{src}"
File.open(TMP_PROGRAM, 'w') do |file|
file << program
end
cmd = "#{@cc} #{TMP_PROGRAM} -o #{EXE_NAME}"
system cmd
unless $?.success?
raise "failed to compile program: #{cmd.inspect}\n#{program}"
end
output = `./#{EXE_NAME} 2>&1`
unless $?.success?
raise "failed to run program: #{cmd.inspect}\n#{output}"
end
output.chomp
ensure
File.delete TMP_PROGRAM if File.exist?(TMP_PROGRAM)
File.delete EXE_NAME if File.exist?(EXE_NAME)
end
def result
if @sizeof.empty? && @constants.empty?
raise "no data collected, nothing to do"
end
out = ['module ChildProcess::Unix::Platform']
out << ' SIZEOF = {'
max = @sizeof.keys.map { |e| e.length }.max
@sizeof.each_with_index do |(type, size), idx|
out << " :#{type.ljust max} => #{size}#{',' unless idx == @sizeof.size - 1}"
end
out << ' }'
max = @constants.keys.map { |e| e.length }.max
@constants.each do |name, val|
out << " #{name.ljust max} = #{val}"
end
out << 'end'
out.join "\n"
end
end
end
end
|