dimrub: (Default)
[personal profile] dimrub
Вот задача про Юникс и Си, её придумал пользователь [livejournal.com profile] avysk, а я слегка модифицировал.

Написать на Си коротенькую программу, которая при вызове через конвейер выдаёт фразу "Hello, world!\n", а при вызове с командной строки выдаёт ту же строку, но не один, а два раза.
Короче, вот так:

$ my_prog
Hello, world!
Hello, world!
$ my_prog | cat -
Hello, world!
$

Конечно есть функция isatty, с помощью которой можно просто проверить, запущена ли программа с терминала, вот так:
if(isatty(1))...else...;
Поэтому дополнительное условие: этой функцией (или подобными ей) пользоваться нельзя.

И вот что интересно - пользователь [livejournal.com profile] ilya_dogolazky запостил очень похожую задачу.
Похожую, да решающуюся несколько иначе, хоть и непросто найти отличия в условии.




on 2008-03-08 10:08 pm (UTC)
Posted by [identity profile] michk.livejournal.com
ЖЖёте!

on 2008-03-08 10:49 pm (UTC)
Posted by [identity profile] sartoris.livejournal.com
EBADF?

Ответная задачка:

Bookintosh:user$ ./my_prog
Hello world 1!
Hello world 2!
Bookintosh:user$ ./my_prog | cat -
Hello world 2!
Hello world 1!

on 2008-03-09 12:00 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Если вы имеете в виду
printf("Hello, world 1\n") ;
fprintf(stderr, "Hello, world 2\n") ;
то тут вот какое дело: в обеих исходных задачах вывод происходит в stdout, а stderr вообще не задействован: можно смело ко всем вызовам приписать 2>/dev/null и ничего не изменится.

А в каком смысле "bad file descriptor"?

on 2008-03-09 12:15 am (UTC)
Posted by [identity profile] sartoris.livejournal.com
А в каком смысле "bad file descriptor"?

В смысле что

fd = fcntl(STDOUT_FILENO, F_DUPFD, 0);
write( fd, hello, strlen( hello ) );
in = read( STDIN_FILENO, rx, 0 );
if( in != -1 )
write( fd, hello, strlen( hello ) );

ну и в обратную сторону раскручивается с тем же успехом. Я не помню как это фифект оффициально называется (с чтением STDOUT), но вот такая вот байда.

Если вы имеете в виду
printf("Hello, world 1\n") ;
fprintf(stderr, "Hello, world 2\n") ;


Совершенно верно. Но это была ответная задачка.

on 2008-03-09 01:10 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Как сообщают ниже, можно прямо так читать, без dup: http://dimrub.livejournal.com/646117.html?thread=9677541#t9677541
Но это не то :-)

on 2008-03-08 10:49 pm (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
одну из них я решил, а вторую что-то никак

on 2008-03-08 10:58 pm (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
осталось только уточнить, какую из них ии почему :-)

on 2008-03-08 11:08 pm (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
почему — понятно, время позднее, соображаю плохо.
а какую — не скажу из соображений симметрии ;)

on 2008-03-08 11:11 pm (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
В таком случае подсказка (но только к той, которая не решена!) --- «утро вечера мудреннее» :-)

on 2008-03-08 11:25 pm (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
на самом деле почти получилось, только один лишний перевод строки мешает, не могу избавиться.

on 2008-03-08 11:38 pm (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Видать у Вас решение совсем не такое как имелось в виду :-)

on 2008-03-08 11:52 pm (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
скорее всего
(deleted comment)
(deleted comment)

on 2008-03-09 01:07 am (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
затер

on 2008-03-09 12:12 am (UTC)
Posted by [identity profile] avva.livejournal.com
Ну например. По-моему, это не подходит под "подобными ей"?

on 2008-03-09 01:02 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Ну это тоже прямой вопрос «не в конвейере ли мы сидим», так? Какой смысл был бы городить огород, если бы обе задачии решались бы абсолютно одинаково? :-)

on 2008-03-09 01:19 am (UTC)
Posted by [identity profile] avva.livejournal.com
Не знаю, по-моему это прямой вопрос "могу ли я читать оттуда, куда пишу"? Это совсем не то же самое, что "сижу ли я в конвейере", хоть в данном случае и совпадает.

on 2008-03-09 01:26 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Да, разумеется. Эта задача (обе точнее) хороша тем, что имеет очень красивое (точнее два разных, но совпадающих на 50%) решение, но плоха тем, что формально отсечь другие решения нам не удалось. Считайте, что красота --- ещё одно дополнительное условие :-)

on 2008-03-09 01:32 am (UTC)
Posted by [identity profile] avva.livejournal.com
Хорошо, тогда давайте так в качестве одного из решений, хоть это и не очень-то гарантировано разнообразными стандартами.

on 2008-03-09 01:38 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Ровно то, что надо! А что может обломиться? В случае с конвейером вроде ничего. А что говорят стандарты про случай интерактивного запуска?
(deleted comment)

on 2008-03-09 02:00 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Пожалуйста!

А, здорово! Я вот немножко подсократил, так что получилось 4 «существенных» строчки - http://codepad.org/hh15AzmC
Если хотите можете подумать, как обойтись лишь двумя принтф"ами и ещё одним дополнительным вызовом некой функции (сразу скажу, что получится не слишком переносимо, но просто считайте, что запускаем под линуксом и всё тогда будет окей).

[если Вы ещё не спите и если не сложно, потрите пожалуйста коммент про волшебное слово на букву «с», а то с утра народ подтянется, его увидит и расстроится. А уж в ссылки с готовыми решениями никто случайно не ткнёт :-) ]

on 2008-03-09 02:02 am (UTC)
Posted by [identity profile] avva.livejournal.com
ага, стер.

on 2008-03-09 02:04 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
спасибо! [всё, я спать пойду, скоро уже Дима проснётся и продолжит :-) ]

on 2008-03-09 09:56 am (UTC)
Posted by [identity profile] ex-ex-zhuzh.livejournal.com
более надежно, например, так (http://codepad.org/hlJmdRw0).

on 2008-03-09 09:20 am (UTC)
avysk: (Default)
Posted by [personal profile] avysk
Можно запретить любые ветвления. То есть постулировать, что в обоих случаях исполняется один и тот же код.

on 2008-03-09 10:48 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
Это мысль! Хотя чревато массой дискуссий на тему того, является ли ветвлением ?:, && или даже == :-)

on 2008-03-09 10:50 am (UTC)
Posted by [identity profile] topboot30.livejournal.com
Вы попали в top30 на яндексе самых обсуждаемых тем в блогосфере. Поэтому копия вашего поста доступна в ленте по ссылке (http://topbot2.livejournal.com/4225455.html)
Почитать текст со всеми комментариями можно тут (http://deep-water.ru/?http://dimrub.livejournal.com/646117.html)
Это Ваш 5-й ТОПовый пост за последний год (http://deep-water.ru/top/). Посмотреть статистику автора можно тут (http://deep-water.ru/top/info.php?id=3361).
Этот "бот не имеет отношения к Яндексу" © НадежныйИсточникImage

on 2008-03-09 11:00 am (UTC)
Posted by [identity profile] ilya-dogolazky.livejournal.com
фигасе :-)

on 2008-03-10 05:57 am (UTC)
Posted by [identity profile] dbg.livejournal.com
#include
[Error: Irreparable invalid markup ('<stdio.h>') in entry. Owner must fix manually. Raw contents below.]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
printf("Hello world!\n");
fork();
return EXIT_SUCCESS;
}

on 2008-03-10 11:19 am (UTC)
Posted by [identity profile] dimrub.livejournal.com
Это, как раз, обратная задача - та, что у [livejournal.com profile] ilya_dogolazky :)

on 2008-03-10 12:21 pm (UTC)
Posted by [identity profile] dbg.livejournal.com
А. /me дал себе подзатыльник за невнимательность.

Ну, можно смухлевать и воспользоваться ttyname, если ограничение касается только isatty. Можно позвать ioctl(STDOUT_FILENO, TCGET ...), но это тоже жульничество, ибо isatty - это просто обертка для этого ioctl.

Можно попробовать почитать из STDOUT_FILENO в неблокируемом режиме: если это перенаправление, то будет EBADF, а если будет EAGAIN, то перенаправления не было. Но, боюсь, это не переносимо. На линуксе это так, а на других системах сейчас проверить нет возможности.

Можно позвать fstat, который все расскажет, но это не интересно.

В общем, решений масса, но "прикольное" что-то не придумывается.

on 2008-03-10 12:30 pm (UTC)
Posted by [identity profile] dimrub.livejournal.com
На самом деле, в этом направлении у задачи не настолько прикольное решение, как в обратном (там, где форк). Так что может оно и не "щелкает".

Profile

dimrub: (Default)
Adventures of a somewhat curious character

September 2013

S M T W T F S
12 345 67
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 24th, 2025 11:26 pm
Powered by Dreamwidth Studios