#!/usr/bin/env rdmd
/* Copyright (C) Eugene 'Vindex' Stulin, 2023-2024
 *
 * This example is written according to the original from libfuse.
 * Distributed under BSL 1.0 or (at your option) the GNU GPL 3.0 or later.
 * This file is offered as-is, without any warranty.
 */

/// This program tests the poll.d example file system.

import std.exception : enforce;
import std.stdio;
import std.string : toStringz;

import core.sys.posix.fcntl : O_ACCMODE, O_RDONLY;
static import unix_fcntl = core.sys.posix.fcntl;
static import unix_unistd = core.sys.posix.unistd;
import core.sys.posix.sys.select : select, fd_set, FD_ZERO, FD_SET, FD_ISSET;
import core.sys.posix.sys.time : timeval;

immutable NFILES = 16;
immutable fselHexMap = "0123456789ABCDEF";

int main() {
    int[NFILES] fds;

    for (size_t i = 0; i < NFILES; i++) {
        string name = [fselHexMap[i]];
        fds[i] = unix_fcntl.open(name.toStringz, O_RDONLY);
        enforce(fds[i] >= 0, "open");
    }
    int nfds = fds[NFILES - 1] + 1;

    for (int tries = 0; tries < 16; tries++) {
        static char[4096] buf;
        fd_set rfds;
        FD_ZERO(&rfds);
        for (size_t i = 0; i < NFILES; i++) {
            FD_SET(fds[i], &rfds);
        }
        enforce(select(nfds, &rfds, null, null, null) >= 0, "select");

        for (size_t i = 0; i < NFILES; i++) {
            if (!FD_ISSET(fds[i], &rfds)) {
                write("_:   ");
            } else {
                writef("%X:", i);
                auto r = unix_unistd.read(fds[i], buf.ptr, buf.sizeof);
                enforce(r >= 0, "read");
                writef("%02d ", r);
            }
        }
        writeln;
    }
    return 0;
}
