Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 18.06.2010, 15:43   #1
0xDEFACE
 
Регистрация: 18.06.2010
Сообщений: 3
По умолчанию Нужно приткнуть dup2() в правильное место в программе

Добрый день!

В аттаче ff7.zip код правильно работающей программы. В программе используется односторонняя связь между родительским процессом и дочерним через пайп (т.е. данные от родителя передаются потомку через пайа) имитирует что-то вроде шелла (исполнитель команд).

В коде представленном ниже находится абсолютно аналогичная программа (листинг представлен ниже), в которой используется двусторонняя связь родителя с потомком. То есть родительский процесс передает данные дочерниму процессу через пайп, а дочерний процесс возвращает данные (результат) родителю через другой пайп.

Проблема в том, что никак не получается реализовать ТАКОЙ ЖЕ интерфейс в программе (листинг представлен ниже), как и в ff7. Для этого, я так понимаю нужно просто кое-где воткнуть соответствующий dup2() (наверное 2 штуки).

Собственно вопрос к аудитории: КУДА? Пожалуйста помогите разобраться!!

Итак, разархивируем ff7.zip. Компилируем, например так:

$ gcc ff7.c -o ff7

Запускаем:
$ ./ff7

Открываем новый терминал/консоль и командуем, например следующее:

$ echo pwd > input.txt

Наблюдаем за результатом в первой консоле.

Интерфейс взаимодействия с программой ниже абсолютно аналогичный.

Нужно достичь АБСОЛЮТНО такого же взаимодействия и интерфейса в программе ниже, путем правильного использования dup2()...

Код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

/* Original version got from http://www.iakovlev.org */

void do_parent(int input_pipe[], int output_pipe[])
{
    int c;
    char ch;
    int rc;
	FILE *in;

    close(input_pipe[1]); /* we don't need to write to this pipe.  */
    close(output_pipe[0]); /* we don't need to read from this pipe. */

	while (1)
	{
		in = fopen("input.txt", "r");
		while ((c = fgetc(in)) > 0) {
			ch = (char)c;
			/* write to child */
			rc = write(output_pipe[1], &ch, 1);
			if (rc == -1) {
				perror("child: write");
				close(input_pipe[0]);
				close(output_pipe[1]);
				exit(1);
			}
			/* read back from child */
			rc = read(input_pipe[0], &ch, 1);
			c = (int)ch;
			if (rc <= 0) {
				perror("parent: read");
				close(input_pipe[0]);
				close(output_pipe[1]);
				exit(1);
			}
			/* print given character to stdout. */
			putchar(c);
		}
		fclose(in);
	}
    close(input_pipe[0]);
    close(output_pipe[1]);
    exit(0);
}

void do_child(int input_pipe[], int output_pipe[])
{
    int c;
    char ch;
    int rc;

    close(input_pipe[1]); /* we don't need to write to this pipe.  */
    close(output_pipe[0]); /* we don't need to read from this pipe. */
	
	//dup2(output_pipe[1], 1);
	dup2(input_pipe[0], 0);
	
   	char* cmd[] = { "cmd", (char *)0 };
	execvp("cmd", cmd);
	
    while (read(input_pipe[0], &ch, 1) > 0) {
        c = (int)ch;
        ch = (char)c;
		putchar(ch);
        rc = write(output_pipe[1], &ch, 1);
        if (rc == -1) {
            perror("child: write");
            close(input_pipe[0]);
            close(output_pipe[1]);
            exit(1);
        }
    }
    close(input_pipe[0]);
    close(output_pipe[1]);
    exit(0);
}

int main(int argc, char* argv[])
{
    int parent_to_child[2];
    int child_to_parent[2];
    int pid;
    int rc;

    umask(0);
    mknod("input.txt", S_IFIFO|0666, 0);

    rc = pipe(parent_to_child);
    if (rc == -1) {
		perror("main: pipe parent_to_child");
		exit(1);
    }

    rc = pipe(child_to_parent);
    if (rc == -1) {
		perror("main: pipe child_to_parent");
		exit(1);
    }

    pid = fork();
    switch (pid) {
 	case -1:
 	    perror("main: fork");
 	    exit(1);
 	case 0:
 	    do_child(parent_to_child, child_to_parent);
 	default:
 	    do_parent(child_to_parent, parent_to_child);
    }
    return 0;
}

P.S. Если компилите из-под никсов, понадобится заменить cmd на ваш шелл (csh/bash...):

Код:
char* cmd[] = { "bash", (char *)0 };
execvp("bash", cmd);
Вложения
Тип файла: zip ff7.zip (599 байт, 6 просмотров)

Последний раз редактировалось 0xDEFACE; 18.06.2010 в 16:14.
0xDEFACE вне форума
Старый 18.06.2010, 18:29   #2
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Ну, сама передача через пайпы пашет.

dup2 - это маппинг одного дескриптора на другой.

Последний раз редактировалось Carbon; 18.06.2010 в 18:43.
Carbon вне форума
Старый 20.06.2010, 10:59   #3
0xDEFACE
 
Регистрация: 18.06.2010
Сообщений: 3
По умолчанию

Пашет-то оно пашет. Нужно такой же результат как и в ff7.
0xDEFACE вне форума
Старый 21.06.2010, 11:36   #4
0xDEFACE
 
Регистрация: 18.06.2010
Сообщений: 3
По умолчанию

Вопрос решен с помощью poll().
0xDEFACE вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужно найти ошибку в программе (С++) STIFFmaster_LP Помощь студентам 13 24.01.2010 00:44
Программа с классом и объектами (Что в программе нужно изменить?) wepoTWR Помощь студентам 0 17.11.2009 19:26
плиз помогите переделать одно место в программе hen Помощь студентам 2 23.04.2009 19:44
Нужно сохранить информацию в программе Alex_09 Общие вопросы Delphi 10 23.03.2009 18:41