Add reboot syscall

Only linux for now
This commit is contained in:
daurnimator 2022-10-27 22:25:48 +11:00 committed by Andrew Kelley
parent 0b99e5e4c4
commit c0c8ee5ae9
2 changed files with 107 additions and 0 deletions

View File

@ -366,6 +366,56 @@ pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {
}
}
pub const RebootError = error{
PermissionDenied,
} || UnexpectedError;
pub const RebootCommand = switch (builtin.os.tag) {
.linux => union(linux.LINUX_REBOOT.CMD) {
RESTART: void,
HALT: void,
CAD_ON: void,
CAD_OFF: void,
POWER_OFF: void,
RESTART2: [*:0]const u8,
SW_SUSPEND: void,
KEXEC: void,
},
else => @compileError("Unsupported OS"),
};
pub fn reboot(cmd: RebootCommand) RebootError!void {
switch (builtin.os.tag) {
.linux => {
switch (system.getErrno(linux.reboot(
.MAGIC1,
.MAGIC2,
@as(linux.LINUX_REBOOT.CMD, cmd),
switch (cmd) {
.RESTART2 => |s| s,
else => null,
},
))) {
.SUCCESS => {},
.PERM => return error.PermissionDenied,
else => |err| return std.os.unexpectedErrno(err),
}
switch (cmd) {
.CAD_OFF => {},
.CAD_ON => {},
.SW_SUSPEND => {},
.HALT => unreachable,
.KEXEC => unreachable,
.POWER_OFF => unreachable,
.RESTART => unreachable,
.RESTART2 => unreachable,
}
},
else => @compileError("Unsupported OS"),
}
}
pub const GetRandomError = OpenError;
/// Obtain a series of random bytes. These bytes can be used to seed user-space

View File

@ -804,6 +804,63 @@ pub fn exit_group(status: i32) noreturn {
unreachable;
}
/// flags for the `reboot' system call.
pub const LINUX_REBOOT = struct {
/// First magic value required to use _reboot() system call.
pub const MAGIC1 = enum(u32) {
MAGIC1 = 0xfee1dead,
_,
};
/// Second magic value required to use _reboot() system call.
pub const MAGIC2 = enum(u32) {
MAGIC2 = 672274793,
MAGIC2A = 85072278,
MAGIC2B = 369367448,
MAGIC2C = 537993216,
_,
};
/// Commands accepted by the _reboot() system call.
pub const CMD = enum(u32) {
/// Restart system using default command and mode.
RESTART = 0x01234567,
/// Stop OS and give system control to ROM monitor, if any.
HALT = 0xCDEF0123,
/// Ctrl-Alt-Del sequence causes RESTART command.
CAD_ON = 0x89ABCDEF,
/// Ctrl-Alt-Del sequence sends SIGINT to init task.
CAD_OFF = 0x00000000,
/// Stop OS and remove all power from system, if possible.
POWER_OFF = 0x4321FEDC,
/// Restart system using given command string.
RESTART2 = 0xA1B2C3D4,
/// Suspend system using software suspend if compiled in.
SW_SUSPEND = 0xD000FCE2,
/// Restart system using a previously loaded Linux kernel
KEXEC = 0x45584543,
_,
};
};
pub fn reboot(magic: LINUX_REBOOT.MAGIC1, magic2: LINUX_REBOOT.MAGIC2, cmd: LINUX_REBOOT.CMD, arg: ?*const anyopaque) usize {
return std.os.linux.syscall4(
.reboot,
@enumToInt(magic),
@enumToInt(magic2),
@enumToInt(cmd),
@ptrToInt(arg),
);
}
pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
return syscall3(.getrandom, @ptrToInt(buf), count, flags);
}