PDA

Просмотр полной версии : Pipes in CGI Application


Olim
28.04.2009, 07:19
Есть консольная программа, которая создает дочерний процесс перенаправляя хендл стандартного вывода через пайпы. Проблема в том что, если программа выполняется как CGI под Apache то выдается ошибка при чтение данных из созданного пайпа. А если запустить программу как обычно т.е. из эксплора оно работает без ошибок.
Код создания пайпов:


SecureAttr.nLength := SizeOf(SecureAttr);
SecureAttr.lpSecurityDescriptor := nil;
SecureAttr.bInheritHandle := True;

if not CreatePipe(hReadOut, hWriteOut, @SecureAttr, 0) then
raise Exception.Create('Unable to create pipe for compiler''s output');

FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb := SizeOf(StartInfo);
StartInfo.wShowWindow := SW_HIDE;
StartInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartInfo.hStdOutput := hWriteOut;
StartInfo.hStdError := hWriteOut;

if not CreateProcess(PChar(fCompilerPath),
PChar(Format(fCompilerCommand, [fSourceFile])), nil, nil, TRUE,
0, nil, PChar(ExtractFileDir(fSourceFile)),
StartInfo, ProcInfo) then
raise Exception.CreateFmt('Unable to run compiler "%s"', [fCompilerPath]);

if WaitForSingleObject(ProcInfo.hProcess, fCompilationTimeLimit) = WAIT_TIMEOUT then
begin
TerminateProcess(ProcInfo.hProcess, 1);
raise Exception.CreateFmt('Timeout while compiling "%s"', [fSourceFile]);
end;
GetExitCodeProcess(ProcInfo.hProcess, ExitCode);
CloseHandle(hWriteOut);

dwFileSize := GetFileSize(hReadOut, nil);
GetMem(Buffer, dwFileSize);

if (not ReadFile(hReadOut, Buffer^, dwFileSize, dwBytesRead, nil)) or (dwFileSize <> dwBytesRead) then
raise Exception.Create('Unable to read data from compiler''s output pipe');

Buffer^[dwFileSize] := #0;

CloseHandle(hReadOut);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
Помогите разобратся!

Olim
28.04.2009, 16:46
Ошибка выдается здесь


if (not ReadFile(hReadOut, Buffer^, dwFileSize, dwBytesRead, nil)) then
raise Exception.Create('Unable to read data from compiler''s output pipe.');


GetLastError возвращает Канал был закрыт

Olim
30.04.2009, 17:04
Ни одного ответа??
Не ужели никто не может помочь мне?

cascada
02.05.2009, 02:30
Ни одного ответа??
Не ужели никто не может помочь мне?

уй..... поплачь бедненький. никто тебе не поможет, умерли все вин32 апи программеры в узбекистане. :))))
попробуй сделать так чтобы дочерний процесс наследовал все хендлы от родительского(наверно из под консоли родительский процесс получает установку на то чтобы не наследовать описатели и эту же настройку передаёт дочернему и когда ты закрываешь вывод родительского то он действительно закрывается) задай это явно. не помню как. компилятор уже полгода не запускал. если я не прав кинь в меня камнем.. не возражаю. кстати что за синтаксис? си шарп?

cascada
05.05.2009, 22:13
Ошибка выдается здесь


if (not ReadFile(hReadOut, Buffer^, dwFileSize, dwBytesRead, nil)) then
raise Exception.Create('Unable to read data from compiler''s output pipe.');


GetLastError возвращает Канал был закрыт

Посмотрел код и понял что сказал чтото не то. но думаю фишка в том же.
тут несколько мыслей:
1.проверь корректность хэндлов стандартного ввода вывода и пайпа
при работе в CGI под Apache, желательно до CloseHandle(hWriteOut), а после и до readfile(). (точки останова необязательны, результат можно скинуть в файл .txt и сравнить с результатами при запуске из под экплорера, ну сделай запусков десять в обоих режимах)
2.вот эта строка CloseHandle(hWriteOut); обязательна? может временно
закомментировать?
3.думаю нужно сделать наоборот- запретитть наследование настроек безопасности и хэндлов дочернему процессу. (в createproccess())

о результатах доложить незамедлительно!!! :)))))))

какова цель? отчёт об удалёной компиляции? закинуть текстовый файл с кодом юзеру, на его тачке компилировать с помощью .NET и запустить с правами отладчика? ух!!! шайтанама!!:)))))