Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Неименованные каналы в Windows




Для создания неименованных каналов в Windows NT (и Windows 9x) предназначена системная функция CreatePipe, имеющая прототип

BOOL CreatePipe(HANDLE* phReadPipe, HANDLE* phWritePipe,

LPSECURITY_ATTRIBUTES pAttributes, DWORD nSize),

где phReadPipe – адрес переменной для хэндла чтения из канала, phWritePipe – адрес переменной для хэндла записи в канал, pAttributes – адрес атрибутов защиты, nSize – число байтов, резервируемых для канала.

Для манипуляций с хэндлами стандартного ввода и вывода в Windows можно использовать не только универсальную функцию DuplicateHandle копирования хэндлов (которая здесь предназначена для копирования хэндлов любых объектов ядра, а не только файлов), но и более простую специализированную функцию SetStdHandle. Она позволяет построить строку таблицы соответствия для стандартного ввода или вывода в строке таблицы соответствия, явно указываемой номером хэндла. Эта функция имеет прототип

BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle),

где nStdHandle – условное обозначение хэндла стандартного ввода, вывода или ошибок, задаваемое одной из символических констант STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE. Аргумент hHandle задает хэндл для той строки таблицы соответствия, на место которой копируется строка таблицы соответствия для хэндла стандартного ввода или вывода.

В листингах 11.3.1 и 11.3.2 приведены программы родительского и дочернего процессов, которые демонстрируют использование неименованных каналов в Windows.

 

#include <stdio.h>

#include <windows.h>

#define PIPESIZE 16

int main()

{HANDLE hW, hR, hstdout;

DWORD rc, cbRead;

STARTUPINFO si;

PROCESS_INFORMATION pi;

DWORD CreationFlags;

char bufread[PIPESIZE]="-";

 

hstdout = GetStdHandle(STD_OUTPUT_HANDLE);

if(!CreatePipe(&hR, &hW, NULL, PIPESIZE))

{printf("Error create Pipe\n");getchar();exit(1);};

SetStdHandle(STD_OUTPUT_HANDLE, hW);

 

memset(&si, 0, sizeof(STARTUPINFO));

si.cb=sizeof(si);

CreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;

rc=CreateProcess(NULL, "childpip.exe", NULL, NULL, TRUE, //наследуемые

CreationFlags, NULL, NULL, &si, &pi);

if (!rc)

{printf("Error create Process, codeError = %ld\n",

GetLastError()); getchar(); return 0;

}

CloseHandle(hW);

do

{rc=ReadFile(hR, bufread, 4, &cbRead, NULL);

if (!rc)

{rc=GetLastError();

if (rc= =ERROR_BROKEN_PIPE) break;

else {printf("Error ReadFile, rc=%d\n", rc); }

}

Sleep(1000);

WriteFile(hstdout, bufread,cbRead,&cbRead,NULL);

} while (cbRead!=0);

printf("\nEnd work with pipe\n");

CloseHandle(hstdout);

CloseHandle(hR);

return 0;

}

Листинг 11.3.1. Программа родительского процесса

 

#include <stdio.h>

#include <windows.h>

 

int main()

{int step=0;

DWORD cb;

int portion=9;

char text[ ]="У лукоморья дуб зеленый, златая цепь на дубе том.";

char *ptxt=text, *textend=text+sizeof(text)-2;

HANDLE hstdout;

hstdout = GetStdHandle(STD_OUTPUT_HANDLE);

ptxt=text;

while(ptxt<=textend)

{if (ptxt>textend-portion) portion=textend-ptxt+1; //last portion may be less than 9

fprintf(stderr,"----I am Child... (step=%d)\n\r", ++step);

WriteFile(hstdout, ptxt, portion,&cb, NULL);

ptxt+=portion;

Sleep(2000);

}

CloseHandle(hstdout);

return 0;

}

Листинг 11.3.2. Программа childpip.exe дочернего процесса

 

Получение данных через канал в Windows имеет свои особенности. Попытка чтения данных из канала, передающий конец в котором закрыт, приводит не к нулевому числу прочитанных байтов, а к возвращаемому функцией ReadFile значению FALSE. Тем самым как бы фиксируется ошибка. При этом функция GetLastError() возвращает значение символической константы ERROR_BROKEN_PIPE (равное 109). Нормально построенная программа чтения данных из канала должна распознавать это значение как обычное завершение данных в канале аналогично концу файла. Именно так построена программа последнего примера.

Заметим, что в программе родительского процесса при создании дочернего процесса использован параметр наследования (пятый аргумент функции CreateProcess), равный TRUE. Это значение заставляет дочерний процесс унаследовать все дескрипторы открытых объектов и соответственно хэндлы этих дескрипторов.

 




Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 1194; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.