M
M
Marat Nagayev2022-04-15 00:55:17
linux
Marat Nagayev, 2022-04-15 00:55:17

How to communicate with a process in Linux?

You need to write a program that will send data to the stdin of the program and take it from stdout.
To begin with, I decided to send a command to the terminal so that it creates a file.
What am I doing wrong?

#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;
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
shurshur, 2022-04-15
@shurshur

The call to pidfd_open is for something completely different. It is needed to monitor the state of the process using I / O operations (in particular, such as select / poll). It is not intended to access the stdin / stdout / stderr of the process, these must be separate descriptors (and different ones).
For simple applications, it is enough to use the popen function. If the goal is to understand how it all works, then I recommend writing a simple program with popen, then running strace on it (with the -f switch) and understanding what is hidden under the hood. In particular, to understand why there will be dup, fork and exec calls, how stdin / stdout / stderr is redefined and all that.

J
jcmvbkbc, 2022-04-15
@jcmvbkbc

You need to write a program that will send data to the stdin of the program and take it from stdout.

What am I doing wrong?

You are using the wrong method. pidfd_open doesn't do what you expect at all, see "Use cases for PID file descriptors" in the link provided.
Interaction with a child process via stdin/stdout is usually implemented via a pipe. Here is an example .
Here is another example that does 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;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question