Как общаться с процессом в Linux?

Нужно написать программу, которая будет посылать в stdin программы данные и забирать из stdout.
Для начала решил отправить в терминал команду чтобы он создал файл.
Что я делаю не так?
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <spawn.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#ifndef __NR_pidfd_open
   #define __NR_pidfd_open 434   /* System call # on most architectures */
#endif

extern char** environ;

static int pidfd_open(pid_t pid, unsigned int flags)
{
  return syscall(__NR_pidfd_open, pid, flags);
}

int main(int argc,char* argv[])
{
        char* command = "echo 3 > lala.txt";
        pid_t pid;
        int status = posix_spawn(&pid,"/bin/sh",NULL,NULL,argv,environ);
        printf("status: %i and %i\n",status,pid);
        int pidfd = pidfd_open(pid, 0);
        if (pidfd<0){
            printf("panic: %i\n",errno); 
            return 1;
        }
        printf("pidfd: %i\n",pidfd);
        write(pidfd,command,(strlen(command)+1));
        close(pidfd);
        system("ls");

    return 0;
}
  • Вопрос задан
  • 286 просмотров
Пригласить эксперта
Ответы на вопрос 2
shurshur
@shurshur
Сисадмин, просто сисадмин...
Вызов pidfd_open предназначен совсем для другого. Он нужен, чтобы мониторить состояние процесса с помощью операций ввода-вывода (в частности, таких, как select/poll). Для доступа к stdin/stdout/stderr процесса он не предназначен, это должны быть отдельные дескрипторы (причём разные).

Для простоых применений достаточно использовать функцию popen. Если целью является разобраться в том, как это всё работает, то рекомендую написать простейшую программу с popen, затем погонять по ней strace (с ключом -f) и понять, что скрывается под капотом. В частности, понять, зачем там будут вызовы dup, fork и exec, как переопределяется stdin/stdout/stderr и всё такое.
Ответ написан
Комментировать
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Нужно написать программу, которая будет посылать в stdin программы данные и забирать из stdout.

Что я делаю не так?


Ты пользуешься не тем методом. pidfd_open делает совсем не то, что ты ожидаешь, см. раздел "Use cases for PID file descriptors" по приведённой ссылке.

Взаимодействие с дочерним процессом через stdin/stdout обычно реализуется через пайп. Вот пример.

Вот ещё пример который делает exec

#include <unistd.h>

int main()
{
        int fd[2][2];
        pipe(fd[0]);
        pipe(fd[1]);
        pid_t pid_fork = fork();
        if (!pid_fork) {
                // Дочерний процесс
                close(fd[0][1]);
                close(fd[1][0]);
                dup2(fd[0][0], STDIN_FILENO);
                dup2(fd[1][1], STDOUT_FILENO);
                execl("/usr/bin/tr", "/usr/bin/tr", "l", "r", NULL);
        } else {
                // Родительский процесс
                close(fd[0][0]);
                close(fd[1][1]);
                char buf[1000];
                ssize_t sz;

                write(fd[0][1], "hello, world\n", sizeof("hello, world\n") - 1);
                close(fd[0][1]);
                sz = read(fd[1][0], buf, sizeof(buf));
                if (sz > 0) {
                        write(STDOUT_FILENO, buf, sz);
                }
        }
        return 0;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы