Hello. Perhaps the topic is a bit confusing, so I’ll explain it easier: I need a C / C ++ program that can run another program passed to it in the arguments, and then give it something to input (input), wait for it (transferred her program) will make its own and get its output (output). And another thing: the program that I pass on to the arguments of my shell program is a Python 3 script, maybe this is an important detail. The program will be under Linux . Actually, I need to find out through what functions this can be done (I mean, do input to the program and get its output).

  • one
    if you can save to input and output files, you can simply make a call to the system from the parameters [name] <input> output - pavel
  • Got it. But it is impossible without additional. files? - drfels
  • Sure you may. - avp

2 answers 2

Look in the direction of popen - for example, here or here - this will not help you?

  • There is one big problem with popen, it can either only write to the input of the program, or only read. for two-way communication, use your own fork / exec by redirecting file descriptors - Mike
  • one
    Please try to publish detailed answers containing a specific example of the minimum solution, supplementing them with a link to the source. Answers –references (as well as comments) do not add knowledge to the Runet. - Nicolas Chabanovsky
  • This will not work if you need to write to the script and read from it. - avp

In the simplest case, you can make 2 pipe ( pipe ), through the first you write to the script, and through the second you read from it, then create a process ( fork ) in which you can switch ( dup2 ) the pipe handles to the stdin and stdout script and run it (for example execl ).

Here is a primitive example:

 #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> #include <fcntl.h> #include <err.h> #include <sysexits.h> #include <errno.h> int main (int ac, char *av[]) { if (ac < 2) errx(EX_USAGE, "Usage: %s cmd [args]\n", av[0]); pid_t pid, cmd; int pin[2], pout[2]; // пара пайпов для обмена со скриптом if (pipe(pin) || pipe(pout)) err(EX_OSERR, "pipes"); if (!(cmd = fork())) { // запуск скрипта с аргументами close(pin[1]); close(pout[0]); dup2(pin[0], 0); // заменим stdin скрипта на наш ввод dup2(pout[1], 1); // перекинем stdout скрипта на наc // stderr скрипта остался тем же, что и у нас execvp(av[1], av + 1); err(EX_UNAVAILABLE, "exec %s", av[1]); } if (cmd == -1) err(EX_OSERR, "fork"); // эти дескрипторы более не нужны close(pin[0]); close(pout[1]); char *str = 0; size_t ssize = 0; ssize_t l; // для примера читаем stdin и передаем в скрипт while ((l = getline(&str, &ssize, stdin)) > 0) if (write(pin[1], str, l) != l) err(EX_IOERR, "write pipe"); close(pin[1]); // пошлем EOF на stdin скрипта // читаем вывод скрипта и для примера печатаем его FILE *progout = fdopen(pout[0], "r"); while (getline(&str, &ssize, progout) > 0) puts(str); free(str); int status; errno = 0; if ((pid = wait(&status)) != cmd) { if (errno) err(EX_SOFTWARE, "wait"); else errx(EX_SOFTWARE, "wait unexpected PID %ld (waited %ld)", (long)pid, (long)cmd); } if (WIFEXITED(status)) printf("%s exit code %d\n", av[1], WEXITSTATUS(status)); else printf("%s terminated by %d\n", av[1], WTERMSIG(status)); return puts("End") == EOF; } 

There may be "pitfalls" (especially if you want "interactive work"), since FILE * with a pipe (unlike the terminal) is buffered (and the output of fprintf / fputs will not actually be output to the pipe in rows), and the pipes have a limited size, which can lead to interlocking processes.

For example, you write to the script, it returns its results through the pipe, and if you don’t read this pipe, the script will "hang" on its write operation (the pipe is full, and no one reads it).

To correctly resolve this situation, you need to read the script's responses as they appear, for which you look at poll or select .

It is also useful to look at pseudo-terminals for solving such problems (the easiest way to start is to call forkpty , well, don't forget about all SEE_ALSO :-)).