Get the standard version of an already running process on Linux in C

Right now, I need to start an external process in C. I am currently using posix_spawn to create a process. It is necessary that I can control whether the process is completed. I also need to have a reference to the standard outside the process. I looked at using popen, however it does not provide an “easy” way to get pid. I'm slowly losing my mind since it can't be so hard to get an executable process command on Linux.

Also, in the following note, I need help deciphering what the file_actions parameter means. man (3) for posix_spawn on this topic says:

If file_actions is not NULL, then file descriptors opened in the child process must be opened in the calling process, modified by the spawn file action object pointed to by file_name, and the FD_CLOEXEC flag of each remaining open file descriptor after the spawn file actions are processed.

If this is not a definition of an opening sentence, I have no idea what it is.

+4
source share
2 answers

Since you have a PID (returned from posix_spawn) and you are running Linux, you will find the process stdout in /proc/<pid>/fd/1. Just open(or fopen) a file to read.

- fork. pipe dup2, , .

+6

posix_spawn , , Linux /proc/<pid>/fd/N. posix_spawn.

, file_actions. , stdout Python, posix_spawn file_actions.

.

child pid: 17468
child exit status: 0
child stdout:
"""Hello World!
"""

.

#define _DEFAULT_SOURCE
#include <spawn.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

extern char **environ;

static void dump_child_stdout(int filedes)
{
    ssize_t num_read;
    char buf[1];

    printf("child stdout:\n\"\"\"");
    for (;;)
    {
        num_read = read(filedes, buf, sizeof(buf));
        if (num_read > 0)
        {
            printf("%c", buf[0]);
        }
        else
        {
            break;
        }
    }
    printf("\"\"\"\n");
}

int main(int argc, char *argv[])
{
    int status;
    pid_t pid;
    int out[2];
    posix_spawn_file_actions_t action;
    char *args[] = {"/bin/echo", "Hello World!", NULL };

    posix_spawn_file_actions_init(&action);

    pipe(out);

    posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO);
    posix_spawn_file_actions_addclose(&action, out[0]);

    status = posix_spawn(&pid, args[0], &action, NULL, args, environ);
    if (status == 0)
    {
        printf("child pid: %d\n", pid);
        if (waitpid(pid, &status, 0) < 0)
        {
            perror("waitpid");
        }
        else
        {
            if (WIFEXITED(status))
            {
                printf("child exit status: %d\n", WEXITSTATUS(status));
            }
            else
            {
                printf("child died an unnatural death.\n");
            }

            close(out[1]);
            dump_child_stdout(out[0]);
        }
    }
    else
    {
        fprintf(stderr, "posix_spawn: %s\n", strerror(status));
        close(out[1]);
    }

    posix_spawn_file_actions_destroy(&action);

    return 0;
}
+3

Source: https://habr.com/ru/post/1525476/


All Articles