bloat-buster/src/lib.cpp
David Gonzalez Martin 510f27e13f
All checks were successful
CI / ci (MinSizeRel, ubuntu-latest) (pull_request) Successful in 1m10s
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 1m9s
CI / ci (RelWithDebInfo, ubuntu-latest) (pull_request) Successful in 1m13s
CI / ci (Debug, ubuntu-latest) (pull_request) Successful in 2m44s
CI / ci (MinSizeRel, ubuntu-latest) (push) Successful in 1m5s
CI / ci (RelWithDebInfo, ubuntu-latest) (push) Successful in 1m5s
CI / ci (Release, ubuntu-latest) (push) Successful in 1m4s
CI / ci (Debug, ubuntu-latest) (push) Successful in 2m37s
Port the compiler from Zig to C++
2025-05-23 07:47:53 -06:00

213 lines
5.5 KiB
C++

#include <lib.hpp>
using uid_t = u32;
using gid_t = u32;
using off_t = s64;
using ino_t = u64;
using dev_t = u64;
struct timespec
{
s64 seconds;
s64 nanoseconds;
};
struct Stat
{
dev_t dev;
ino_t ino;
u64 nlink;
u32 mode;
uid_t uid;
gid_t gid;
u32 _0;
dev_t rdev;
off_t size;
s64 blksize;
s64 blocks;
timespec atim;
timespec mtim;
timespec ctim;
s64 _1[3];
};
extern "C" s32 fstat(s32, Stat*);
extern "C" s32 fork();
extern "C" s32 dup2(s32, s32);
extern "C" s32 execve(const char* path_name, const char* const argv[], char* const envp[]);
extern "C" s32 waitpid(s32 pid, int* wstatus, int options);
u64 os_file_size(s32 fd)
{
Stat stat;
auto result = fstat(fd, &stat);
assert(result == 0);
return (u64)stat.size;
}
fn u8 EXITSTATUS(u32 s)
{
return (u8)((s & 0xff00) >> 8);
}
fn u32 TERMSIG(u32 s)
{
return s & 0x7f;
}
fn u32 STOPSIG(u32 s)
{
return EXITSTATUS(s);
}
fn bool IFEXITED(u32 s)
{
return TERMSIG(s) == 0;
}
fn bool IFSTOPPED(u32 s)
{
return u16(((s & 0xffff) * 0x10001) >> 8) > 0x7f00;
}
fn bool IFSIGNALED(u32 s)
{
return (s & 0xffff) - 1 < 0xff;
}
Execution os_execute(Arena* arena, Slice<const char* const> arguments, Slice<char* const> environment, ExecuteOptions options)
{
unused(arena);
assert(arguments.pointer[arguments.length] == 0);
assert(environment.pointer[environment.length] == 0);
Execution execution = {};
s32 null_file_descriptor = -1;
if (options.null_file_descriptor >= 0)
{
null_file_descriptor = options.null_file_descriptor;
}
else if (options.policies[0] == ExecuteStandardStreamPolicy::ignore || options.policies[1] == ExecuteStandardStreamPolicy::ignore)
{
trap();
}
int pipes[standard_stream_count][2];
for (int i = 0; i < 2; i += 1)
{
if (options.policies[i] == ExecuteStandardStreamPolicy::pipe)
{
trap();
}
}
auto pid = fork();
switch (pid)
{
case -1:
{
trap();
} break;
case 0: // Child process
{
for (u64 i = 0; i < standard_stream_count; i += 1)
{
auto fd = (s32)i + 1;
switch (options.policies[i])
{
case ExecuteStandardStreamPolicy::inherit:
{
} break;
case ExecuteStandardStreamPolicy::pipe:
{
close(pipes[i][0]);
dup2(pipes[i][1], fd);
close(pipes[i][1]);
} break;
case ExecuteStandardStreamPolicy::ignore:
{
dup2(null_file_descriptor, fd);
close(null_file_descriptor);
} break;
}
}
auto result = execve(arguments[0], arguments.pointer, environment.pointer);
if (result != -1)
{
unreachable();
}
trap();
} break;
default:
{
for (u64 i = 0; i < standard_stream_count; i += 1)
{
if (options.policies[i] == ExecuteStandardStreamPolicy::pipe)
{
close(pipes[i][1]);
}
}
if (options.policies[0] == ExecuteStandardStreamPolicy::pipe || options.policies[1] == ExecuteStandardStreamPolicy::pipe)
{
trap();
}
for (u64 i = 0; i < standard_stream_count; i += 1)
{
if (options.policies[i] == ExecuteStandardStreamPolicy::pipe)
{
trap();
}
}
int status = 0;
auto waitpid_result = waitpid(pid, &status, 0);
if (waitpid_result == pid)
{
if (IFEXITED(status))
{
execution.termination_kind = TerminationKind::exit;
execution.termination_code = EXITSTATUS(status);
}
else if (IFSIGNALED(status))
{
execution.termination_kind = TerminationKind::signal;
execution.termination_code = TERMSIG(status);
}
else if (IFSTOPPED(status))
{
execution.termination_kind = TerminationKind::stop;
execution.termination_code = STOPSIG(status);
}
else
{
execution.termination_kind = TerminationKind::unknown;
}
if (options.null_file_descriptor < 0 && null_file_descriptor >= 0)
{
close(null_file_descriptor);
}
}
else if (waitpid_result == -1)
{
trap();
}
else
{
trap();
}
} break;
}
return execution;
}