2019-03-03 05:46:04 +08:00
|
|
|
const std = @import("../../std.zig");
|
2018-04-23 01:24:25 +08:00
|
|
|
const builtin = @import("builtin");
|
2017-11-11 07:12:46 +08:00
|
|
|
const linux = std.os.linux;
|
2019-05-05 19:00:32 +08:00
|
|
|
const mem = std.mem;
|
|
|
|
const elf = std.elf;
|
2019-02-09 07:18:47 +08:00
|
|
|
const expect = std.testing.expect;
|
2017-11-11 07:12:46 +08:00
|
|
|
|
2018-08-03 23:45:23 +08:00
|
|
|
test "getpid" {
|
2019-02-09 07:18:47 +08:00
|
|
|
expect(linux.getpid() != 0);
|
2018-08-03 23:45:23 +08:00
|
|
|
}
|
|
|
|
|
2017-11-11 07:12:46 +08:00
|
|
|
test "timer" {
|
|
|
|
const epoll_fd = linux.epoll_create();
|
|
|
|
var err = linux.getErrno(epoll_fd);
|
2019-02-09 07:18:47 +08:00
|
|
|
expect(err == 0);
|
2017-11-11 07:12:46 +08:00
|
|
|
|
|
|
|
const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);
|
2019-02-09 07:18:47 +08:00
|
|
|
expect(linux.getErrno(timer_fd) == 0);
|
2017-11-11 07:12:46 +08:00
|
|
|
|
2018-11-13 21:08:37 +08:00
|
|
|
const time_interval = linux.timespec{
|
2017-11-11 07:12:46 +08:00
|
|
|
.tv_sec = 0,
|
2018-05-29 08:23:55 +08:00
|
|
|
.tv_nsec = 2000000,
|
2017-11-11 07:12:46 +08:00
|
|
|
};
|
|
|
|
|
2018-11-13 21:08:37 +08:00
|
|
|
const new_time = linux.itimerspec{
|
2017-11-11 07:12:46 +08:00
|
|
|
.it_interval = time_interval,
|
2018-05-29 08:23:55 +08:00
|
|
|
.it_value = time_interval,
|
2017-11-11 07:12:46 +08:00
|
|
|
};
|
|
|
|
|
2018-06-17 14:57:07 +08:00
|
|
|
err = linux.timerfd_settime(@intCast(i32, timer_fd), 0, &new_time, null);
|
2019-02-09 07:18:47 +08:00
|
|
|
expect(err == 0);
|
2017-11-11 07:12:46 +08:00
|
|
|
|
2018-11-13 21:08:37 +08:00
|
|
|
var event = linux.epoll_event{
|
2017-11-11 07:12:46 +08:00
|
|
|
.events = linux.EPOLLIN | linux.EPOLLOUT | linux.EPOLLET,
|
2018-11-13 21:08:37 +08:00
|
|
|
.data = linux.epoll_data{ .ptr = 0 },
|
2017-11-11 07:12:46 +08:00
|
|
|
};
|
|
|
|
|
2018-06-17 14:57:07 +08:00
|
|
|
err = linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event);
|
2019-02-09 07:18:47 +08:00
|
|
|
expect(err == 0);
|
2017-11-11 07:12:46 +08:00
|
|
|
|
|
|
|
const events_one: linux.epoll_event = undefined;
|
2018-11-13 21:08:37 +08:00
|
|
|
var events = []linux.epoll_event{events_one} ** 8;
|
2017-11-11 07:12:46 +08:00
|
|
|
|
2018-06-04 13:09:15 +08:00
|
|
|
// TODO implicit cast from *[N]T to [*]T
|
2018-06-17 14:57:07 +08:00
|
|
|
err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
|
2017-11-11 07:12:46 +08:00
|
|
|
}
|
2019-05-05 19:00:32 +08:00
|
|
|
|
|
|
|
export fn iter_fn(info: *linux.dl_phdr_info, size: usize, data: ?*usize) i32 {
|
|
|
|
var counter = data.?;
|
|
|
|
// Count how many libraries are loaded
|
|
|
|
counter.* += usize(1);
|
|
|
|
|
|
|
|
// The image should contain at least a PT_LOAD segment
|
|
|
|
if (info.dlpi_phnum < 1) return -1;
|
|
|
|
|
|
|
|
// Quick & dirty validation of the phdr pointers, make sure we're not
|
|
|
|
// pointing to some random gibberish
|
|
|
|
var i: usize = 0;
|
|
|
|
var found_load = false;
|
|
|
|
while (i < info.dlpi_phnum) : (i += 1) {
|
|
|
|
const phdr = info.dlpi_phdr[i];
|
|
|
|
|
|
|
|
if (phdr.p_type != elf.PT_LOAD) continue;
|
|
|
|
|
|
|
|
// Find the ELF header
|
|
|
|
const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset);
|
|
|
|
// Validate the magic
|
|
|
|
if (!mem.eql(u8, elf_header.e_ident[0..], "\x7fELF")) return -1;
|
|
|
|
// Consistency check
|
|
|
|
if (elf_header.e_phnum != info.dlpi_phnum) return -1;
|
|
|
|
|
|
|
|
found_load = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found_load) return -1;
|
|
|
|
|
|
|
|
return 42;
|
|
|
|
}
|
|
|
|
|
|
|
|
test "dl_iterate_phdr" {
|
|
|
|
var counter: usize = 0;
|
|
|
|
expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
|
|
|
|
expect(counter != 0);
|
|
|
|
}
|