Как я могу контролировать канал, созданный popen ()? - PullRequest
0 голосов
/ 30 апреля 2020

Примечание: Я знаю, что могу достичь того, что описываю, используя fork и, возможно, wait, но я хочу понять, как работает popen и как я могу использовать его для взаимодействия между процессами .

Я хочу использовать popen для создания дочернего процесса, затем в дочернем процессе я пишу в канал, созданный popen, а затем, в родительском процессе, я читаю из канала и выводу сообщение.

Это то, что я пробовал:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

#define BUFFER_SIZE 105

int main(int argc, const char * argv[])
{
    FILE* fp;
    int status;
    char buffer[BUFFER_SIZE];

    fp = popen("date", "r"); // returns `FILE *` object (the same as a "stream", I think)
    if(fp == NULL) { printf("Eroare la deschidere cu `popen()`\n");} return -1; // or `EXIT_FAILURE`

    fgets(buffer, BUFFER_SIZE, fp); // ????? is this where I am reading from the pipe? 
                                    // `popen` returns a pointer to a stream, thus is it a `FILE *` object?
                                    // As such, is `fp` also the pipe? "pipe" == "stream" == `FILE *` object ?
    printf("I have read: %s", buffer); 

    status = pclose(fp);
    if(status == -1) { printf("`Eroare la inchiderea cu popen()`\n"); return -1;} // or `EXIT_FAILURE`

return 0; // or `EXIT_SUCCESS`?
}

Кроме того, какой канал в таком контексте? Является ли fp объектом FILE * и "трубой"? Могу ли я получить доступ к fp[0] & fp[1]?

Вывод:

I have read: Thu Apr 30 16:29:05 EEST 2020

1 Ответ

2 голосов
/ 30 апреля 2020

Мне не совсем понятно, о чем вы здесь спрашиваете, поэтому дайте мне знать, если этот ответ не соответствует отметке.

man popen подтверждает, что popen возвращает FILE *. Это не массив; fp[0] или fp[1].

* "канал" - это просто пара связанных файловых дескрипторов ... один доступен в родительском процессе (это возвращаемое значение из popen), а другой - доступно в дочернем процессе. Когда вы читаете из своей переменной fp, вы читаете с одного конца канала (а когда дочерний процесс пишет в stdout, он записывает на другой конец канала).

является дочерним, читающим из потока или родительским

Когда вы запускаете fp = popen("date", "r"), вы создаете однонаправленный канал. Родитель может читать, а ребенок может писать (если бы вы указали "w" в качестве режима, а не наоборот).

Вы явно читаете из пункта здесь:

fgets(buffer, BUFFER_SIZE, fp);

и как мне узнать, что выполняется подпроцессом

Подпроцесс выполняет то, что вы ему сказали (в данном случае date).

Кроме того, как мы узнаем, какой конец для чтения, а какой для записи

Вы управляете вторым аргументом команды popen.


- это цель popen (в моем случае, здесь) перенаправить вывод команды родительскому процессу

Цель popen - разрешить связь между дочерним процессом и родительским процессом. Он создает однонаправленный канал, но вы контролируете, является ли это parent -> child или child -> parent.

Это то, что происходит в предоставленной мной программе? 1) popen открывает подпроцесс 2) подпроцесс записывает выходные данные команды date в конец записи канала 3) родительский процесс читает конец чтения канала (ie что имеет дочерний элемент) передано)?

Это правильно.

...