Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > передать stdin


Автор: chubaka 5.5.2008, 10:31
Как вызвать программу и передать ей stdin ?

Добавлено через 10 минут и 54 секунды
Через pipe'ы можна ?

Автор: MAKCim 5.5.2008, 10:48
да

Автор: chubaka 5.5.2008, 11:16
У меня есть программа, и в ней 2 разных способа вызова дочернего процесса. Хотелось бы связать с тем уже уже имееться.

Вариант 1:

Код
    
    FILE * m_pipe = popen(getenv("SCRIPT_FILENAME"), "r");        
    int m_size = 80;
    char buf[m_size + 1];
    while (fgets(buf, m_size, m_pipe) != NULL)
    {
    (void)printf("%s", buf);
    }
    pclose(m_pipe);


Вариант 2:

Код

    int pipedes[2];
    pid_t pid;
    pipe(pipedes);
    pid = fork();
    
    
    if (pid > 0)
    {
    close(pipedes[1]);
    
    char buffer[1024 + 1];

    FILE * stream = fdopen(pipedes[0], "r");    
    while (fgets(buffer, 1024, stream) > 0)
    {
        (void )printf("%s", buffer);
    }
    
    fclose(stream);

    close(pipedes[0]);
    }
    else
    {
    close(pipedes[0]);
    dup2(pipedes[1], STDOUT_FILENO);
    
    char *my_argv[] = {getenv("SCRIPT_FILENAME"), NULL};
    execve(getenv("SCRIPT_FILENAME"), my_argv, environ);
    
    close(pipedes[1]);
    return 0;
    }    


Также имеется: STDIN (типа FILE *) - текущий входной поток, и его нужно передать в дочерний процесс. Можна както связать с уже имеющимся кодом ? Тоесть передать STDIN в дочерний процесс. 

Автор: MAKCim 5.5.2008, 12:02
Код

FILE * input; /* нужно передать на stdin дочернего процесса */
...
else
    {
    close(pipedes[0]);
    dup2(fileno(input), STDIN_FILENO);
    dup2(pipedes[1], STDOUT_FILENO);

Автор: chubaka 5.5.2008, 12:25
Тоесть так ? 

Код

FILE * input = stdin; /* нужно передать на stdin дочернего процесса */
...
else
    {
    close(pipedes[0]);
    dup2(fileno(input), STDIN_FILENO);
    dup2(pipedes[1], STDOUT_FILENO);


Так почемуто не работает.

Автор: MAKCim 5.5.2008, 12:28
Цитата(chubaka @  5.5.2008,  12:25 Найти цитируемый пост)
Тоесть так ? 

нет
stdin и так наследуется дочерним процессом
в этом случае dup2() не нужен
если нужно "подсунуть" процессу что-то отличное от stdin на стандартный вход, тогда применяется dup2() как показано выше

Автор: chubaka 5.5.2008, 12:44
MAKCim, понял, спасибо!

Автор: chubaka 5.5.2008, 13:25
К сожалению проблема не решена.


MAKCim, вы правы, дочерний процесс наследует stdin. Но он вызывает execve, и stdin не переходит на вызываемый execve'ом процесс. Как передать stdin именно туда ? 

Автор: chubaka 5.5.2008, 15:27
Вот нашел пример, там именно то что нужно, но у меня не получается. Да и там 2 fork()'а, не пойму зачем.

http://www.erack.de/download/pipe-fork.c

Автор: MAKCim 5.5.2008, 16:37
Цитата(chubaka @  5.5.2008,  13:25 Найти цитируемый пост)
Но он вызывает execve, и stdin не переходит на вызываемый execve'ом процесс. Как передать stdin именно туда ?  

execve() не влияет на открытые процессом файлы
вот пример
Код

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

/*
 * data - файл вида
 * ------------------------
 * c
 * b
 * a
 * ------------------------
 */
#define PATH      "data"
#define PROGRAM   "/bin/sort"

int main() {
    int fd = open(PATH, O_RDONLY);
    pid_t pid = fork();
    if (pid == 0) {
        dup2(fd, STDIN_FILENO);
        execve(PROGRAM, NULL, NULL);
    }
    wait(NULL);
    return 0;
}

Автор: chubaka 5.5.2008, 17:03
MAKCim, Спасибо. Теперь получилось, опечатка была. Все smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)