mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
Box: remove copied extension files
This commit is contained in:
parent
e8568bbcf2
commit
573896a40a
Notes:
git
2025-12-09 14:42:24 +00:00
60
box.c
60
box.c
@ -62,6 +62,7 @@ bool ruby_box_crashed = false; // extern, changed only in vm.c
|
||||
|
||||
VALUE rb_resolve_feature_path(VALUE klass, VALUE fname);
|
||||
static VALUE rb_box_inspect(VALUE obj);
|
||||
static void cleanup_all_local_extensions(VALUE libmap);
|
||||
|
||||
void
|
||||
rb_box_init_done(void)
|
||||
@ -274,6 +275,8 @@ box_entry_free(void *ptr)
|
||||
st_foreach(box->classext_cow_classes, free_classext_for_box, (st_data_t)box);
|
||||
}
|
||||
|
||||
cleanup_all_local_extensions(box->ruby_dln_libmap);
|
||||
|
||||
box_root_free(ptr);
|
||||
xfree(ptr);
|
||||
}
|
||||
@ -724,8 +727,57 @@ escaped_basename(const char *path, const char *fname, char *rvalue, size_t rsize
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
box_ext_cleanup_mark(void *p)
|
||||
{
|
||||
rb_gc_mark((VALUE)p);
|
||||
}
|
||||
|
||||
static void
|
||||
box_ext_cleanup_free(void *p)
|
||||
{
|
||||
VALUE path = (VALUE)p;
|
||||
unlink(RSTRING_PTR(path));
|
||||
}
|
||||
|
||||
static const rb_data_type_t box_ext_cleanup_type = {
|
||||
"box_ext_cleanup",
|
||||
{box_ext_cleanup_mark, box_ext_cleanup_free},
|
||||
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
||||
};
|
||||
|
||||
void
|
||||
rb_box_cleanup_local_extension(VALUE cleanup)
|
||||
{
|
||||
void *p = DATA_PTR(cleanup);
|
||||
DATA_PTR(cleanup) = NULL;
|
||||
#ifndef _WIN32
|
||||
if (p) box_ext_cleanup_free(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
cleanup_local_extension_i(VALUE key, VALUE value, VALUE arg)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
HMODULE h = (HMODULE)NUM2SVALUE(value);
|
||||
WCHAR module_path[MAXPATHLEN];
|
||||
DWORD len = GetModuleFileNameW(h, module_path, numberof(module_path));
|
||||
|
||||
FreeLibrary(h);
|
||||
if (len > 0 && len < numberof(module_path)) DeleteFileW(module_path);
|
||||
#endif
|
||||
return ST_DELETE;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_all_local_extensions(VALUE libmap)
|
||||
{
|
||||
rb_hash_foreach(libmap, cleanup_local_extension_i, 0);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_box_local_extension(VALUE box_value, VALUE fname, VALUE path)
|
||||
rb_box_local_extension(VALUE box_value, VALUE fname, VALUE path, VALUE *cleanup)
|
||||
{
|
||||
char ext_path[MAXPATHLEN], fname2[MAXPATHLEN], basename[MAXPATHLEN];
|
||||
int wrote;
|
||||
@ -739,14 +791,16 @@ rb_box_local_extension(VALUE box_value, VALUE fname, VALUE path)
|
||||
if (wrote >= (int)sizeof(ext_path)) {
|
||||
rb_bug("Extension file path in the box was too long");
|
||||
}
|
||||
VALUE new_path = rb_str_new_cstr(ext_path);
|
||||
*cleanup = TypedData_Wrap_Struct(0, &box_ext_cleanup_type, NULL);
|
||||
enum copy_error_type copy_error = copy_ext_file(src_path, ext_path);
|
||||
if (copy_error) {
|
||||
char message[1024];
|
||||
copy_ext_file_error(message, sizeof(message), copy_error);
|
||||
rb_raise(rb_eLoadError, "can't prepare the extension file for Ruby Box (%s from %"PRIsVALUE"): %s", ext_path, path, message);
|
||||
}
|
||||
// TODO: register the path to be clean-uped
|
||||
return rb_str_new_cstr(ext_path);
|
||||
DATA_PTR(*cleanup) = (void *)new_path;
|
||||
return new_path;
|
||||
}
|
||||
|
||||
// TODO: delete it just after dln_load? or delay it?
|
||||
|
||||
@ -3,6 +3,16 @@
|
||||
|
||||
#include "ruby/ruby.h" /* for VALUE */
|
||||
|
||||
#if SIZEOF_VALUE <= SIZEOF_LONG
|
||||
# define SVALUE2NUM(x) LONG2NUM((long)(x))
|
||||
# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LONG(x)
|
||||
#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
|
||||
# define SVALUE2NUM(x) LL2NUM((LONG_LONG)(x))
|
||||
# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LL(x)
|
||||
#else
|
||||
# error Need integer for VALUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @author Ruby developers <ruby-core@ruby-lang.org>
|
||||
* @copyright This file is a part of the programming language Ruby.
|
||||
@ -75,7 +85,8 @@ void rb_box_gc_update_references(void *ptr);
|
||||
rb_box_t * rb_get_box_t(VALUE ns);
|
||||
VALUE rb_get_box_object(rb_box_t *ns);
|
||||
|
||||
VALUE rb_box_local_extension(VALUE box, VALUE fname, VALUE path);
|
||||
VALUE rb_box_local_extension(VALUE box, VALUE fname, VALUE path, VALUE *cleanup);
|
||||
void rb_box_cleanup_local_extension(VALUE cleanup);
|
||||
|
||||
void rb_initialize_main_box(void);
|
||||
void rb_box_init_done(void);
|
||||
|
||||
16
load.c
16
load.c
@ -27,16 +27,6 @@
|
||||
#define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
|
||||
#define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
|
||||
|
||||
#if SIZEOF_VALUE <= SIZEOF_LONG
|
||||
# define SVALUE2NUM(x) LONG2NUM((long)(x))
|
||||
# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LONG(x)
|
||||
#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
|
||||
# define SVALUE2NUM(x) LL2NUM((LONG_LONG)(x))
|
||||
# define NUM2SVALUE(x) (SIGNED_VALUE)NUM2LL(x)
|
||||
#else
|
||||
# error Need integer for VALUE
|
||||
#endif
|
||||
|
||||
enum {
|
||||
loadable_ext_rb = (0+ /* .rb extension is the first in both tables */
|
||||
1) /* offset by rb_find_file_ext() */
|
||||
@ -1203,11 +1193,15 @@ load_ext(VALUE path, VALUE fname)
|
||||
{
|
||||
VALUE loaded = path;
|
||||
const rb_box_t *box = rb_loading_box();
|
||||
VALUE cleanup = 0;
|
||||
if (BOX_USER_P(box)) {
|
||||
loaded = rb_box_local_extension(box->box_object, fname, path);
|
||||
loaded = rb_box_local_extension(box->box_object, fname, path, &cleanup);
|
||||
}
|
||||
rb_scope_visibility_set(METHOD_VISI_PUBLIC);
|
||||
void *handle = dln_load_feature(RSTRING_PTR(loaded), RSTRING_PTR(fname));
|
||||
if (cleanup) {
|
||||
rb_box_cleanup_local_extension(cleanup);
|
||||
}
|
||||
RB_GC_GUARD(loaded);
|
||||
RB_GC_GUARD(fname);
|
||||
return (VALUE)handle;
|
||||
|
||||
@ -697,10 +697,6 @@ class TestBox < Test::Unit::TestCase
|
||||
assert !$LOADED_FEATURES.include?("/tmp/barbaz")
|
||||
assert !Object.const_defined?(:FooClass)
|
||||
end;
|
||||
ensure
|
||||
tmp = ENV["TMPDIR"] || ENV["TMP"] || Etc.systmpdir || "/tmp"
|
||||
pat = "_ruby_ns_*."+RbConfig::CONFIG["DLEXT"]
|
||||
File.unlink(*Dir.glob(pat, base: tmp).map {|so| "#{tmp}/#{so}"})
|
||||
end
|
||||
|
||||
def test_basic_box_detections
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user