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


Автор: alexey009 30.10.2009, 16:42
День добрый!
Есть 2 программы.
Первая
Код

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *envp[])
{
    int fd[2], result;
    size_t size;
    char string[] = "Hello, world!\n";
    char resstring[16];
    if(pipe(fd) < 0)
    {
        printf("Can\'t creat pipe\n");
        exit(-1);    
    }
    result = fork();
    if(result > 0)
    {
        close(fd[0]);
        size = write(fd[1], string, 16);
        if(size != 16)
        {
            printf("Can\'t write all string\n");
            exit(-1);        
        }
        close(fd[1]);
        printf("Parrent exit.\n");
    }else if(result == 0)
    {
        close(fd[1]);
        int fds[2][200];        
        sprintf(fds[0], "%d", fd[0]);
        (void) execlp("2.out", "2.out", fds[0], NULL);
        printf("Error on program start\n");
        exit(-1);
        //printf("child exit.\n");
    }else{
        printf("Error\n");
    }
    return 0;
}

Вторая
Код

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *envp[])
{
    size_t size;
    char resstring[16];
    size = read((int)argv[1], resstring, 16);
    if(size < 0)
    {
        printf("Can\'t read all string\n");
        exit(-1);        
    }
    printf("%s", resstring);
    close(argv[1]);
    printf("child exit.\n");
    return 0;
}

Данные программы не работают. Знаю в чем ошибка, но не знаю как исправить.
1. Нужно передать из 1 программы файловый дескриптор на чтение во 2 программу. Как это лучше сделать? 
2. Ещё задачка, определить размер потока pipa, но это после решения 1 задачи.

Автор: MAKCim 30.10.2009, 18:51
Цитата(alexey009 @  30.10.2009,  16:42 Найти цитируемый пост)
Нужно передать из 1 программы файловый дескриптор на чтение во 2 программу. Как это лучше сделать? 

man 2 dup2 (если я правильно понял, что нужно сделать)

Цитата(alexey009 @  30.10.2009,  16:42 Найти цитируемый пост)
Ещё задачка, определить размер потока pipa, но это после решения 1 задачи. 

ioctl и FIONREAD

Автор: alexey009 30.10.2009, 19:08
Нужно сделать примерно следующее: 
Основная программа:
родитель записывает строку в поток информации pipe() строку,
создает ребенка, ребенок вызывает вторую программу.
Вторая программа:
Получает от 1 программы необходимые данные, чтобы вывести записанную в поток pipe() строку,
Выводит данную строку.
Даже не слышал про такую функцию, а как нибудь проще это сделать нельзя? примерно так, как я пытался реализовать у себя в программе:
выделить память под массив, который будет содержать файловый дескриптор, и далее передать этот массив второй программе через exec()
Цитата

ioctl и FIONREAD

Хм.. Тоже что-то не знакомое. У меня была идея реализовать так:
Передавать информацию через pipe определенного объема. далее посмотреть сколько реально передалось информации за 1 раз, это и будет размер потока pipe()

Автор: MAKCim 30.10.2009, 19:21
alexey009
Цитата(alexey009 @  30.10.2009,  19:08 Найти цитируемый пост)
Даже не слышал про такую функцию, а как нибудь проще это сделать нельзя?

куда уж проще? ;)
она специально для этого (перенаправление аотоков ввода-вывода) и предназначена

Цитата(alexey009 @  30.10.2009,  19:08 Найти цитируемый пост)
Хм.. Тоже что-то не знакомое. У меня была идея реализовать так:

советую не заниматься велосипедостроительством

Автор: alexey009 30.10.2009, 20:08
Пытаюсь разобраться, но как-то пока глухо.
Про передачу файлового дескриптора:
Код

    int fds[1];
    fds[0] = dup2 (fd[0], STDIN_FILENO);
    (void) execlp("2.out", "2.out", fd[0], NULL);

Что тут неверно?
По поводу размера pipe()
Код

    size = write(fd[1], string, 16);
    ioctl(size, FIONREAD);

Где косяк?)
Цитата

советую не заниматься велосипедостроительством 

Ну а все-таки(для более глубокого понятия работы pipe и прочего временами велосипедостроительство полезно), как реализовать тот механизм, что написал я?

Автор: MAKCim 30.10.2009, 22:09
Цитата(alexey009 @  30.10.2009,  20:08 Найти цитируемый пост)
Что тут неверно?

ну во-первых, передавать так fd[0] нельзя, т. к fd[0] - int, а аргумент должен быть char*
во-вторых, ты уже перенаправление сделал, 2.out будет читать из пайпа fd[0]


Цитата(alexey009 @  30.10.2009,  20:08 Найти цитируемый пост)
Где косяк?)

советую научиться читать документацию ;)

Код

ioctl(fd[0], FIONREAD, &size);


Код

char s;
int size;
int mode = 1;
ioctl(fd[1], FIONBIO, &mode);
while (write(fd[1], &s, sizeof(s)) == sizeof(s));
if (errno != EAGAIN)
{
    // error
}
ioctl(fd[0], FIONREAD, &size);
// `size' contains PIPE size

Автор: alexey009 30.10.2009, 22:19
Цитата(MAKCim @  30.10.2009,  22:09 Найти цитируемый пост)
ну во-первых, передавать так fd[0] нельзя, т. к fd[0] - int, а аргумент должен быть char*во-вторых, ты уже перенаправление сделал, 2.out будет читать из пайпа fd[0]


прошу прощения, туплю.. smile 
 smile 

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