LINUX.ORG.RU

перенаправление в/в НИЧЕГО НЕ ПОЙМУ!!!


0

0

#include ...
...
void main()
{
int d[2];
int status;
char buf[32];
pipe(d);
if(fork()==0)
{
close(1);
close(d[0]);
dup(d[1]);
close(d[1]);
printf("Message\n");
close(1);
exit(0);
}
else
{
close(d[1]);
wait(&status);
read(d[0],buf,32);
printf("%s\n",buf);
close(d[0]);
exit(0);
}
}

у меня какая-то бяка выводится, а должно быть по идее "Message"
Посмотрите кому не лень. Может я чего пропустил?

anonymous

1.
> Может я чего пропустил?

Точно!
Это же просто нонсенс:
printf("Message\n");
close(1);


После printf'а вставь fflush(stdout); скорее всего, сработает:
printf("Message\n");
fflush(stdout);

и убери close(1);

2. НИКОГДА не мешай функции из stdio и низкоуровневые вызовы типа
read/write!

Die-Hard ★★★★★
()

всё же так можно: printf("ssdff"); fflush(stdout); write(1,"",1);
но void main - уже не хорошо :=(( - даже g++ 3. ругается.
проще - write(1,"Message",strlen("Message")+1) - теперь нет проблем и с нулём в конце и с буффером все ОК.

fendor
()
Ответ на: комментарий от fendor

fendor (*) (2003-05-19 19:12:43.127):
> всё же так можно: printf("ssdff"); fflush(stdout); write(1,"",1);
Конкретно ТАК, возможно. Но что делать с операциями буферизованного
ЧТЕНИЯ? На них флеша нету :(

> но void main - уже не хорошо :=(( - даже g++ 3. ругается.
А где тут хоть запах ЦеПП?

Но, вообще, я с тобой согласен, void main must die!

Die-Hard ★★★★★
()

Ну про то что написано (про printf): - я имел в виду, что нужен flush и нет завершающего нуля, ан не рекомендовал так делать := - мне и в страшном сне не приснится такое ....
А ввод таким образом делать - я не знаю как.... :=))
g++ и gcc - всё одна система --) - просто только недавно его юзаю, копирнул, значить, сие творение компильнул - оно варнинг и вывалило :=)) - раньше этого gcc/g++ не делал (может я не видел никогда... - я пишу int mufunc() и т.п. -))

fendor
()
Ответ на: комментарий от fendor

fendor (*) (2003-05-19 19:57:01.63):
> ...я имел в виду, что нужен flush и нет завершающего нуля,

Он НЕ нужен, и даже вреден, если ты читаешь из пайпа функцией из stdio.
При попытке чтения из пайпа 0 функция fgets, например, встанет на уши.

С др. стороны, если читать read'ом, как в примере, то, действит., нужен
завершающий нуль.

> g++ и gcc - всё одна система --)
Верно, но gcc выдаст варнинг и откомпилит, а g++ выдаст варнинг и вывалит.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Верно, но gcc выдаст варнинг и откомпилит, а g++ выдаст варнинг и вывалит.
Ну да - это важнеший вопрос :=))
Итого:
USE write+read+pipe NOT scanf+printf+pipe
З.Ы. Хватит, не будем делать смесь бульдога с носорогом и всё - будем писать грамотные проги.
З.З.Ы Кажись сабж closed.....

fendor
()

Вопрос открыт

какие завершающие нули к черту??? какой к черту void main()??? какой g++??? вот мне, например, вывод команды ls нужно в pipe перенаправить, а с другого конца прочесть - так мне что, скидывать сей вывод в файл, потом его open'ом открывать, read'ом лопатить и write'ом в пайп писать? Или вы хотите сказать, что все утилиты в Юникс write'ом выводят? А про fflush я тоже ничего не понял. Я ж сначала ЖДУ ЗАВЕРШЕНИЯ ПРОЦЕССА, а потом читаю - неужели может быть такое, что процесс окочурился уже давно, а printf, вызванный из этого процесса в буфере застрял??? Ну хорошо, хрен с ним с printf'ом. Вы мне вот что скажите, вот допустим, что ls'сы действительно работают через write, тогда если я сделаю вот так:

//child close(d[0]); close(1); dup(d[1]); close(d[1]); execl("/bin/ls","ls","-l","/my/dir",0);

//parent char szbuf[128]; close(d[1]); while(read(d[0],szbuf,sizeof(szbuf)/sizeof(char)) { //делаем что-то с szbuf }

это прокатит? жду ответов.

anonymous
()
Ответ на: Вопрос открыт от anonymous

Э-э-э...
Тяжело ж тебе будет :-)

> Или вы хотите сказать, что все утилиты в Юникс write'ом выводят?
Ты будешь удивлен, но это - так.

printf - всего лишь враппер над write'ом.

> это прокатит? жду ответов.
Да. Только у тебя

1. возможное переполнение буфера (гордись - на эти грабли наступали
многие великие! char szbuf[128]; read(...,szbuf,128); - просто
классика!);

2. "делаем что-то с szbuf" будет тебе несколько нетривиально.

Короче, RTFM и - думай. Для начала - man fflush, потом - man stdio


Die-Hard ★★★★★
()

> char szbuf[128]; read(...,szbuf,128);
а где здесь ошибка? завели массив из 128 байт. прочитали в него максимум 128 байт. вроде всё нормально?

anonymous
()

Можно :
count=read(.....);
buf[count]='\0';

Коечно надо соблюсти размер буфера чтоб влез нулевой символ.

anonymous
()

ок. int d[2]; pipe(d); char szbuf[128]; //child printf("input message: "); scanf("%s",szbuf); write(d[1],szbuf,128); exit(0); //parent wait((int*)0); read(d[0],szbuf,128); printf("MESSAGE!!!: %s\n",szbuf);

это хоть будет работать?

anonymous
()

mean
int d[2];
pipe(d);
char szbuf[128];
//child
printf("input message: ");
scanf("%s",szbuf);
write(d[1],szbuf,128);
exit(0);
//parent
wait((int*)0);
read(d[0],szbuf,128);
printf("MESSAGE!!!: %s\n",szbuf);



anonymous
()
Ответ на: комментарий от anonymous

Будет, но если введшь строку длиннее 126 символов, переполнишь буфер.

Die-Hard ★★★★★
()

ну хорошо, тогда где вы увидели переполнение буфера в исходном примере?
я ведь в read сколько укажу байт, столько он и запишет в буфер
аналогично с write. и тут не важно, записываю ли я c пом. printf или
write т.к. printf в конечном счете юзает write
не так ли?

anonymous
()
Ответ на: комментарий от anonymous

> где вы увидели переполнение буфера в исходном примере?
> ... printf в конечном счете юзает write ...
scanf добавит 0.

Слушай, я не могу нянчиться с детьми. Извини, больше я тебе не отвечаю.
Думай сам, это все тривиально.

Die-Hard ★★★★★
()

ну вот теперь я понял. Так сразу и сказали бы, что библиотечные ф-ции
добавляют конец строки, а write/read работают с неструктурированным
потоком байтов поэтому считав 32 байта read'ом из пайпа я не могу быть уверен, что в буфере вообще есть символ конца строки.

anonymous
()
Ответ на: комментарий от anonymous

Обрати внимание - есть два разных "конца строки".
В текстовом файле признаком конца строки является '\n', а функции
с прототипами из string.h (и многие другие) в качестве конца строки
употребляют '\0' ( (char)0 ).

Когда ты прочитаешь fgets(buf, 128, stdin), в буффере будут оба конца:
blah-blah\n\0

Когда ты прочитаешь scanf("%s",buf), в буффере будет только один конец:
blah-blah\0

Когда ты прочитаешь read(1,buf,32), в буффере будет только то, что ты
прочитал.

Die-Hard ★★★★★
()

да, это я понял, а также я понял, что нельзя использовать read/write
вместе с scanf/printf, т.к. это может привести к нарушению сегментации

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.