URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8472
[ Назад ]

Исходное сообщение
"Дочерние процессы+консоль"

Отправлено Hromonin , 09-Окт-09 18:08 
Совсем недавно начал разбираться в програмировании под Linux. И вот возникла проблема.
Допустим необходимо чтобы процесс proc вывел в исходный процесс строку blablabla.
void main()    
{    
   WINDOW *wnd;    
   //всякие там атрибуты и т.д.    
  if(fork()==0)    
execl("proc", " blablabla", NULL);    
}    
/* proc */    
void main()    
{    
   WINDOW *wnd;    
   wprintw(wnd,argv[1]);     
   wrefresh(wnd);    
}
При вызове proc субственно "затирается" консоль родительского процесса. Я так понимаю надо как-то передать индефикатор консоли родительского дочернему. В windows это легко делалось через GetStdHandle(STD_OUTPUT_HANDLE). Как же это сделать в Linux?

Содержание

Сообщения в этом обсуждении
"Дочерние процессы+консоль"
Отправлено elvenic , 09-Окт-09 19:01 
>[оверквотинг удален]
>/* proc */
>void main()
>{
>   WINDOW *wnd;
>   wprintw(wnd,argv[1]);
>   wrefresh(wnd);
>}
>При вызове proc субственно "затирается" консоль родительского процесса. Я так понимаю надо
>как-то передать индефикатор консоли родительского дочернему. В windows это легко делалось
>через GetStdHandle(STD_OUTPUT_HANDLE). Как же это сделать в Linux?

По моему, вы что-то путаете. Если вы хотите просто вывести из дочернего процесса строчку на терминал, то это можно сделать просто функцией printf() - она выводит на standard output, чей файл-дескриптор наследуется дочерними процессами - все открытые файл-дескрипторы так наследуются. Соответственно, файл-дескриптор standard output'a дочернего процесса это тот же файл-дескриптор что и файл-дескриптор standard output'a родительского процесса, и если у родительского процесса это дескриптор его терминала, значит и у дочернего процесса это дескриптор того-же терминала.

Но если вы в родительском процессе используете curses, создаете текстовые окна curses на терминале, и хотите что бы дочерний процесс использовал curses и писал в те окна curses что были созданы родительским процессом, боюсь, так не выйдет. curses в дочернем процессе ничего не знает о curses в родительском процессе, и пытается полностью контролировать терминал по своему. Что, понятно, конфликтует с тем фактом что curses в родительском процессе то-же хочет полностью контролировать терминал.

Мораль: терминал должен контролировать один процесс. Например, родительский. И если дочерний процесс хочет что-то вывести в окно на этом терминале, он должен культурно попросить об этом хозяина терминала - родительский процесс. Например, можно открыть pipe между двумя процессами (или использовать какое-то другое средство inter-process communication) и создать протокол передачи данных от процесса который хочет что-то сказать в окно, процессу - хозяину терминала.



"Дочерние процессы+консоль"
Отправлено Hromonin , 10-Окт-09 12:53 
>[оверквотинг удален]
>curses в родительском процессе, и пытается полностью контролировать терминал по своему.
>Что, понятно, конфликтует с тем фактом что curses в родительском процессе
>то-же хочет полностью контролировать терминал.
>
>Мораль: терминал должен контролировать один процесс. Например, родительский. И если дочерний процесс
>хочет что-то вывести в окно на этом терминале, он должен культурно
>попросить об этом хозяина терминала - родительский процесс. Например, можно открыть
>pipe между двумя процессами (или использовать какое-то другое средство inter-process communication)
>и создать протокол передачи данных от процесса который хочет что-то сказать
>в окно, процессу - хозяину терминала.

Вы имеете ввиду передачу из дочернего процесса строки в родительский и вывод из родительского? Если да, то необходимо выводить именно из дочернего. Если же нет, то немогли бы вы привети пример куска кода с подобным запросом.


"Дочерние процессы+консоль"
Отправлено elvenic , 10-Окт-09 15:51 
>[оверквотинг удален]
>>хочет что-то вывести в окно на этом терминале, он должен культурно
>>попросить об этом хозяина терминала - родительский процесс. Например, можно открыть
>>pipe между двумя процессами (или использовать какое-то другое средство inter-process communication)
>>и создать протокол передачи данных от процесса который хочет что-то сказать
>>в окно, процессу - хозяину терминала.
>
>Вы имеете ввиду передачу из дочернего процесса строки в родительский и вывод
>из родительского? Если да, то необходимо выводить именно из дочернего. Если
>же нет, то немогли бы вы привети пример куска кода с
>подобным запросом.

Да, я имею в виду именно передачу из дочернего процесса строки в родительский и вывод из родительского процесса. Как я уже говорил, два curses'а из двух различных процессов на одном терминале работать не могут. Т.е, нельзя создать curses-окно в родительском процессе, передать его "хендл" в дочерний и выводить в это окно строки в дочернем процессе: дочерний curses начнет с того что снова проинициализирует терминал, что мы и видим на практике.

Если необходимо выводить именно из дочернего, то единственный вариант это не использовать curses вообще и писать и из родительского, и из дочернего просто printf()'ом, но тогда все строки будут появлятся внизу терминала и скроллировать все содержимое терминала вверх, без каких-либо окон.


"Дочерние процессы+консоль"
Отправлено Артур , 11-Окт-09 13:41 
если я все правильно понял, советую перед форком создать пайп,

int fds[2];
pipe(fds);

а дальше два варианта:
1. после форка подменить стдаут чилда пишущим концом трубы:

char buf[80];
if (!fork()) {
    close(STDOUT_FILENO);
    dup2(fds[1], STDOUT_FILENO);
    close(fds[1]);
    execl("proc", " blablabla", NULL);
    /* unreached */
}
// любой f[w]printf(stdout, ...) в чилде будет попадать в fds[0]
FILE *pin = fdopen(fds[0], "r");
fgets(buf, sizeof(buf), pin);

2. передать proc'у дескриптор в виде строки в качестве второго параметра (там его подцепите как pout и передавайте в f[w]printf'ы)

в обоих случаях следите за fflush(3)


"Дочерние процессы+консоль"
Отправлено Артур , 11-Окт-09 13:44 
не туда запостил, блин...
см. пост №4