Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Omake for Linux running #1060

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

chuggafan
Copy link
Contributor

This is a prototype with some basic changes for linux, this DOES NOT CURRENTLY WORK, and I know this because I haven't tested anything to do with actually capturing process output, this is just some fill-in from before to get some eyeballs on this.

The main thing stopping me from getting anywhere is my complete inability to understand how the dup2 stuff works, and all of the pipe issues, which gets me lost immediately upon trying to understand it, I'm at the point of trying to understand how glibc implements popen and it has also gotten me absolutely nowhere...
@GitMensch I assume you have the best eyes to know what in the universe POSIX is supposed to be doing and if I'm on the right track here, because I sure know I don't.

@chuggafan chuggafan changed the title Fix prototype code. Update Omake for Linux running Jan 4, 2025
@chuggafan
Copy link
Contributor Author

Ok, so I've done some testing, I've figured out how to get the readout from posix_spawn properly, thankfully, it's not too bad, it's just annoying because I have to juggle multiple pipes (for stdout and stdin) on that, and then remember everything, I've actually made a test-program for this because the online documentation is so bad that it's not understandable to a beginning that I'll add here in case someone in the future somehow finds this and wants my work as a reference:

#define _GNU_SOURCE
#include <spawn.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
extern char **environ;
int main()
{
    posix_spawn_file_actions_t spawn_actions;
    posix_spawnattr_t attrs;
    posix_spawn_file_actions_init(&spawn_actions);
    posix_spawnattr_init(&attrs);
    pid_t spawned_pid;
    int pipes[2];
    int ret = pipe2(pipes, O_CLOEXEC);
    if (ret != 0)
    {
        printf("Pipe failed\n");
    }
    // Copy stdout to the writable pipe, pipes[0] is the readable pipe. Mirrors stdin vs stdout
    posix_spawn_file_actions_adddup2(&spawn_actions, pipes[1], 1);
    // Ensure pipes close
    posix_spawn_file_actions_addclose(&spawn_actions, pipes[1]);
    posix_spawn_file_actions_addclose(&spawn_actions, pipes[0]);

    ret = posix_spawn(&spawned_pid, "/bin/sh", &spawn_actions, &attrs, (char *const[]){"sh", "-c", "--", "ls /var/", NULL}, environ);
    if (ret)
    {
        printf("Failed to spawn! errno: %d\n", ret);
    }
    posix_spawn_file_actions_destroy(&spawn_actions);
    posix_spawnattr_destroy(&attrs);

    int wait_status = 0;
    do
    {
        wait_status = 0;
        char val[80] = {0};
        struct pollfd polls = {.events = POLLIN, .fd = pipes[0]};
        // Poll for < 100ms, if we timeout on having any data whatsoever, we check if the process is done, if the process is done, exit the read loop.
        int ret = poll(&polls, 1, 100);
        if (ret > 0)
        {
            if (polls.revents & POLLIN)
            {
                int success = read(pipes[0], val, sizeof(val) - 1);
                printf("%s", val);
                if (success < 1)
                {
                    break;
                }
            }
        }
        if (ret == 0)
        {
            waitpid(spawned_pid, &wait_status, WUNTRACED);
            if (!(!WIFEXITED(wait_status) && !WIFSIGNALED(wait_status) && !WIFSTOPPED(wait_status)))
            {
                break;
            }
        }
    } while (1);
    close(pipes[0]);
    close(pipes[1]);
}

I have verified in WSL that this prints the exact output of ls /var/ on my machine.
I'm going to incorporate this now that I have it into my code for this PR since I now realize my previous attempt was not even close to successful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant