provide more libc functions for the expect implementation

This commit is contained in:
Folkert 2022-10-12 20:59:18 +02:00
parent d27eff1b36
commit 19ea3489cb
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
17 changed files with 426 additions and 31 deletions

View file

@ -65,6 +65,34 @@ export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() i32 {

View file

@ -64,6 +64,34 @@ export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() i32 {

View file

@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const testing = std.testing;
const expectEqual = testing.expectEqual;
const expect = testing.expect;
@ -13,7 +14,6 @@ comptime {
// -fcompiler-rt in link.rs instead of doing this. Note that this
// workaround is present in many host.zig files, so make sure to undo
// it everywhere!
const builtin = @import("builtin");
if (builtin.os.tag == .macos) {
_ = @import("compiler_rt");
}
@ -81,6 +81,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
pub export fn main() u8 {
const stdout = std.io.getStdOut().writer();
const stderr = std.io.getStdErr().writer();

View file

@ -80,6 +80,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
// warning! the array is currently stack-allocated so don't make this too big
const NUM_NUMS = 100;

View file

@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("str");
const RocStr = str.RocStr;
const testing = std.testing;
@ -15,7 +16,6 @@ comptime {
// -fcompiler-rt in link.rs instead of doing this. Note that this
// workaround is present in many host.zig files, so make sure to undo
// it everywhere!
const builtin = @import("builtin");
if (builtin.os.tag == .macos) {
_ = @import("compiler_rt");
}
@ -85,6 +85,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub fn main() !u8 {

View file

@ -27,6 +27,12 @@ void* roc_memcpy(void* dest, const void* src, size_t n) {
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
int roc_send_signal(int pid, int sig) { return kill(pid, sig); }
int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); }
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); }
int roc_getppid() { return getppid(); }
struct RocStr {
char* bytes;
size_t len;

View file

@ -54,6 +54,41 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut
libc::memset(dst, c, n)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_getppid() -> libc::pid_t {
libc::getppid()
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_mmap(
addr: *mut libc::c_void,
len: libc::size_t,
prot: libc::c_int,
flags: libc::c_int,
fd: libc::c_int,
offset: libc::off_t,
) -> *mut libc::c_void {
libc::mmap(addr, len, prot, flags, fd, offset)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_shm_open(
name: *const libc::c_char,
oflag: libc::c_int,
mode: libc::mode_t,
) -> libc::c_int {
libc::shm_open(name, oflag, mode)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
unsafe {

View file

@ -75,6 +75,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const mem = std.mem;
const Allocator = mem.Allocator;

View file

@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const SIGUSR1: c_int = 10;
@ -22,17 +23,18 @@ pub fn expectFailedStart() callconv(.C) [*]u8 {
return SHARED_BUFFER.ptr;
}
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn getppid() c_int;
extern fn roc_send_signal(pid: c_int, sig: c_int) c_int;
extern fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn roc_getppid() c_int;
pub fn readSharedBufferEnv() callconv(.C) void {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const name = "/roc_expect_buffer"; // IMPORTANT: shared memory object names must begin with / and contain no other slashes!
const shared_fd = shm_open(@ptrCast(*const i8, name), O_RDWR | O_CREAT, 0o666);
const shared_fd = roc_shm_open(@ptrCast(*const i8, name), O_RDWR | O_CREAT, 0o666);
const length = 4096;
const shared_ptr = mmap(
const shared_ptr = roc_mmap(
null,
length,
PROT_WRITE,
@ -44,10 +46,13 @@ pub fn readSharedBufferEnv() callconv(.C) void {
const ptr = @ptrCast([*]u8, shared_ptr);
SHARED_BUFFER = ptr[0..length];
}
}
pub fn expectFailedFinalize() callconv(.C) void {
const parent_pid = getppid();
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
const parent_pid = roc_getppid();
_ = kill(parent_pid, SIGUSR1);
_ = roc_send_signal(parent_pid, SIGUSR1);
}
}

View file

@ -77,13 +77,23 @@ fn collect_roc_definitions<'a>(object: &object::File<'a, &'a [u8]>) -> MutMap<St
let address = sym.address() as u64;
// special exceptions for memcpy and memset.
if name == "roc_memcpy" {
vaddresses.insert("memcpy".to_string(), address);
} else if name == "roc_memset" {
vaddresses.insert("memset".to_string(), address);
} else if name == "roc_memmove" {
vaddresses.insert("memmove".to_string(), address);
// special exceptions for roc_ functions that map to libc symbols
let direct_mapping = match name {
"roc_memcpy" => Some("memcpy"),
"roc_memset" => Some("memset"),
"roc_memmove" => Some("memmove"),
// for expects
"roc_mmap" => Some("mmap"),
"roc_getppid" => Some("getppid"),
"roc_send_signal" => Some("kill"),
"roc_shm_open" => Some("shm_open"),
_ => None,
};
if let Some(libc_symbol) = direct_mapping {
vaddresses.insert(libc_symbol.to_string(), address);
}
vaddresses.insert(name.to_string(), address);

View file

@ -73,6 +73,41 @@ pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) {
}
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_getppid() -> libc::pid_t {
libc::getppid()
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_mmap(
addr: *mut libc::c_void,
len: libc::size_t,
prot: libc::c_int,
flags: libc::c_int,
fd: libc::c_int,
offset: libc::off_t,
) -> *mut libc::c_void {
libc::mmap(addr, len, prot, flags, fd, offset)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_shm_open(
name: *const libc::c_char,
oflag: libc::c_int,
mode: libc::mode_t,
) -> libc::c_int {
libc::shm_open(name, oflag, mode)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
fn print_backtrace() {
eprintln!("Here is the call stack that led to the crash:\n");

View file

@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("str");
const RocStr = str.RocStr;
const testing = std.testing;
@ -15,7 +16,6 @@ comptime {
// -fcompiler-rt in link.rs instead of doing this. Note that this
// workaround is present in many host.zig files, so make sure to undo
// it everywhere!
const builtin = @import("builtin");
if (builtin.os.tag == .macos) {
_ = @import("compiler_rt");
}
@ -85,6 +85,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() u8 {

View file

@ -72,6 +72,41 @@ pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut
libc::memset(dst, c, n)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_getppid() -> libc::pid_t {
libc::getppid()
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_mmap(
addr: *mut libc::c_void,
len: libc::size_t,
prot: libc::c_int,
flags: libc::c_int,
fd: libc::c_int,
offset: libc::off_t,
) -> *mut libc::c_void {
libc::mmap(addr, len, prot, flags, fd, offset)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_shm_open(
name: *const libc::c_char,
oflag: libc::c_int,
mode: libc::mode_t,
) -> libc::c_int {
libc::shm_open(name, oflag, mode)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let arg = env::args()

View file

@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("str");
const RocStr = str.RocStr;
const testing = std.testing;
@ -15,7 +16,6 @@ comptime {
// -fcompiler-rt in link.rs instead of doing this. Note that this
// workaround is present in many host.zig files, so make sure to undo
// it everywhere!
const builtin = @import("builtin");
if (builtin.os.tag == .macos) {
_ = @import("compiler_rt");
}
@ -134,6 +134,34 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() callconv(.C) u8 {

View file

@ -95,6 +95,11 @@ void *roc_memset(void *str, int c, size_t n) {
return memset(str, c, n);
}
int roc_send_signal(int pid, int sig) { return kill(pid, sig); }
int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); }
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); }
int roc_getppid() { return getppid(); }
struct RocStr {
char *bytes;
size_t len;

View file

@ -27,6 +27,11 @@ void* roc_memcpy(void* dest, const void* src, size_t n) {
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
int roc_send_signal(int pid, int sig) { return kill(pid, sig); }
int roc_shm_open(char* name, int oflag, int mode) { return shm_open(name, oflag, mode); }
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) { return mmap(addr, length, prot, flags, fd, offset); }
int roc_getppid() { return getppid(); }
struct RocStr {
char* bytes;
size_t len;

View file

@ -33,6 +33,41 @@ pub unsafe extern "C" fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
libc::free(c_ptr)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_getppid() -> libc::pid_t {
libc::getppid()
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_mmap(
addr: *mut libc::c_void,
len: libc::size_t,
prot: libc::c_int,
flags: libc::c_int,
fd: libc::c_int,
offset: libc::off_t,
) -> *mut libc::c_void {
libc::mmap(addr, len, prot, flags, fd, offset)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_shm_open(
name: *const libc::c_char,
oflag: libc::c_int,
mode: libc::mode_t,
) -> libc::c_int {
libc::shm_open(name, oflag, mode)
}
#[cfg(unix)]
#[no_mangle]
pub unsafe extern "C" fn roc_send_signal(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int {
libc::kill(pid, sig)
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
let args: Vec<String> = env::args().collect();